tor-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2020
- 25 participants
- 2156 discussions

[orbot/master] re-enable traffic notification info and improve debug output
by n8fr8@torproject.org 28 Apr '20
by n8fr8@torproject.org 28 Apr '20
28 Apr '20
commit 7cd5a2884d3d2980c92b323ad3191afe48736c38
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Mon Dec 9 15:45:12 2019 -0500
re-enable traffic notification info and improve debug output
- tor entrance IP now displayed in logs if you enable debug option
---
.../android/service/TorEventHandler.java | 161 +++++++--------------
.../org/torproject/android/service/TorService.java | 37 ++---
.../android/service/util/ExternalIPFetcher.java | 95 ++++++++++++
.../android/service/vpn/OrbotVpnManager.java | 24 ++-
.../android/service/vpn/TorVpnService.java | 4 +-
orbotservice/src/main/res/drawable/ic_onion.xml | 9 ++
.../src/main/res/drawable/ic_stat_tor_xfer.png | Bin 0 -> 990 bytes
orbotservice/src/main/res/drawable/ic_transfer.xml | 9 ++
8 files changed, 194 insertions(+), 145 deletions(-)
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
index c67afff4..8635eb7b 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
@@ -4,6 +4,7 @@ import android.text.TextUtils;
import net.freehaven.tor.control.EventHandler;
+import org.torproject.android.service.util.ExternalIPFetcher;
import org.torproject.android.service.util.Prefs;
import java.text.NumberFormat;
@@ -32,12 +33,14 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
public class Node
{
- String status;
- String id;
- String name;
- String ipAddress;
- String country;
- String organization;
+ public String status;
+ public String id;
+ public String name;
+ public String ipAddress;
+ public String country;
+ public String organization;
+
+ public boolean isFetchingInfo = false;
}
public HashMap<String,Node> getNodes ()
@@ -102,7 +105,6 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
if (read != lastRead || written != lastWritten)
{
- /**
StringBuilder sb = new StringBuilder();
sb.append(formatCount(read));
sb.append(" \u2193");
@@ -116,7 +118,6 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
iconId = R.drawable.ic_stat_tor_xfer;
mService.showToolbarNotification(sb.toString(), mService.getNotifyId(), iconId);
- **/
mTotalTrafficWritten += written;
mTotalTrafficRead += read;
@@ -161,9 +162,12 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
StringTokenizer st = new StringTokenizer(path, ",");
Node node = null;
+ boolean isFirstNode = true;
+ int nodeCount = st.countTokens();
+
while (st.hasMoreTokens()) {
String nodePath = st.nextToken();
- node = new Node();
+ String nodeId = null, nodeName = null;
String[] nodeParts;
@@ -173,129 +177,70 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
nodeParts = nodePath.split("~");
if (nodeParts.length == 1) {
- node.id = nodeParts[0].substring(1);
- node.name = node.id;
+ nodeId = nodeParts[0].substring(1);
+ nodeName = node.id;
} else if (nodeParts.length == 2) {
- node.id = nodeParts[0].substring(1);
- node.name = nodeParts[1];
+ nodeId = nodeParts[0].substring(1);
+ nodeName = nodeParts[1];
+ }
+
+ if (nodeId == null)
+ continue;
+
+ node = hmBuiltNodes.get(nodeId);
+
+ if (node == null)
+ {
+ node = new Node();
+ node.id = nodeId;
+ node.name = nodeName;
}
node.status = status;
sb.append(node.name);
+ if (!TextUtils.isEmpty(node.ipAddress))
+ sb.append("(").append(node.ipAddress).append(")");
+
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 (status.equals("EXTENDED"))
+ {
- if (Prefs.expandedNotifications()) {
- //get IP from last nodename
- if (status.equals("BUILT")) {
+ if (isFirstNode)
+ {
+ hmBuiltNodes.put(node.id, node);
- // if (node.ipAddress == null)
- // mService.exec(new ExternalIPFetcher(node));
+ if (node.ipAddress == null && (!node.isFetchingInfo) && Prefs.useDebugLogging()) {
+ node.isFetchingInfo = true;
+ mService.exec(new ExternalIPFetcher(mService, node, TorService.mPortHTTP));
+ }
- hmBuiltNodes.put(circID, node);
+ isFirstNode = false;
+ }
}
+ else if (status.equals("BUILT")) {
+ // mService.logNotice(sb.toString());
- if (status.equals("CLOSED")) {
- hmBuiltNodes.remove(circID);
-
+ if (Prefs.useDebugLogging() && nodeCount > 3)
+ mService.debug(sb.toString());
+ }
+ else if (status.equals("CLOSED")) {
+ // mService.logNotice(sb.toString());
+ 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_addre…";
- 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)
{
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index ea807be4..110b562f 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -37,6 +37,8 @@ import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
+import android.widget.RemoteViews;
+
import com.jaredrummler.android.shell.CommandResult;
import net.freehaven.tor.control.ConfigEntry;
@@ -75,6 +77,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -402,7 +405,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try {
- unregisterReceiver(mNetworkStateReceiver);
+ // unregisterReceiver(mNetworkStateReceiver);
unregisterReceiver(mActionBroadcastReceiver);
}
catch (IllegalArgumentException iae)
@@ -536,8 +539,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
- IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);
+ // IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+ // registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);
IntentFilter filter = new IntentFilter();
filter.addAction(CMD_NEWNYM);
@@ -1472,6 +1475,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
* BroadcastReciever in the Android manifest.
*/
+ /**
private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1504,33 +1508,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
if (newConnectivityState != mConnectivity) {
mConnectivity = newConnectivityState;
- if (mConnectivity)
- newIdentity();
+ //if (mConnectivity)
+ // newIdentity();
}
- /**
- if (doNetworKSleep && mCurrentStatus != STATUS_OFF)
- {
- setTorNetworkEnabled (mConnectivity);
-
- if (!mConnectivity)
- {
- logNotice(context.getString(R.string.no_network_connectivity_putting_tor_to_sleep_));
- showToolbarNotification(getString(R.string.no_internet_connection_tor),NOTIFY_ID,R.drawable.ic_stat_tor_off);
-
- }
- else
- {
- logNotice(context.getString(R.string.network_connectivity_is_good_waking_tor_up_));
- showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor);
-
- }
-
- }**/
-
-
}
- };
+ };**/
private StringBuffer processSettingsImpl (StringBuffer extraLines) throws IOException
{
diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java b/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java
new file mode 100644
index 00000000..ae99e7de
--- /dev/null
+++ b/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java
@@ -0,0 +1,95 @@
+package org.torproject.android.service.util;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.torproject.android.service.TorEventHandler;
+import org.torproject.android.service.TorService;
+
+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;
+
+public class ExternalIPFetcher implements Runnable {
+
+ private TorService mService;
+ private TorEventHandler.Node mNode;
+ private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addre…";
+ private int mLocalHttpProxyPort = 8118;
+
+ public ExternalIPFetcher (TorService service, TorEventHandler.Node node, int localProxyPort )
+ {
+ mService = service;
+ mNode = node;
+ mLocalHttpProxyPort = localProxyPort;
+ }
+
+ public void run ()
+ {
+ try {
+
+ URLConnection conn = null;
+
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", mLocalHttpProxyPort));
+ 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.name).append("(");
+ sbInfo.append(mNode.ipAddress).append(")");
+
+ if (mNode.country != null)
+ sbInfo.append(' ').append(mNode.country);
+
+ if (mNode.organization != null)
+ sbInfo.append(" (").append(mNode.organization).append(')');
+
+ mService.debug(sbInfo.toString());
+
+ }
+
+ reader.close();
+ is.close();
+
+
+
+ } catch (Exception e) {
+
+ // mService.debug ("Error getting node details from onionoo: " + e.getMessage());
+
+
+ }
+
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
index b78c7a4f..c747eb59 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
@@ -51,6 +51,7 @@ import java.net.InetAddress;
import java.util.ArrayList;
import java.util.concurrent.TimeoutException;
+import static org.torproject.android.service.TorServiceConstants.ACTION_START;
import static org.torproject.android.service.vpn.VpnUtils.getSharedPrefs;
import static org.torproject.android.service.vpn.VpnUtils.killProcess;
@@ -101,6 +102,8 @@ public class OrbotVpnManager implements Handler.Callback {
}
+
+ boolean isStarted = false;
//public int onStartCommand(Intent intent, int flags, int startId) {
public int handleIntent(Builder builder, Intent intent) {
@@ -109,8 +112,10 @@ public class OrbotVpnManager implements Handler.Callback {
{
String action = intent.getAction();
- if (action.equals("start"))
+ if (action.equals(TorVpnService.ACTION_START))
{
+ isStarted = true;
+
// Stop the previous session by interrupting the thread.
if (mThreadVPN != null && mThreadVPN.isAlive())
stopVPN();
@@ -129,8 +134,10 @@ public class OrbotVpnManager implements Handler.Callback {
}
- else if (action.equals("stop"))
+ else if (action.equals(TorVpnService.ACTION_STOP))
{
+ isStarted = false;
+
Log.d(TAG,"stop OrbotVPNService service!");
stopVPN();
@@ -335,12 +342,13 @@ public class OrbotVpnManager implements Handler.Callback {
isRestart = false;
//start PDNSD daemon pointing to actual DNS
- int pdnsdPort = 8091;
- startDNS(filePdnsd.getCanonicalPath(), localhost,mTorDns, virtualGateway, pdnsdPort);
- final boolean localDnsTransparentProxy = true;
-
- Tun2Socks.Start(mService, mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , virtualGateway + ":" + pdnsdPort , localDnsTransparentProxy);
+ if (filePdnsd != null) {
+ int pdnsdPort = 8091;
+ startDNS(filePdnsd.getCanonicalPath(), localhost, mTorDns, virtualGateway, pdnsdPort);
+ final boolean localDnsTransparentProxy = true;
+ Tun2Socks.Start(mService, mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks, virtualGateway + ":" + pdnsdPort, localDnsTransparentProxy);
+ }
}
catch (Exception e)
@@ -409,7 +417,7 @@ public class OrbotVpnManager implements Handler.Callback {
File fileConf = makePdnsdConf(mService, mService.getFilesDir(), torDnsHost, torDnsPort, pdnsdHost, pdnsdPort);
- String[] cmdString = {pdnsPath,"-c",fileConf.toString()};
+ String[] cmdString = {pdnsPath,"-c",fileConf.toString(),"-g","-v2"};
ProcessBuilder pb = new ProcessBuilder(cmdString);
pb.redirectErrorStream(true);
Process proc = pb.start();
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
index d394b5c8..cedd2528 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
@@ -22,8 +22,8 @@ public class TorVpnService extends VpnService {
public static final String TAG = "TorVpnService";
- private static final String ACTION_START = "start";
- private static final String ACTION_STOP = "stop";
+ public static final String ACTION_START = "start";
+ public static final String ACTION_STOP = "stop";
public static void start(Context context) {
Intent intent = new Intent(context, TorVpnService.class);
diff --git a/orbotservice/src/main/res/drawable/ic_onion.xml b/orbotservice/src/main/res/drawable/ic_onion.xml
new file mode 100644
index 00000000..3047a149
--- /dev/null
+++ b/orbotservice/src/main/res/drawable/ic_onion.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="69.9dp"
+ android:height="107.3dp"
+ android:viewportWidth="69.9"
+ android:viewportHeight="107.3">
+ <path
+ android:pathData="M59.9,54.5c-3.4,-3.1 -7.7,-5.6 -12.1,-8.1c-2,-1.1 -8.1,-5.9 -6,-12.7l-3.8,-1.6c6,-9.3 13.8,-18.5 23.4,-27.1c-7.7,2.6 -14.5,6.6 -19.6,13.7c3,-6.3 7.9,-12.5 13.3,-18.8c-7.4,5.3 -13.8,11.3 -17.8,19.3L40.1,8c-4,7.2 -6.8,14.5 -7.9,21.8l-5.9,-2.4l-1,0.8c5.2,9.3 2.5,14.2 -0.1,15.9C20,47.6 12.5,52.1 8.7,56c-7.2,7.4 -9.3,14.4 -8.6,23.7c0.7,11.9 9.4,21.8 20.9,25.7c5.1,1.7 9.8,1.9 15,1.9c8.4,0 17,-2.2 23.3,-7.5c6.7,-5.5 10.6,-13.9 10.6,-22.5C69.9,68.6 66.3,60.3 59.9,54.5zM18.6,101.8C9.3,97.3 3.1,87.6 2.7,79.7C1.9,63.6 9.6,58.9 16.8,53c4,-3.3 9.6,-4.9 12.8,-10.8c0.6,-1.3 1,-4.1 0.2,-7.1c-0.3,-1 -1.8,-4.6 -2.4,-5.4l8.9,3.9l0,0l0,0c-0.2,4.2 -0.3,7.6 0.5,10.7c0.9,3.4 5.3,8.3 7.1,14c3.5,10.8 2.6,24.9 0.1,35.9c-0.4,1.8 -1.7,4 -3.3,6c0.6,-1.1 1.1,-2.2 1.4,-3.4c2.5,-8.9 3.6,-13 2.4,-22.8c-0.2,-1 -0.6,-4.2 -2.1,-7.7C40.3,61 37.1,56 36.7,54.9c-0.7,-1.7 -1.7,-8.9 -1.8,-13.8C35,45.3 35.3,53 36.4,56c0.3,1 3.2,5.5 5.3,11c1.4,3.8 1.7,7.3 2,8.3c1,4.5 -0.2,12.1 -1.8,19.3c-0.5,2.6 -1.9,5
.6 -3.7,7.9c1,-1.4 1.8,-3.2 2.4,-5.3c1.2,-4.2 1.7,-9.6 1.6,-13c-0.1,-2 -1,-6.3 -2.5,-10.2c-0.9,-2.1 -2.2,-4.3 -3.1,-5.8c-1,-1.5 -1,-4.8 -1.4,-8.6c0.1,4.1 -0.3,6.2 0.7,9.1c0.6,1.7 2.8,4.1 3.4,6.4c0.9,3.1 1.8,6.5 1.7,8.6c0,2.4 -0.1,6.8 -1.2,11.6c-0.7,3.6 -2.3,6.7 -4.9,8.7c1.1,-1.4 1.7,-2.8 2,-4.2c0.4,-2.1 0.5,-4.1 0.7,-6.6c0.2,-2.1 0.1,-4.8 -0.5,-7.7c-0.8,-3.6 -2.1,-7.2 -2.7,-9.7c0.1,2.8 1.2,6.3 1.7,10c0.4,2.7 0.2,5.4 0.1,7.8c-0.1,2.8 -1,7.7 -2.2,10.1c-1.2,-0.5 -1.6,-1.2 -2.4,-2.2c-1,-1.3 -1.6,-2.7 -2.2,-4.3c-0.5,-1.2 -1,-2.6 -1.3,-4.1c-0.3,-2.4 -0.2,-6.1 2.5,-9.9c2.1,-3 2.5,-3.2 3.2,-6.7c-1,3.1 -1.7,3.4 -3.9,6c-2.5,2.9 -2.9,7.1 -2.9,10.5c0,1.4 0.6,3 1.1,4.5c0.6,1.6 1.2,3.2 2,4.4c0.6,1 1.4,1.7 2.1,2.2c-2.6,-0.7 -5.3,-1.7 -7,-3.1c-4.2,-3.6 -7.9,-9.7 -8.4,-15.1c-0.4,-4.4 3.6,-10.8 9.3,-14c4.8,-2.8 5.9,-5.9 6.9,-11c-1.4,4.4 -2.8,8.2 -7.4,10.5C19,75 15.6,80.8 15.9,86.4c0.5,7.1 3.3,12 9,15.9c1.3,0.9 3.1,1.8 5,2.5c-7.1,-1.7 -8,-2.7 -10.4,-5.5c0,-0.2 -0.6,-0.6 -0.6,-0.7c-3.2,-3.6 -7.2,-9.8 -
8.6,-15.5c-0.5,-2 -1,-4.1 -0.4,-6.1c2.6,-9.4 8.3,-13 14,-16.9c1.4,-1 2.8,-1.9 4.1,-2.9c3.2,-2.5 4,-9 4.7,-12.7c-1.3,4.5 -2.7,10.1 -5.2,11.9c-1.3,1 -2.9,1.8 -4.2,2.7c-5.9,4 -11.8,7.8 -14.5,17.5c-0.6,2.5 -0.2,4.3 0.4,6.7c1.5,5.9 5.5,12.3 8.9,16.1c0,0 0.6,0.6 0.6,0.6c1.5,1.7 3.4,3 5.7,3.9C22.3,103.4 20.4,102.7 18.6,101.8z"
+ android:fillColor="#010101"/>
+</vector>
diff --git a/orbotservice/src/main/res/drawable/ic_stat_tor_xfer.png b/orbotservice/src/main/res/drawable/ic_stat_tor_xfer.png
new file mode 100644
index 00000000..d222fb67
Binary files /dev/null and b/orbotservice/src/main/res/drawable/ic_stat_tor_xfer.png differ
diff --git a/orbotservice/src/main/res/drawable/ic_transfer.xml b/orbotservice/src/main/res/drawable/ic_transfer.xml
new file mode 100644
index 00000000..a2d1fa99
--- /dev/null
+++ b/orbotservice/src/main/res/drawable/ic_transfer.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9,3L5,6.99h3L8,14h2L10,6.99h3L9,3zM16,17.01L16,10h-2v7.01h-3L15,21l4,-3.99h-3z"/>
+</vector>
1
0

[orbot/master] switch to Briar jtorctl, upgrade to AndroidX, and tor 0.4.1.6
by n8fr8@torproject.org 28 Apr '20
by n8fr8@torproject.org 28 Apr '20
28 Apr '20
commit 0c8e2e7d24ae349db9b34933636b83f6d641e8f1
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Fri Nov 15 12:30:57 2019 -0500
switch to Briar jtorctl, upgrade to AndroidX, and tor 0.4.1.6
---
app-mini/build.gradle | 4 +-
.../torproject/android/mini/MiniMainActivity.java | 16 +-
.../org/torproject/android/mini/OrbotMiniApp.java | 2 +-
.../android/mini/ui/AppConfigActivity.java | 4 +-
.../android/mini/ui/AppManagerActivity.java | 2 +-
.../mini/ui/NoPersonalizedLearningEditText.java | 2 +-
.../mini/ui/onboarding/CustomSlideBigText.java | 4 +-
.../mini/ui/onboarding/OnboardingActivity.java | 4 +-
.../android/mini/vpn/VPNEnableActivity.java | 2 +-
.../src/main/res/layout/activity_app_config.xml | 10 +-
app-mini/src/main/res/layout/layout_main.xml | 10 +-
app/build.gradle | 2 +-
app/src/main/AndroidManifest.xml | 2 +-
.../main/java/org/torproject/android/OrbotApp.java | 2 +-
.../org/torproject/android/OrbotMainActivity.java | 12 +-
.../torproject/android/ui/AppManagerActivity.java | 2 +-
.../android/ui/NoPersonalizedLearningEditText.java | 2 +-
.../torproject/android/ui/VPNEnableActivity.java | 2 +-
.../ui/hiddenservices/ClientCookiesActivity.java | 6 +-
.../ui/hiddenservices/HiddenServicesActivity.java | 8 +-
.../adapters/ClientCookiesAdapter.java | 2 +-
.../hiddenservices/adapters/OnionListAdapter.java | 2 +-
.../android/ui/hiddenservices/backup/ZipIt.java | 4 +-
.../ui/hiddenservices/dialogs/AddCookieDialog.java | 6 +-
.../dialogs/CookieActionsDialog.java | 6 +-
.../hiddenservices/dialogs/CookieDeleteDialog.java | 6 +-
.../ui/hiddenservices/dialogs/HSActionsDialog.java | 6 +-
.../ui/hiddenservices/dialogs/HSCookieDialog.java | 6 +-
.../ui/hiddenservices/dialogs/HSDataDialog.java | 6 +-
.../ui/hiddenservices/dialogs/HSDeleteDialog.java | 6 +-
.../dialogs/SelectCookieBackupDialog.java | 6 +-
.../dialogs/SelectHSBackupDialog.java | 6 +-
.../permissions/PermissionManager.java | 6 +-
.../providers/CookieContentProvider.java | 4 +-
.../providers/HSContentProvider.java | 4 +-
.../ui/onboarding/BridgeWizardActivity.java | 4 +-
.../android/ui/onboarding/CustomSlideBigText.java | 4 +-
.../android/ui/onboarding/OnboardingActivity.java | 4 +-
app/src/main/res/layout/activity_bridge_wizard.xml | 10 +-
.../res/layout/layout_activity_client_cookies.xml | 12 +-
app/src/main/res/layout/layout_hs_list_view.xml | 12 +-
app/src/main/res/layout/layout_main.xml | 10 +-
gradle.properties | 2 +
orbotservice/build.gradle | 6 +-
.../java/org/torproject/android/control/Bytes.java | 114 ----
.../torproject/android/control/ConfigEntry.java | 20 -
.../torproject/android/control/EventHandler.java | 75 ---
.../torproject/android/control/PasswordDigest.java | 98 ---
.../android/control/TorControlCommands.java | 148 -----
.../android/control/TorControlConnection.java | 730 ---------------------
.../android/control/TorControlError.java | 39 --
.../android/control/TorControlSyntaxError.java | 16 -
.../android/service/TorEventHandler.java | 4 +-
.../org/torproject/android/service/TorService.java | 18 +-
.../android/service/util/CustomShell.java | 6 +-
.../android/service/vpn/TorVpnService.java | 2 +-
56 files changed, 138 insertions(+), 1370 deletions(-)
diff --git a/app-mini/build.gradle b/app-mini/build.gradle
index e48340e8..76f2a0ce 100644
--- a/app-mini/build.gradle
+++ b/app-mini/build.gradle
@@ -102,9 +102,9 @@ android {
dependencies {
implementation project(':orbotservice')
implementation 'com.github.apl-devs:appintro:v4.2.2'
- implementation 'com.android.support:palette-v7:28.0.0'
+ implementation 'androidx.palette:palette:1.0.0'
implementation 'com.github.javiersantos:AppUpdater:2.7'
- implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
androidTestImplementation "tools.fastlane:screengrab:1.2.0"
}
diff --git a/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java b/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java
index d43cec81..bc46b251 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java
@@ -23,14 +23,14 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.graphics.Palette;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.SwitchCompat;
-import android.support.v7.widget.Toolbar;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.palette.graphics.Palette;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.SwitchCompat;
+import androidx.appcompat.widget.Toolbar;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
diff --git a/app-mini/src/main/java/org/torproject/android/mini/OrbotMiniApp.java b/app-mini/src/main/java/org/torproject/android/mini/OrbotMiniApp.java
index 80b34d6d..41bd0697 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/OrbotMiniApp.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/OrbotMiniApp.java
@@ -11,7 +11,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.support.v4.app.NotificationCompat;
+import androidx.core.app.NotificationCompat;
import com.github.javiersantos.appupdater.AppUpdater;
import com.github.javiersantos.appupdater.enums.Display;
import com.github.javiersantos.appupdater.enums.UpdateFrom;
diff --git a/app-mini/src/main/java/org/torproject/android/mini/ui/AppConfigActivity.java b/app-mini/src/main/java/org/torproject/android/mini/ui/AppConfigActivity.java
index a731ef29..03b56bfa 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/ui/AppConfigActivity.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/ui/AppConfigActivity.java
@@ -4,8 +4,8 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
diff --git a/app-mini/src/main/java/org/torproject/android/mini/ui/AppManagerActivity.java b/app-mini/src/main/java/org/torproject/android/mini/ui/AppManagerActivity.java
index 489aba4c..1af635d0 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/ui/AppManagerActivity.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/ui/AppManagerActivity.java
@@ -12,7 +12,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
diff --git a/app-mini/src/main/java/org/torproject/android/mini/ui/NoPersonalizedLearningEditText.java b/app-mini/src/main/java/org/torproject/android/mini/ui/NoPersonalizedLearningEditText.java
index a5d67d79..07d91429 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/ui/NoPersonalizedLearningEditText.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/ui/NoPersonalizedLearningEditText.java
@@ -1,7 +1,7 @@
package org.torproject.android.mini.ui;
import android.content.Context;
-import android.support.v7.widget.AppCompatEditText;
+import androidx.appcompat.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
diff --git a/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/CustomSlideBigText.java b/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/CustomSlideBigText.java
index a370c6f1..a4512639 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/CustomSlideBigText.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/CustomSlideBigText.java
@@ -1,8 +1,8 @@
package org.torproject.android.mini.ui.onboarding;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/OnboardingActivity.java b/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/OnboardingActivity.java
index 5e661999..bce4585a 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/OnboardingActivity.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/ui/onboarding/OnboardingActivity.java
@@ -2,8 +2,8 @@ package org.torproject.android.mini.ui.onboarding;
import android.content.Context;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import com.github.paolorotolo.appintro.AppIntro;
import org.torproject.android.mini.R;
import org.torproject.android.mini.settings.LocaleHelper;
diff --git a/app-mini/src/main/java/org/torproject/android/mini/vpn/VPNEnableActivity.java b/app-mini/src/main/java/org/torproject/android/mini/vpn/VPNEnableActivity.java
index bb263372..d65913b5 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/vpn/VPNEnableActivity.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/vpn/VPNEnableActivity.java
@@ -5,7 +5,7 @@ import android.net.VpnService;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.Window;
import org.torproject.android.service.TorService;
diff --git a/app-mini/src/main/res/layout/activity_app_config.xml b/app-mini/src/main/res/layout/activity_app_config.xml
index accb290b..e2b12feb 100644
--- a/app-mini/src/main/res/layout/activity_app_config.xml
+++ b/app-mini/src/main/res/layout/activity_app_config.xml
@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.AppConfigActivity">
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/DefaultTheme.AppBarOverlay">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/dark_green"
app:popupTheme="@style/DefaultTheme.PopupOverlay" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_app_config" />
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app-mini/src/main/res/layout/layout_main.xml b/app-mini/src/main/res/layout/layout_main.xml
index d8fbfce6..9fff25b8 100644
--- a/app-mini/src/main/res/layout/layout_main.xml
+++ b/app-mini/src/main/res/layout/layout_main.xml
@@ -8,12 +8,12 @@
android:background="@color/light_gray"
xmlns:app="http://schemas.android.com/apk/res-auto">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
- <android.support.v4.widget.DrawerLayout
+ <androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -23,7 +23,7 @@
android:layout_height="match_parent">
-<android.support.v7.widget.RecyclerView
+<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rv"
@@ -62,7 +62,7 @@
android:layout_margin="0dp"
android:src="@drawable/toroff" />
- <android.support.v7.widget.SwitchCompat
+ <androidx.appcompat.widget.SwitchCompat
android:id="@+id/btnVPN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -139,7 +139,7 @@
/>
</LinearLayout>
- </android.support.v4.widget.DrawerLayout>
+ </androidx.drawerlayout.widget.DrawerLayout>
</LinearLayout>
diff --git a/app/build.gradle b/app/build.gradle
index 1c89e568..3c5d265f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -117,7 +117,7 @@ android {
dependencies {
implementation project(':orbotservice')
- implementation 'com.android.support:design:28.0.0'
+ implementation 'com.google.android.material:material:1.0.0'
implementation 'pl.bclogic:pulsator4droid:1.0.3'
implementation 'com.github.apl-devs:appintro:v4.2.2'
implementation 'com.github.javiersantos:AppUpdater:2.6.4'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f118253e..184dbdd9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -137,7 +137,7 @@
android:authorities="org.torproject.android.ui.hiddenservices.providers"
android:exported="false" />
<provider
- android:name="android.support.v4.content.FileProvider"
+ android:name="androidx.core.content.FileProvider"
android:authorities="org.torproject.android.ui.hiddenservices.storage"
android:exported="false"
android:grantUriPermissions="true">
diff --git a/app/src/main/java/org/torproject/android/OrbotApp.java b/app/src/main/java/org/torproject/android/OrbotApp.java
index f022f611..e265bef8 100644
--- a/app/src/main/java/org/torproject/android/OrbotApp.java
+++ b/app/src/main/java/org/torproject/android/OrbotApp.java
@@ -11,7 +11,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.support.v4.app.NotificationCompat;
+import androidx.core.app.NotificationCompat;
import com.github.javiersantos.appupdater.AppUpdater;
import com.github.javiersantos.appupdater.enums.Display;
import com.github.javiersantos.appupdater.enums.UpdateFrom;
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
index 4ff3e850..64f1ee42 100644
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@ -24,11 +24,11 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.SwitchCompat;
-import android.support.v7.widget.Toolbar;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.SwitchCompat;
+import androidx.appcompat.widget.Toolbar;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
@@ -87,7 +87,7 @@ import java.util.ArrayList;
import java.util.Locale;
import java.util.StringTokenizer;
-import static android.support.v4.content.FileProvider.getUriForFile;
+import static androidx.core.content.FileProvider.getUriForFile;
import static org.torproject.android.MainConstants.COUNTRY_CODES;
import static org.torproject.android.MainConstants.RESULT_CLOSE_ALL;
import static org.torproject.android.MainConstants.URL_TOR_CHECK;
diff --git a/app/src/main/java/org/torproject/android/ui/AppManagerActivity.java b/app/src/main/java/org/torproject/android/ui/AppManagerActivity.java
index 111dda5f..98e62a1f 100644
--- a/app/src/main/java/org/torproject/android/ui/AppManagerActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/AppManagerActivity.java
@@ -12,7 +12,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
diff --git a/app/src/main/java/org/torproject/android/ui/NoPersonalizedLearningEditText.java b/app/src/main/java/org/torproject/android/ui/NoPersonalizedLearningEditText.java
index 15d8d023..7a21c7c5 100644
--- a/app/src/main/java/org/torproject/android/ui/NoPersonalizedLearningEditText.java
+++ b/app/src/main/java/org/torproject/android/ui/NoPersonalizedLearningEditText.java
@@ -1,7 +1,7 @@
package org.torproject.android.ui;
import android.content.Context;
-import android.support.v7.widget.AppCompatEditText;
+import androidx.appcompat.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
diff --git a/app/src/main/java/org/torproject/android/ui/VPNEnableActivity.java b/app/src/main/java/org/torproject/android/ui/VPNEnableActivity.java
index e910be32..be26e315 100644
--- a/app/src/main/java/org/torproject/android/ui/VPNEnableActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/VPNEnableActivity.java
@@ -5,7 +5,7 @@ import android.net.VpnService;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.Window;
import org.torproject.android.service.TorService;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java
index 8ff14fbb..4b76e1e7 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java
@@ -9,9 +9,9 @@ import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
index f41babdf..04404df2 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
@@ -8,10 +8,10 @@ import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v4.view.MenuItemCompat;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import androidx.core.view.MenuItemCompat;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/ClientCookiesAdapter.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/ClientCookiesAdapter.java
index 10108ba8..e0db9528 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/ClientCookiesAdapter.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/ClientCookiesAdapter.java
@@ -4,7 +4,7 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
+import androidx.cursoradapter.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/OnionListAdapter.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/OnionListAdapter.java
index a41befdf..485afe09 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/OnionListAdapter.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/adapters/OnionListAdapter.java
@@ -4,7 +4,7 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
+import androidx.cursoradapter.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
index 130b56bb..4a42df1f 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/ZipIt.java
@@ -1,8 +1,8 @@
package org.torproject.android.ui.hiddenservices.backup;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/AddCookieDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/AddCookieDialog.java
index af8922d6..c47d9ae8 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/AddCookieDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/AddCookieDialog.java
@@ -5,9 +5,9 @@ import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java
index 03dddbd6..a060453d 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java
@@ -6,9 +6,9 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieDeleteDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieDeleteDialog.java
index d2b1220d..ed847cdc 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieDeleteDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieDeleteDialog.java
@@ -5,9 +5,9 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import org.torproject.android.R;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
index ce77fd2a..31ae2bee 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
@@ -8,9 +8,9 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSCookieDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSCookieDialog.java
index eb9ee9ce..054516fb 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSCookieDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSCookieDialog.java
@@ -5,9 +5,9 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
index d7ba35e3..bfae0ca3 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDataDialog.java
@@ -5,9 +5,9 @@ import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDeleteDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDeleteDialog.java
index cf38ffab..a0951d35 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDeleteDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSDeleteDialog.java
@@ -5,9 +5,9 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import org.torproject.android.R;
import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectCookieBackupDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectCookieBackupDialog.java
index af362358..a8e380d9 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectCookieBackupDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectCookieBackupDialog.java
@@ -3,9 +3,9 @@ package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectHSBackupDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectHSBackupDialog.java
index cb0c2bfe..ae15ae49 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectHSBackupDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/SelectHSBackupDialog.java
@@ -3,9 +3,9 @@ package org.torproject.android.ui.hiddenservices.dialogs;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AlertDialog;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+import androidx.appcompat.app.AlertDialog;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/permissions/PermissionManager.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/permissions/PermissionManager.java
index 3ee11ec8..eb1a40b4 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/permissions/PermissionManager.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/permissions/PermissionManager.java
@@ -11,9 +11,9 @@ import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.FragmentActivity;
+import com.google.android.material.snackbar.Snackbar;
+import androidx.core.app.ActivityCompat;
+import androidx.fragment.app.FragmentActivity;
import android.view.View;
import org.torproject.android.R;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/CookieContentProvider.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/CookieContentProvider.java
index 1f31b9cb..318e37af 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/CookieContentProvider.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/CookieContentProvider.java
@@ -9,8 +9,8 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.BaseColumns;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import org.torproject.android.ui.hiddenservices.database.HSDatabase;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
index 07641ea0..5cf20f8e 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/providers/HSContentProvider.java
@@ -9,8 +9,8 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.BaseColumns;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import org.torproject.android.ui.hiddenservices.database.HSDatabase;
diff --git a/app/src/main/java/org/torproject/android/ui/onboarding/BridgeWizardActivity.java b/app/src/main/java/org/torproject/android/ui/onboarding/BridgeWizardActivity.java
index 15216333..6e54e103 100644
--- a/app/src/main/java/org/torproject/android/ui/onboarding/BridgeWizardActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/onboarding/BridgeWizardActivity.java
@@ -8,8 +8,8 @@ import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
diff --git a/app/src/main/java/org/torproject/android/ui/onboarding/CustomSlideBigText.java b/app/src/main/java/org/torproject/android/ui/onboarding/CustomSlideBigText.java
index 2ed1c01c..b4f319b2 100644
--- a/app/src/main/java/org/torproject/android/ui/onboarding/CustomSlideBigText.java
+++ b/app/src/main/java/org/torproject/android/ui/onboarding/CustomSlideBigText.java
@@ -1,8 +1,8 @@
package org.torproject.android.ui.onboarding;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
diff --git a/app/src/main/java/org/torproject/android/ui/onboarding/OnboardingActivity.java b/app/src/main/java/org/torproject/android/ui/onboarding/OnboardingActivity.java
index 88359434..e73a88b8 100644
--- a/app/src/main/java/org/torproject/android/ui/onboarding/OnboardingActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/onboarding/OnboardingActivity.java
@@ -3,8 +3,8 @@ package org.torproject.android.ui.onboarding;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
import android.view.View;
import com.github.paolorotolo.appintro.AppIntro;
import org.torproject.android.R;
diff --git a/app/src/main/res/layout/activity_bridge_wizard.xml b/app/src/main/res/layout/activity_bridge_wizard.xml
index 7ff470c9..d5b88c0d 100644
--- a/app/src/main/res/layout/activity_bridge_wizard.xml
+++ b/app/src/main/res/layout/activity_bridge_wizard.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -8,20 +8,20 @@
tools:context="org.torproject.android.ui.onboarding.BridgeWizardActivity">
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/DefaultTheme.AppBarOverlay">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/DefaultTheme.PopupOverlay" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_bridge_wizard" />
-</android.support.design.widget.CoordinatorLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/layout_activity_client_cookies.xml b/app/src/main/res/layout/layout_activity_client_cookies.xml
index b8f0626e..9314255d 100644
--- a/app/src/main/res/layout/layout_activity_client_cookies.xml
+++ b/app/src/main/res/layout/layout_activity_client_cookies.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -7,23 +7,23 @@
android:fitsSystemWindows="true"
tools:context="org.torproject.android.ui.hiddenservices.ClientCookiesActivity">
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/DefaultTheme.AppBarOverlay">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/DefaultTheme.PopupOverlay" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/layout_content_client_cookies" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -32,4 +32,4 @@
app:srcCompat="@android:drawable/stat_notify_more"
app:backgroundTint="@android:color/darker_gray" />
-</android.support.design.widget.CoordinatorLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/layout_hs_list_view.xml b/app/src/main/res/layout/layout_hs_list_view.xml
index 4981877d..e4171949 100644
--- a/app/src/main/res/layout/layout_hs_list_view.xml
+++ b/app/src/main/res/layout/layout_hs_list_view.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -7,21 +7,21 @@
android:fitsSystemWindows="true"
tools:context="org.torproject.android.ui.hiddenservices.HiddenServicesActivity">
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/layout_hs_list_view_main" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -30,4 +30,4 @@
app:srcCompat="@android:drawable/stat_notify_more"
app:backgroundTint="@android:color/darker_gray" />
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_main.xml b/app/src/main/res/layout/layout_main.xml
index 42e6691f..106cf921 100644
--- a/app/src/main/res/layout/layout_main.xml
+++ b/app/src/main/res/layout/layout_main.xml
@@ -9,12 +9,12 @@
android:background="@color/dark_purple"
xmlns:app="http://schemas.android.com/apk/res-auto">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
- <android.support.v4.widget.DrawerLayout
+ <androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -147,7 +147,7 @@
android:layout_weight="1"
>
- <android.support.v7.widget.SwitchCompat
+ <androidx.appcompat.widget.SwitchCompat
android:id="@+id/btnVPN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -261,7 +261,7 @@
android:lines="1"
/>
- <android.support.v7.widget.SwitchCompat
+ <androidx.appcompat.widget.SwitchCompat
android:id="@+id/btnBridges"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -336,7 +336,7 @@
/>
</LinearLayout>
- </android.support.v4.widget.DrawerLayout>
+ </androidx.drawerlayout.widget.DrawerLayout>
</LinearLayout>
diff --git a/gradle.properties b/gradle.properties
index d5f3dfc4..1cf3bf02 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,6 +6,8 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
+android.enableJetifier=true
+android.useAndroidX=true
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
diff --git a/orbotservice/build.gradle b/orbotservice/build.gradle
index 13987ab9..5f8cadba 100644
--- a/orbotservice/build.gradle
+++ b/orbotservice/build.gradle
@@ -41,9 +41,9 @@ android {
dependencies {
- implementation 'com.android.support:support-v4:28.0.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'org.torproject:tor-android-binary:0.4.1.5'
+ implementation 'org.torproject:tor-android-binary:0.4.1.6-dev'
implementation 'info.pluggabletransports.aptds:apt-dispatch-library:1.0.7'
implementation 'info.pluggabletransports.aptds:apt-meek-obfs4-legacy:1.0.7'
implementation 'info.pluggabletransports.aptds:jsocksAndroid:1.0.4'
@@ -53,4 +53,6 @@ dependencies {
testImplementation 'junit:junit:4.12'
implementation 'com.offbynull.portmapper:portmapper:2.0.5'
+
+ implementation 'org.briarproject:jtorctl:0.3'
}
diff --git a/orbotservice/src/main/java/org/torproject/android/control/Bytes.java b/orbotservice/src/main/java/org/torproject/android/control/Bytes.java
deleted file mode 100644
index e754d907..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/Bytes.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Static class to do bytewise structure manipulation in Java.
- */
-/* XXXX There must be a better way to do most of this.
- * XXXX The string logic here uses default encoding, which is stupid.
- */
-final class Bytes {
-
- /** Write the two-byte value in 's' into the byte array 'ba', starting at
- * the index 'pos'. */
- public static void setU16(byte[] ba, int pos, short s) {
- ba[pos] = (byte)((s >> 8) & 0xff);
- ba[pos+1] = (byte)((s ) & 0xff);
- }
-
- /** Write the four-byte value in 'i' into the byte array 'ba', starting at
- * the index 'pos'. */
- public static void setU32(byte[] ba, int pos, int i) {
- ba[pos] = (byte)((i >> 24) & 0xff);
- ba[pos+1] = (byte)((i >> 16) & 0xff);
- ba[pos+2] = (byte)((i >> 8) & 0xff);
- ba[pos+3] = (byte)((i ) & 0xff);
- }
-
- /** Return the four-byte value starting at index 'pos' within 'ba' */
- public static int getU32(byte[] ba, int pos) {
- return
- ((ba[pos ]&0xff)<<24) |
- ((ba[pos+1]&0xff)<<16) |
- ((ba[pos+2]&0xff)<< 8) |
- ((ba[pos+3]&0xff));
- }
-
- public static String getU32S(byte[] ba, int pos) {
- return String.valueOf( (getU32(ba,pos))&0xffffffffL );
- }
-
- /** Return the two-byte value starting at index 'pos' within 'ba' */
- public static int getU16(byte[] ba, int pos) {
- return
- ((ba[pos ]&0xff)<<8) |
- ((ba[pos+1]&0xff));
- }
-
- /** Return the string starting at position 'pos' of ba and extending
- * until a zero byte or the end of the string. */
- public static String getNulTerminatedStr(byte[] ba, int pos) {
- int len, maxlen = ba.length-pos;
- for (len=0; len<maxlen; ++len) {
- if (ba[pos+len] == 0)
- break;
- }
- return new String(ba, pos, len);
- }
-
- /**
- * Read bytes from 'ba' starting at 'pos', dividing them into strings
- * along the character in 'split' and writing them into 'lst'
- */
- public static void splitStr(List<String> lst, byte[] ba, int pos, byte split) {
- while (pos < ba.length && ba[pos] != 0) {
- int len;
- for (len=0; pos+len < ba.length; ++len) {
- if (ba[pos+len] == 0 || ba[pos+len] == split)
- break;
- }
- if (len>0)
- lst.add(new String(ba, pos, len));
- pos += len;
- if (ba[pos] == split)
- ++pos;
- }
- }
-
- /**
- * Read bytes from 'ba' starting at 'pos', dividing them into strings
- * along the character in 'split' and writing them into 'lst'
- */
- public static List<String> splitStr(List<String> lst, String str) {
- // split string on spaces, include trailing/leading
- String[] tokenArray = str.split(" ", -1);
- if (lst == null) {
- lst = Arrays.asList( tokenArray );
- } else {
- lst.addAll( Arrays.asList( tokenArray ) );
- }
- return lst;
- }
-
- private static final char[] NYBBLES = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
-
- public static final String hex(byte[] ba) {
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < ba.length; ++i) {
- int b = (ba[i]) & 0xff;
- buf.append(NYBBLES[b >> 4]);
- buf.append(NYBBLES[b&0x0f]);
- }
- return buf.toString();
- }
-
- private Bytes() {};
-}
-
diff --git a/orbotservice/src/main/java/org/torproject/android/control/ConfigEntry.java b/orbotservice/src/main/java/org/torproject/android/control/ConfigEntry.java
deleted file mode 100644
index 31eb4b8e..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/ConfigEntry.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-/** A single key-value pair from Tor's configuration. */
-public class ConfigEntry {
- public ConfigEntry(String k, String v) {
- key = k;
- value = v;
- is_default = false;
- }
- public ConfigEntry(String k) {
- key = k;
- value = "";
- is_default = true;
- }
- public final String key;
- public final String value;
- public final boolean is_default;
-}
diff --git a/orbotservice/src/main/java/org/torproject/android/control/EventHandler.java b/orbotservice/src/main/java/org/torproject/android/control/EventHandler.java
deleted file mode 100644
index de06bf0f..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/EventHandler.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-/**
- * Abstract interface whose methods are invoked when Tor sends us an event.
- *
- * @see TorControlConnection#setEventHandler
- * @see TorControlConnection#setEvents
- */
-public interface EventHandler {
- /**
- * Invoked when a circuit's status has changed.
- * Possible values for <b>status</b> are:
- * <ul>
- * <li>"LAUNCHED" : circuit ID assigned to new circuit</li>
- * <li>"BUILT" : all hops finished, can now accept streams</li>
- * <li>"EXTENDED" : one more hop has been completed</li>
- * <li>"FAILED" : circuit closed (was not built)</li>
- * <li>"CLOSED" : circuit closed (was built)</li>
- * </ul>
- *
- * <b>circID</b> is the alphanumeric identifier of the affected circuit,
- * and <b>path</b> is a comma-separated list of alphanumeric ServerIDs.
- */
- public void circuitStatus(String status, String circID, String path);
- /**
- * Invoked when a stream's status has changed.
- * Possible values for <b>status</b> are:
- * <ul>
- * <li>"NEW" : New request to connect</li>
- * <li>"NEWRESOLVE" : New request to resolve an address</li>
- * <li>"SENTCONNECT" : Sent a connect cell along a circuit</li>
- * <li>"SENTRESOLVE" : Sent a resolve cell along a circuit</li>
- * <li>"SUCCEEDED" : Received a reply; stream established</li>
- * <li>"FAILED" : Stream failed and not retriable.</li>
- * <li>"CLOSED" : Stream closed</li>
- * <li>"DETACHED" : Detached from circuit; still retriable.</li>
- * </ul>
- *
- * <b>streamID</b> is the alphanumeric identifier of the affected stream,
- * and its <b>target</b> is specified as address:port.
- */
- public void streamStatus(String status, String streamID, String target);
- /**
- * Invoked when the status of a connection to an OR has changed.
- * Possible values for <b>status</b> are ["LAUNCHED" | "CONNECTED" | "FAILED" | "CLOSED"].
- * <b>orName</b> is the alphanumeric identifier of the OR affected.
- */
- public void orConnStatus(String status, String orName);
- /**
- * Invoked once per second. <b>read</b> and <b>written</b> are
- * the number of bytes read and written, respectively, in
- * the last second.
- */
- public void bandwidthUsed(long read, long written);
- /**
- * Invoked whenever Tor learns about new ORs. The <b>orList</b> object
- * contains the alphanumeric ServerIDs associated with the new ORs.
- */
- public void newDescriptors(java.util.List<String> orList);
- /**
- * Invoked when Tor logs a message.
- * <b>severity</b> is one of ["DEBUG" | "INFO" | "NOTICE" | "WARN" | "ERR"],
- * and <b>msg</b> is the message string.
- */
- public void message(String severity, String msg);
- /**
- * Invoked when an unspecified message is received.
- * <type> is the message type, and <msg> is the message string.
- */
- public void unrecognized(String type, String msg);
-
-}
-
diff --git a/orbotservice/src/main/java/org/torproject/android/control/PasswordDigest.java b/orbotservice/src/main/java/org/torproject/android/control/PasswordDigest.java
deleted file mode 100644
index 03d0a98e..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/PasswordDigest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
-/**
- * A hashed digest of a secret password (used to set control connection
- * security.)
- *
- * For the actual hashing algorithm, see RFC2440's secret-to-key conversion.
- */
-public class PasswordDigest {
-
- private final byte[] secret;
- private final String hashedKey;
-
- /** Return a new password digest with a random secret and salt. */
- public static PasswordDigest generateDigest() {
- byte[] secret = new byte[20];
- SecureRandom rng = new SecureRandom();
- rng.nextBytes(secret);
- return new PasswordDigest(secret);
- }
-
- /** Construct a new password digest with a given secret and random salt */
- public PasswordDigest(byte[] secret) {
- this(secret, null);
- }
-
- /** Construct a new password digest with a given secret and random salt.
- * Note that the 9th byte of the specifier determines the number of hash
- * iterations as in RFC2440.
- */
- public PasswordDigest(byte[] secret, byte[] specifier) {
- this.secret = secret.clone();
- if (specifier == null) {
- specifier = new byte[9];
- SecureRandom rng = new SecureRandom();
- rng.nextBytes(specifier);
- specifier[8] = 96;
- }
- hashedKey = "16:"+encodeBytes(secretToKey(secret, specifier));
- }
-
- /** Return the secret used to generate this password hash.
- */
- public byte[] getSecret() {
- return secret.clone();
- }
-
- /** Return the hashed password in the format used by Tor. */
- public String getHashedPassword() {
- return hashedKey;
- }
-
- /** Parameter used by RFC2440's s2k algorithm. */
- private static final int EXPBIAS = 6;
-
- /** Implement rfc2440 s2k */
- public static byte[] secretToKey(byte[] secret, byte[] specifier) {
- MessageDigest d;
- try {
- d = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException ex) {
- throw new RuntimeException("Can't run without sha-1.");
- }
- int c = (specifier[8])&0xff;
- int count = (16 + (c&15)) << ((c>>4) + EXPBIAS);
-
- byte[] tmp = new byte[8+secret.length];
- System.arraycopy(specifier, 0, tmp, 0, 8);
- System.arraycopy(secret, 0, tmp, 8, secret.length);
- while (count > 0) {
- if (count >= tmp.length) {
- d.update(tmp);
- count -= tmp.length;
- } else {
- d.update(tmp, 0, count);
- count = 0;
- }
- }
- byte[] key = new byte[20+9];
- System.arraycopy(d.digest(), 0, key, 9, 20);
- System.arraycopy(specifier, 0, key, 0, 9);
- return key;
- }
-
- /** Return a hexadecimal encoding of a byte array. */
- // XXX There must be a better way to do this in Java.
- private static final String encodeBytes(byte[] ba) {
- return Bytes.hex(ba);
- }
-
-}
-
diff --git a/orbotservice/src/main/java/org/torproject/android/control/TorControlCommands.java b/orbotservice/src/main/java/org/torproject/android/control/TorControlCommands.java
deleted file mode 100644
index c98a1c48..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/TorControlCommands.java
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-/** Interface defining constants used by the Tor controller protocol.
- */
-// XXXX Take documentation for these from control-spec.txt
-public interface TorControlCommands {
-
- public static final short CMD_ERROR = 0x0000;
- public static final short CMD_DONE = 0x0001;
- public static final short CMD_SETCONF = 0x0002;
- public static final short CMD_GETCONF = 0x0003;
- public static final short CMD_CONFVALUE = 0x0004;
- public static final short CMD_SETEVENTS = 0x0005;
- public static final short CMD_EVENT = 0x0006;
- public static final short CMD_AUTH = 0x0007;
- public static final short CMD_SAVECONF = 0x0008;
- public static final short CMD_SIGNAL = 0x0009;
- public static final short CMD_MAPADDRESS = 0x000A;
- public static final short CMD_GETINFO = 0x000B;
- public static final short CMD_INFOVALUE = 0x000C;
- public static final short CMD_EXTENDCIRCUIT = 0x000D;
- public static final short CMD_ATTACHSTREAM = 0x000E;
- public static final short CMD_POSTDESCRIPTOR = 0x000F;
- public static final short CMD_FRAGMENTHEADER = 0x0010;
- public static final short CMD_FRAGMENT = 0x0011;
- public static final short CMD_REDIRECTSTREAM = 0x0012;
- public static final short CMD_CLOSESTREAM = 0x0013;
- public static final short CMD_CLOSECIRCUIT = 0x0014;
-
- public static final String[] CMD_NAMES = {
- "ERROR",
- "DONE",
- "SETCONF",
- "GETCONF",
- "CONFVALUE",
- "SETEVENTS",
- "EVENT",
- "AUTH",
- "SAVECONF",
- "SIGNAL",
- "MAPADDRESS",
- "GETINFO",
- "INFOVALUE",
- "EXTENDCIRCUIT",
- "ATTACHSTREAM",
- "POSTDESCRIPTOR",
- "FRAGMENTHEADER",
- "FRAGMENT",
- "REDIRECTSTREAM",
- "CLOSESTREAM",
- "CLOSECIRCUIT",
- };
-
- public static final short EVENT_CIRCSTATUS = 0x0001;
- public static final short EVENT_STREAMSTATUS = 0x0002;
- public static final short EVENT_ORCONNSTATUS = 0x0003;
- public static final short EVENT_BANDWIDTH = 0x0004;
- public static final short EVENT_NEWDESCRIPTOR = 0x0006;
- public static final short EVENT_MSG_DEBUG = 0x0007;
- public static final short EVENT_MSG_INFO = 0x0008;
- public static final short EVENT_MSG_NOTICE = 0x0009;
- public static final short EVENT_MSG_WARN = 0x000A;
- public static final short EVENT_MSG_ERROR = 0x000B;
-
- public static final String[] EVENT_NAMES = {
- "(0)",
- "CIRC",
- "STREAM",
- "ORCONN",
- "BW",
- "OLDLOG",
- "NEWDESC",
- "DEBUG",
- "INFO",
- "NOTICE",
- "WARN",
- "ERR",
- };
-
- public static final byte CIRC_STATUS_LAUNCHED = 0x01;
- public static final byte CIRC_STATUS_BUILT = 0x02;
- public static final byte CIRC_STATUS_EXTENDED = 0x03;
- public static final byte CIRC_STATUS_FAILED = 0x04;
- public static final byte CIRC_STATUS_CLOSED = 0x05;
-
- public static final String[] CIRC_STATUS_NAMES = {
- "LAUNCHED",
- "BUILT",
- "EXTENDED",
- "FAILED",
- "CLOSED",
- };
-
- public static final byte STREAM_STATUS_SENT_CONNECT = 0x00;
- public static final byte STREAM_STATUS_SENT_RESOLVE = 0x01;
- public static final byte STREAM_STATUS_SUCCEEDED = 0x02;
- public static final byte STREAM_STATUS_FAILED = 0x03;
- public static final byte STREAM_STATUS_CLOSED = 0x04;
- public static final byte STREAM_STATUS_NEW_CONNECT = 0x05;
- public static final byte STREAM_STATUS_NEW_RESOLVE = 0x06;
- public static final byte STREAM_STATUS_DETACHED = 0x07;
-
- public static final String[] STREAM_STATUS_NAMES = {
- "SENT_CONNECT",
- "SENT_RESOLVE",
- "SUCCEEDED",
- "FAILED",
- "CLOSED",
- "NEW_CONNECT",
- "NEW_RESOLVE",
- "DETACHED"
- };
-
- public static final byte OR_CONN_STATUS_LAUNCHED = 0x00;
- public static final byte OR_CONN_STATUS_CONNECTED = 0x01;
- public static final byte OR_CONN_STATUS_FAILED = 0x02;
- public static final byte OR_CONN_STATUS_CLOSED = 0x03;
-
- public static final String[] OR_CONN_STATUS_NAMES = {
- "LAUNCHED","CONNECTED","FAILED","CLOSED"
- };
-
- public static final byte SIGNAL_HUP = 0x01;
- public static final byte SIGNAL_INT = 0x02;
- public static final byte SIGNAL_USR1 = 0x0A;
- public static final byte SIGNAL_USR2 = 0x0C;
- public static final byte SIGNAL_TERM = 0x0F;
-
- public static final String ERROR_MSGS[] = {
- "Unspecified error",
- "Internal error",
- "Unrecognized message type",
- "Syntax error",
- "Unrecognized configuration key",
- "Invalid configuration value",
- "Unrecognized byte code",
- "Unauthorized",
- "Failed authentication attempt",
- "Resource exhausted",
- "No such stream",
- "No such circuit",
- "No such OR",
- };
-
-}
-
diff --git a/orbotservice/src/main/java/org/torproject/android/control/TorControlConnection.java b/orbotservice/src/main/java/org/torproject/android/control/TorControlConnection.java
deleted file mode 100644
index bed62128..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/TorControlConnection.java
+++ /dev/null
@@ -1,730 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/** A connection to a running Tor process as specified in control-spec.txt. */
-public class TorControlConnection implements TorControlCommands {
-
- private final LinkedList<Waiter> waiters;
- private final BufferedReader input;
- private final Writer output;
-
- private ControlParseThread thread; // Locking: this
-
- private volatile EventHandler handler;
- private volatile PrintWriter debugOutput;
- private volatile IOException parseThreadException;
-
- static class Waiter {
-
- List<ReplyLine> response; // Locking: this
-
- synchronized List<ReplyLine> getResponse() throws InterruptedException {
- while (response == null) {
- wait();
- }
- return response;
- }
-
- synchronized void setResponse(List<ReplyLine> response) {
- this.response = response;
- notifyAll();
- }
- }
-
- static class ReplyLine {
-
- final String status;
- final String msg;
- final String rest;
-
- ReplyLine(String status, String msg, String rest) {
- this.status = status; this.msg = msg; this.rest = rest;
- }
- }
-
- /** Create a new TorControlConnection to communicate with Tor over
- * a given socket. After calling this constructor, it is typical to
- * call launchThread and authenticate. */
- public TorControlConnection(Socket connection) throws IOException {
- this(connection.getInputStream(), connection.getOutputStream());
- }
-
- /** Create a new TorControlConnection to communicate with Tor over
- * an arbitrary pair of data streams.
- */
- public TorControlConnection(InputStream i, OutputStream o) {
- this(new InputStreamReader(i), new OutputStreamWriter(o));
- }
-
- public TorControlConnection(Reader i, Writer o) {
- this.output = o;
- if (i instanceof BufferedReader)
- this.input = (BufferedReader) i;
- else
- this.input = new BufferedReader(i);
- this.waiters = new LinkedList<Waiter>();
- }
-
- protected final void writeEscaped(String s) throws IOException {
- StringTokenizer st = new StringTokenizer(s, "\n");
- while (st.hasMoreTokens()) {
- String line = st.nextToken();
- if (line.startsWith("."))
- line = "."+line;
- if (line.endsWith("\r"))
- line += "\n";
- else
- line += "\r\n";
- if (debugOutput != null)
- debugOutput.print(">> "+line);
- output.write(line);
- }
- output.write(".\r\n");
- if (debugOutput != null)
- debugOutput.print(">> .\n");
- }
-
- protected static final String quote(String s) {
- StringBuffer sb = new StringBuffer("\"");
- for (int i = 0; i < s.length(); ++i) {
- char c = s.charAt(i);
- switch (c)
- {
- case '\r':
- case '\n':
- case '\\':
- case '\"':
- sb.append('\\');
- }
- sb.append(c);
- }
- sb.append('\"');
- return sb.toString();
- }
-
- protected final ArrayList<ReplyLine> readReply() throws IOException {
- ArrayList<ReplyLine> reply = new ArrayList<ReplyLine>();
- char c;
- do {
- String line = input.readLine();
- if (line == null) {
- // if line is null, the end of the stream has been reached, i.e.
- // the connection to Tor has been closed!
- if (reply.isEmpty()) {
- // nothing received so far, can exit cleanly
- return reply;
- }
- // received half of a reply before the connection broke down
- throw new TorControlSyntaxError("Connection to Tor " +
- " broke down while receiving reply!");
- }
- if (debugOutput != null)
- debugOutput.println("<< "+line);
- if (line.length() < 4)
- throw new TorControlSyntaxError("Line (\""+line+"\") too short");
- String status = line.substring(0,3);
- c = line.charAt(3);
- String msg = line.substring(4);
- String rest = null;
- if (c == '+') {
- StringBuffer data = new StringBuffer();
- while (true) {
- line = input.readLine();
- if (debugOutput != null)
- debugOutput.print("<< "+line);
- if (line.equals("."))
- break;
- else if (line.startsWith("."))
- line = line.substring(1);
- data.append(line).append('\n');
- }
- rest = data.toString();
- }
- reply.add(new ReplyLine(status, msg, rest));
- } while (c != ' ');
-
- return reply;
- }
-
- protected synchronized List<ReplyLine> sendAndWaitForResponse(String s,
- String rest) throws IOException {
- if(parseThreadException != null) throw parseThreadException;
- checkThread();
- Waiter w = new Waiter();
- if (debugOutput != null)
- debugOutput.print(">> "+s);
- synchronized (waiters) {
- output.write(s);
- if (rest != null)
- writeEscaped(rest);
- output.flush();
- waiters.addLast(w);
- }
- List<ReplyLine> lst;
- try {
- lst = w.getResponse();
- } catch (InterruptedException ex) {
- throw new IOException("Interrupted");
- }
- for (Iterator<ReplyLine> i = lst.iterator(); i.hasNext(); ) {
- ReplyLine c = i.next();
- if (! c.status.startsWith("2"))
- throw new TorControlError("Error reply: "+c.msg);
- }
- return lst;
- }
-
- /** Helper: decode a CMD_EVENT command and dispatch it to our
- * EventHandler (if any). */
- protected void handleEvent(ArrayList<ReplyLine> events) {
- if (handler == null)
- return;
-
- for (Iterator<ReplyLine> i = events.iterator(); i.hasNext(); ) {
- ReplyLine line = i.next();
- int idx = line.msg.indexOf(' ');
- String tp = line.msg.substring(0, idx).toUpperCase();
- String rest = line.msg.substring(idx+1);
- if (tp.equals("CIRC")) {
- List<String> lst = Bytes.splitStr(null, rest);
- handler.circuitStatus(lst.get(1),
- lst.get(0),
- lst.get(1).equals("LAUNCHED")
- || lst.size() < 3 ? ""
- : lst.get(2));
- } else if (tp.equals("STREAM")) {
- List<String> lst = Bytes.splitStr(null, rest);
- handler.streamStatus(lst.get(1),
- lst.get(0),
- lst.get(3));
- // XXXX circID.
- } else if (tp.equals("ORCONN")) {
- List<String> lst = Bytes.splitStr(null, rest);
- handler.orConnStatus(lst.get(1), lst.get(0));
- } else if (tp.equals("BW")) {
- List<String> lst = Bytes.splitStr(null, rest);
- handler.bandwidthUsed(Integer.parseInt(lst.get(0)),
- Integer.parseInt(lst.get(1)));
- } else if (tp.equals("NEWDESC")) {
- List<String> lst = Bytes.splitStr(null, rest);
- handler.newDescriptors(lst);
- } else if (tp.equals("DEBUG") ||
- tp.equals("INFO") ||
- tp.equals("NOTICE") ||
- tp.equals("WARN") ||
- tp.equals("ERR")) {
- handler.message(tp, rest);
- } else {
- handler.unrecognized(tp, rest);
- }
- }
- }
-
-
- /** Sets <b>w</b> as the PrintWriter for debugging output,
- * which writes out all messages passed between Tor and the controller.
- * Outgoing messages are preceded by "\>\>" and incoming messages are preceded
- * by "\<\<"
- */
- public void setDebugging(PrintWriter w) {
- debugOutput = w;
- }
-
- /** Sets <b>s</b> as the PrintStream for debugging output,
- * which writes out all messages passed between Tor and the controller.
- * Outgoing messages are preceded by "\>\>" and incoming messages are preceded
- * by "\<\<"
- */
- public void setDebugging(PrintStream s) {
- debugOutput = new PrintWriter(s, true);
- }
-
- /** Set the EventHandler object that will be notified of any
- * events Tor delivers to this connection. To make Tor send us
- * events, call setEvents(). */
- public void setEventHandler(EventHandler handler) {
- this.handler = handler;
- }
-
- /**
- * Start a thread to react to Tor's responses in the background.
- * This is necessary to handle asynchronous events and synchronous
- * responses that arrive independantly over the same socket.
- */
- public synchronized Thread launchThread(boolean daemon) {
- ControlParseThread th = new ControlParseThread();
- if (daemon)
- th.setDaemon(true);
- th.start();
- this.thread = th;
- return th;
- }
-
- protected class ControlParseThread extends Thread {
-
- @Override
- public void run() {
- try {
- react();
- } catch (IOException ex) {
- parseThreadException = ex;
- }
- }
- }
-
- protected synchronized void checkThread() {
- if (thread == null)
- launchThread(true);
- }
-
- /** helper: implement the main background loop. */
- protected void react() throws IOException {
- while (true) {
- ArrayList<ReplyLine> lst = readReply();
- if (lst.isEmpty()) {
- // connection has been closed remotely! end the loop!
- return;
- }
- if ((lst.get(0)).status.startsWith("6"))
- handleEvent(lst);
- else {
- synchronized (waiters) {
- if (!waiters.isEmpty())
- {
- Waiter w;
- w = waiters.removeFirst();
- w.setResponse(lst);
- }
- }
-
- }
- }
- }
-
- /** Change the value of the configuration option 'key' to 'val'.
- */
- public void setConf(String key, String value) throws IOException {
- List<String> lst = new ArrayList<String>();
- lst.add(key+" "+value);
- setConf(lst);
- }
-
- /** Change the values of the configuration options stored in kvMap. */
- public void setConf(Map<String, String> kvMap) throws IOException {
- List<String> lst = new ArrayList<String>();
- for (Iterator<Map.Entry<String,String>> it = kvMap.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry<String,String> ent = it.next();
- lst.add(ent.getKey()+" "+ent.getValue()+"\n");
- }
- setConf(lst);
- }
-
- /** Changes the values of the configuration options stored in
- * <b>kvList</b>. Each list element in <b>kvList</b> is expected to be
- * String of the format "key value".
- *
- * Tor behaves as though it had just read each of the key-value pairs
- * from its configuration file. Keywords with no corresponding values have
- * their configuration values reset to their defaults. setConf is
- * all-or-nothing: if there is an error in any of the configuration settings,
- * Tor sets none of them.
- *
- * When a configuration option takes multiple values, or when multiple
- * configuration keys form a context-sensitive group (see getConf below), then
- * setting any of the options in a setConf command is taken to reset all of
- * the others. For example, if two ORBindAddress values are configured, and a
- * command arrives containing a single ORBindAddress value, the new
- * command's value replaces the two old values.
- *
- * To remove all settings for a given option entirely (and go back to its
- * default value), include a String in <b>kvList</b> containing the key and no value.
- */
- public void setConf(Collection<String> kvList) throws IOException {
- if (kvList.size() == 0)
- return;
- StringBuffer b = new StringBuffer("SETCONF");
- for (Iterator<String> it = kvList.iterator(); it.hasNext(); ) {
- String kv = it.next();
- int i = kv.indexOf(' ');
- if (i == -1)
- b.append(" ").append(kv);
- b.append(" ").append(kv.substring(0,i)).append("=")
- .append(quote(kv.substring(i+1)));
- }
- b.append("\r\n");
- sendAndWaitForResponse(b.toString(), null);
- }
-
- /** Try to reset the values listed in the collection 'keys' to their
- * default values.
- **/
- public void resetConf(Collection<String> keys) throws IOException {
- if (keys.size() == 0)
- return;
- StringBuffer b = new StringBuffer("RESETCONF");
- for (Iterator<String> it = keys.iterator(); it.hasNext(); ) {
- String key = it.next();
- b.append(" ").append(key);
- }
- b.append("\r\n");
- sendAndWaitForResponse(b.toString(), null);
- }
-
- /** Return the value of the configuration option 'key' */
- public List<ConfigEntry> getConf(String key) throws IOException {
- List<String> lst = new ArrayList<String>();
- lst.add(key);
- return getConf(lst);
- }
-
- /** Requests the values of the configuration variables listed in <b>keys</b>.
- * Results are returned as a list of ConfigEntry objects.
- *
- * If an option appears multiple times in the configuration, all of its
- * key-value pairs are returned in order.
- *
- * Some options are context-sensitive, and depend on other options with
- * different keywords. These cannot be fetched directly. Currently there
- * is only one such option: clients should use the "HiddenServiceOptions"
- * virtual keyword to get all HiddenServiceDir, HiddenServicePort,
- * HiddenServiceNodes, and HiddenServiceExcludeNodes option settings.
- */
- public List<ConfigEntry> getConf(Collection<String> keys) throws IOException {
- StringBuffer sb = new StringBuffer("GETCONF");
- for (Iterator<String> it = keys.iterator(); it.hasNext(); ) {
- String key = it.next();
- sb.append(" ").append(key);
- }
- sb.append("\r\n");
- List<ReplyLine> lst = sendAndWaitForResponse(sb.toString(), null);
- List<ConfigEntry> result = new ArrayList<ConfigEntry>();
- for (Iterator<ReplyLine> it = lst.iterator(); it.hasNext(); ) {
- String kv = (it.next()).msg;
- int idx = kv.indexOf('=');
- if (idx >= 0)
- result.add(new ConfigEntry(kv.substring(0, idx),
- kv.substring(idx+1)));
- else
- result.add(new ConfigEntry(kv));
- }
- return result;
- }
-
- /** Request that the server inform the client about interesting events.
- * Each element of <b>events</b> is one of the following Strings:
- * ["CIRC" | "STREAM" | "ORCONN" | "BW" | "DEBUG" |
- * "INFO" | "NOTICE" | "WARN" | "ERR" | "NEWDESC" | "ADDRMAP"] .
- *
- * Any events not listed in the <b>events</b> are turned off; thus, calling
- * setEvents with an empty <b>events</b> argument turns off all event reporting.
- */
- public void setEvents(List<String> events) throws IOException {
- StringBuffer sb = new StringBuffer("SETEVENTS");
- for (Iterator<String> it = events.iterator(); it.hasNext(); ) {
- sb.append(" ").append(it.next());
- }
- sb.append("\r\n");
- sendAndWaitForResponse(sb.toString(), null);
- }
-
- /** Authenticates the controller to the Tor server.
- *
- * By default, the current Tor implementation trusts all local users, and
- * the controller can authenticate itself by calling authenticate(new byte[0]).
- *
- * If the 'CookieAuthentication' option is true, Tor writes a "magic cookie"
- * file named "control_auth_cookie" into its data directory. To authenticate,
- * the controller must send the contents of this file in <b>auth</b>.
- *
- * If the 'HashedControlPassword' option is set, <b>auth</b> must contain the salted
- * hash of a secret password. The salted hash is computed according to the
- * S2K algorithm in RFC 2440 (OpenPGP), and prefixed with the s2k specifier.
- * This is then encoded in hexadecimal, prefixed by the indicator sequence
- * "16:".
- *
- * You can generate the salt of a password by calling
- * 'tor --hash-password <password>'
- * or by using the provided PasswordDigest class.
- * To authenticate under this scheme, the controller sends Tor the original
- * secret that was used to generate the password.
- */
- public void authenticate(byte[] auth) throws IOException {
- String cmd = "AUTHENTICATE " + Bytes.hex(auth) + "\r\n";
- sendAndWaitForResponse(cmd, null);
- }
-
- /** Instructs the server to write out its configuration options into its torrc.
- */
- public void saveConf() throws IOException {
- sendAndWaitForResponse("SAVECONF\r\n", null);
- }
-
- /** Sends a signal from the controller to the Tor server.
- * <b>signal</b> is one of the following Strings:
- * <ul>
- * <li>"RELOAD" or "HUP" : Reload config items, refetch directory</li>
- * <li>"SHUTDOWN" or "INT" : Controlled shutdown: if server is an OP, exit immediately.
- * If it's an OR, close listeners and exit after 30 seconds</li>
- * <li>"DUMP" or "USR1" : Dump stats: log information about open connections and circuits</li>
- * <li>"DEBUG" or "USR2" : Debug: switch all open logs to loglevel debug</li>
- * <li>"HALT" or "TERM" : Immediate shutdown: clean up and exit now</li>
- * </ul>
- */
- public void signal(String signal) throws IOException {
- String cmd = "SIGNAL " + signal + "\r\n";
- sendAndWaitForResponse(cmd, null);
- }
-
- /** Send a signal to the Tor process to shut it down or halt it.
- * Does not wait for a response. */
- public void shutdownTor(String signal) throws IOException {
- String s = "SIGNAL " + signal + "\r\n";
- Waiter w = new Waiter();
- if (debugOutput != null)
- debugOutput.print(">> "+s);
- synchronized (waiters) {
- output.write(s);
- output.flush();
- }
- }
-
- /** Tells the Tor server that future SOCKS requests for connections to a set of original
- * addresses should be replaced with connections to the specified replacement
- * addresses. Each element of <b>kvLines</b> is a String of the form
- * "old-address new-address". This function returns the new address mapping.
- *
- * The client may decline to provide a body for the original address, and
- * instead send a special null address ("0.0.0.0" for IPv4, "::0" for IPv6, or
- * "." for hostname), signifying that the server should choose the original
- * address itself, and return that address in the reply. The server
- * should ensure that it returns an element of address space that is unlikely
- * to be in actual use. If there is already an address mapped to the
- * destination address, the server may reuse that mapping.
- *
- * If the original address is already mapped to a different address, the old
- * mapping is removed. If the original address and the destination address
- * are the same, the server removes any mapping in place for the original
- * address.
- *
- * Mappings set by the controller last until the Tor process exits:
- * they never expire. If the controller wants the mapping to last only
- * a certain time, then it must explicitly un-map the address when that
- * time has elapsed.
- */
- public Map<String,String> mapAddresses(Collection<String> kvLines) throws IOException {
- StringBuffer sb = new StringBuffer("MAPADDRESS");
- for (Iterator<String> it = kvLines.iterator(); it.hasNext(); ) {
- String kv = it.next();
- int i = kv.indexOf(' ');
- sb.append(" ").append(kv.substring(0,i)).append("=")
- .append(quote(kv.substring(i+1)));
- }
- sb.append("\r\n");
- List<ReplyLine> lst = sendAndWaitForResponse(sb.toString(), null);
- Map<String,String> result = new HashMap<String,String>();
- for (Iterator<ReplyLine> it = lst.iterator(); it.hasNext(); ) {
- String kv = (it.next()).msg;
- int idx = kv.indexOf('=');
- result.put(kv.substring(0, idx),
- kv.substring(idx+1));
- }
- return result;
- }
-
- public Map<String,String> mapAddresses(Map<String,String> addresses) throws IOException {
- List<String> kvList = new ArrayList<String>();
- for (Iterator<Map.Entry<String, String>> it = addresses.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry<String,String> e = it.next();
- kvList.add(e.getKey()+" "+e.getValue());
- }
- return mapAddresses(kvList);
- }
-
- public String mapAddress(String fromAddr, String toAddr) throws IOException {
- List<String> lst = new ArrayList<String>();
- lst.add(fromAddr+" "+toAddr+"\n");
- Map<String,String> m = mapAddresses(lst);
- return m.get(fromAddr);
- }
-
- /** Queries the Tor server for keyed values that are not stored in the torrc
- * configuration file. Returns a map of keys to values.
- *
- * Recognized keys include:
- * <ul>
- * <li>"version" : The version of the server's software, including the name
- * of the software. (example: "Tor 0.0.9.4")</li>
- * <li>"desc/id/<OR identity>" or "desc/name/<OR nickname>" : the latest server
- * descriptor for a given OR, NUL-terminated. If no such OR is known, the
- * corresponding value is an empty string.</li>
- * <li>"network-status" : a space-separated list of all known OR identities.
- * This is in the same format as the router-status line in directories;
- * see tor-spec.txt for details.</li>
- * <li>"addr-mappings/all"</li>
- * <li>"addr-mappings/config"</li>
- * <li>"addr-mappings/cache"</li>
- * <li>"addr-mappings/control" : a space-separated list of address mappings, each
- * in the form of "from-address=to-address". The 'config' key
- * returns those address mappings set in the configuration; the 'cache'
- * key returns the mappings in the client-side DNS cache; the 'control'
- * key returns the mappings set via the control interface; the 'all'
- * target returns the mappings set through any mechanism.</li>
- * <li>"circuit-status" : A series of lines as for a circuit status event. Each line is of the form:
- * "CircuitID CircStatus Path"</li>
- * <li>"stream-status" : A series of lines as for a stream status event. Each is of the form:
- * "StreamID StreamStatus CircID Target"</li>
- * <li>"orconn-status" : A series of lines as for an OR connection status event. Each is of the
- * form: "ServerID ORStatus"</li>
- * </ul>
- */
- public Map<String,String> getInfo(Collection<String> keys) throws IOException {
- StringBuffer sb = new StringBuffer("GETINFO");
- for (Iterator<String> it = keys.iterator(); it.hasNext(); ) {
- sb.append(" ").append(it.next());
- }
- sb.append("\r\n");
- List<ReplyLine> lst = sendAndWaitForResponse(sb.toString(), null);
- Map<String,String> m = new HashMap<String,String>();
- for (Iterator<ReplyLine> it = lst.iterator(); it.hasNext(); ) {
- ReplyLine line = it.next();
- int idx = line.msg.indexOf('=');
- if (idx<0)
- break;
- String k = line.msg.substring(0,idx);
- String v;
- if (line.rest != null) {
- v = line.rest;
- } else {
- v = line.msg.substring(idx+1);
- }
- m.put(k, v);
- }
- return m;
- }
-
-
-
- /** Return the value of the information field 'key' */
- public String getInfo(String key) throws IOException {
- List<String> lst = new ArrayList<String>();
- lst.add(key);
- Map<String,String> m = getInfo(lst);
- return m.get(key);
- }
-
- /** An extendCircuit request takes one of two forms: either the <b>circID</b> is zero, in
- * which case it is a request for the server to build a new circuit according
- * to the specified path, or the <b>circID</b> is nonzero, in which case it is a
- * request for the server to extend an existing circuit with that ID according
- * to the specified <b>path</b>.
- *
- * If successful, returns the Circuit ID of the (maybe newly created) circuit.
- */
- public String extendCircuit(String circID, String path) throws IOException {
- List<ReplyLine> lst = sendAndWaitForResponse(
- "EXTENDCIRCUIT "+circID+" "+path+"\r\n", null);
- return (lst.get(0)).msg;
- }
-
- /** Informs the Tor server that the stream specified by <b>streamID</b> should be
- * associated with the circuit specified by <b>circID</b>.
- *
- * Each stream may be associated with
- * at most one circuit, and multiple streams may share the same circuit.
- * Streams can only be attached to completed circuits (that is, circuits that
- * have sent a circuit status "BUILT" event or are listed as built in a
- * getInfo circuit-status request).
- *
- * If <b>circID</b> is 0, responsibility for attaching the given stream is
- * returned to Tor.
- *
- * By default, Tor automatically attaches streams to
- * circuits itself, unless the configuration variable
- * "__LeaveStreamsUnattached" is set to "1". Attempting to attach streams
- * via TC when "__LeaveStreamsUnattached" is false may cause a race between
- * Tor and the controller, as both attempt to attach streams to circuits.
- */
- public void attachStream(String streamID, String circID)
- throws IOException {
- sendAndWaitForResponse("ATTACHSTREAM "+streamID+" "+circID+"\r\n", null);
- }
-
- /** Tells Tor about the server descriptor in <b>desc</b>.
- *
- * The descriptor, when parsed, must contain a number of well-specified
- * fields, including fields for its nickname and identity.
- */
- // More documentation here on format of desc?
- // No need for return value? control-spec.txt says reply is merely "250 OK" on success...
- public String postDescriptor(String desc) throws IOException {
- List<ReplyLine> lst = sendAndWaitForResponse("+POSTDESCRIPTOR\r\n", desc);
- return (lst.get(0)).msg;
- }
-
- /** Tells Tor to change the exit address of the stream identified by <b>streamID</b>
- * to <b>address</b>. No remapping is performed on the new provided address.
- *
- * To be sure that the modified address will be used, this event must be sent
- * after a new stream event is received, and before attaching this stream to
- * a circuit.
- */
- public void redirectStream(String streamID, String address) throws IOException {
- sendAndWaitForResponse("REDIRECTSTREAM "+streamID+" "+address+"\r\n",
- null);
- }
-
- /** Tells Tor to close the stream identified by <b>streamID</b>.
- * <b>reason</b> should be one of the Tor RELAY_END reasons given in tor-spec.txt, as a decimal:
- * <ul>
- * <li>1 -- REASON_MISC (catch-all for unlisted reasons)</li>
- * <li>2 -- REASON_RESOLVEFAILED (couldn't look up hostname)</li>
- * <li>3 -- REASON_CONNECTREFUSED (remote host refused connection)</li>
- * <li>4 -- REASON_EXITPOLICY (OR refuses to connect to host or port)</li>
- * <li>5 -- REASON_DESTROY (Circuit is being destroyed)</li>
- * <li>6 -- REASON_DONE (Anonymized TCP connection was closed)</li>
- * <li>7 -- REASON_TIMEOUT (Connection timed out, or OR timed out while connecting)</li>
- * <li>8 -- (unallocated)</li>
- * <li>9 -- REASON_HIBERNATING (OR is temporarily hibernating)</li>
- * <li>10 -- REASON_INTERNAL (Internal error at the OR)</li>
- * <li>11 -- REASON_RESOURCELIMIT (OR has no resources to fulfill request)</li>
- * <li>12 -- REASON_CONNRESET (Connection was unexpectedly reset)</li>
- * <li>13 -- REASON_TORPROTOCOL (Sent when closing connection because of Tor protocol violations)</li>
- * </ul>
- *
- * Tor may hold the stream open for a while to flush any data that is pending.
- */
- public void closeStream(String streamID, byte reason)
- throws IOException {
- sendAndWaitForResponse("CLOSESTREAM "+streamID+" "+reason+"\r\n",null);
- }
-
- /** Tells Tor to close the circuit identified by <b>circID</b>.
- * If <b>ifUnused</b> is true, do not close the circuit unless it is unused.
- */
- public void closeCircuit(String circID, boolean ifUnused) throws IOException {
- sendAndWaitForResponse("CLOSECIRCUIT "+circID+
- (ifUnused?" IFUNUSED":"")+"\r\n", null);
- }
-}
-
diff --git a/orbotservice/src/main/java/org/torproject/android/control/TorControlError.java b/orbotservice/src/main/java/org/torproject/android/control/TorControlError.java
deleted file mode 100644
index d07ee514..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/TorControlError.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.io.IOException;
-
-/**
- * An exception raised when Tor tells us about an error.
- */
-public class TorControlError extends IOException {
-
- static final long serialVersionUID = 3;
-
- private final int errorType;
-
- public TorControlError(int type, String s) {
- super(s);
- errorType = type;
- }
-
- public TorControlError(String s) {
- this(-1, s);
- }
-
- public int getErrorType() {
- return errorType;
- }
-
- public String getErrorMsg() {
- try {
- if (errorType == -1)
- return null;
- return TorControlCommands.ERROR_MSGS[errorType];
- } catch (ArrayIndexOutOfBoundsException ex) {
- return "Unrecongized error #"+errorType;
- }
- }
-}
-
diff --git a/orbotservice/src/main/java/org/torproject/android/control/TorControlSyntaxError.java b/orbotservice/src/main/java/org/torproject/android/control/TorControlSyntaxError.java
deleted file mode 100644
index dba4f44b..00000000
--- a/orbotservice/src/main/java/org/torproject/android/control/TorControlSyntaxError.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2005 Nick Mathewson, Roger Dingledine
-// See LICENSE file for copying information
-package org.torproject.android.control;
-
-import java.io.IOException;
-
-/**
- * An exception raised when Tor behaves in an unexpected way.
- */
-public class TorControlSyntaxError extends IOException {
-
- static final long serialVersionUID = 3;
-
- public TorControlSyntaxError(String s) { super(s); }
-}
-
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
index 62f14308..c67afff4 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
@@ -1,7 +1,9 @@
package org.torproject.android.service;
import android.text.TextUtils;
-import org.torproject.android.control.EventHandler;
+
+import net.freehaven.tor.control.EventHandler;
+
import org.torproject.android.service.util.Prefs;
import java.text.NumberFormat;
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index e5a8c216..5e9e9168 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -29,20 +29,19 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.BaseColumns;
-import android.support.annotation.RequiresApi;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.content.LocalBroadcastManager;
+import androidx.annotation.RequiresApi;
+import androidx.core.app.NotificationCompat;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
import com.jaredrummler.android.shell.CommandResult;
-import info.pluggabletransports.dispatch.util.TransportListener;
-import info.pluggabletransports.dispatch.util.TransportManager;
-import org.torproject.android.control.ConfigEntry;
-import org.torproject.android.control.TorControlConnection;
+
+import net.freehaven.tor.control.ConfigEntry;
+import net.freehaven.tor.control.TorControlConnection;
+
import org.torproject.android.service.util.CustomShell;
import org.torproject.android.service.util.CustomTorResourceInstaller;
import org.torproject.android.service.util.DummyActivity;
@@ -52,6 +51,9 @@ import org.torproject.android.service.util.Utils;
import org.torproject.android.service.vpn.OrbotVpnManager;
import org.torproject.android.service.vpn.VpnPrefs;
+import info.pluggabletransports.dispatch.util.TransportListener;
+import info.pluggabletransports.dispatch.util.TransportManager;
+
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/CustomShell.java b/orbotservice/src/main/java/org/torproject/android/service/util/CustomShell.java
index db1a08e2..8007d047 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/util/CustomShell.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/util/CustomShell.java
@@ -1,8 +1,8 @@
package org.torproject.android.service.util;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.WorkerThread;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
import com.jaredrummler.android.shell.CommandResult;
import com.jaredrummler.android.shell.Shell;
import com.jaredrummler.android.shell.ShellExitCode;
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
index 13ff2c49..d394b5c8 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
@@ -6,7 +6,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.VpnService;
-import android.support.v4.content.LocalBroadcastManager;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log;
import org.torproject.android.service.TorService;
import org.torproject.android.service.TorServiceConstants;
1
0

[orbot/master] Merge branch 'rename-to-OrbotService' of https://github.com/eighthave/orbot into eighthave-rename-to-OrbotService
by n8fr8@torproject.org 28 Apr '20
by n8fr8@torproject.org 28 Apr '20
28 Apr '20
commit b3d747e4ed9a7cd36e0dbfe508d37a99fc59e15f
Merge: 200c4045 a655beed
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Tue Dec 17 16:16:33 2019 -0500
Merge branch 'rename-to-OrbotService' of https://github.com/eighthave/orbot into eighthave-rename-to-OrbotService
app-mini/src/debug/AndroidManifest.xml | 2 +-
app-mini/src/main/AndroidManifest.xml | 2 +-
.../torproject/android/mini/MiniMainActivity.java | 54 +++++++++++-----------
.../torproject/android/mini/OnBootReceiver.java | 12 ++---
.../android/mini/vpn/VPNEnableActivity.java | 12 ++---
app/src/main/AndroidManifest.xml | 2 +-
.../org/torproject/android/OnBootReceiver.java | 12 ++---
.../org/torproject/android/OrbotMainActivity.java | 50 ++++++++++----------
.../torproject/android/ui/VPNEnableActivity.java | 12 ++---
.../service/{TorService.java => OrbotService.java} | 10 ++--
.../android/service/StartTorReceiver.java | 6 +--
.../android/service/TorEventHandler.java | 4 +-
.../android/service/vpn/OrbotVpnManager.java | 6 +--
.../android/service/vpn/TorVpnService.java | 4 +-
14 files changed, 94 insertions(+), 94 deletions(-)
1
0
commit 200c404596f8b5e5962b9fdabb80676fe97531e5
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Mon Dec 9 15:46:55 2019 -0500
update version code to 16132000
---
app/build.gradle | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 3c5d265f..0b725341 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -73,7 +73,7 @@ android {
minSdkVersion 16
applicationId 'org.torproject.android'
targetSdkVersion 28
- versionCode 16123000
+ versionCode 16132000
versionName getVersionName()
archivesBaseName = "Orbot-$versionName"
}
@@ -82,8 +82,8 @@ android {
minSdkVersion 16
applicationId 'org.torproject.android.max'
targetSdkVersion 28
- versionCode 16123000
- versionName '16.1.2-RC-2-tor-0.4.1.5-rc'
+ versionCode 16132000
+ versionName getVersionName()
archivesBaseName = "orbotMAX-$versionName"
}
}
1
0

28 Apr '20
commit bb3640a51891e0285a358fddcc2e3b7de1527ae1
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Mon Dec 9 15:44:56 2019 -0500
when you exit, make sure you also stop the VPN
---
app/src/main/java/org/torproject/android/OrbotMainActivity.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
index 64f1ee42..9ca9f28f 100644
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@ -568,6 +568,8 @@ public class OrbotMainActivity extends AppCompatActivity
private void doExit() {
stopTor();
+ TorVpnService.stop(this);
+
// Kill all the wizard activities
setResult(RESULT_CLOSE_ALL);
finish();
1
0
commit 2682b52254570b2dfa7ef8825d21e66b2511c4b1
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Sat Dec 7 06:49:16 2019 -0500
update gradle tools
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 2d5b3312..c14d6885 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.1'
+ classpath 'com.android.tools.build:gradle:3.5.3'
}
}
1
0

28 Apr '20
commit 815bb83dbeaa411ae9e3c96f211de7d270c63a6a
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Tue Feb 4 13:24:29 2020 -0500
set the VPN button properly for mini UI
---
.../java/org/torproject/android/mini/MiniMainActivity.java | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java b/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java
index 5be3d027..7ef51c52 100644
--- a/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java
+++ b/app-mini/src/main/java/org/torproject/android/mini/MiniMainActivity.java
@@ -173,8 +173,6 @@ public class MiniMainActivity extends AppCompatActivity
private void stopTor() {
-// requestTorStatus();
-
Intent intent = new Intent(MiniMainActivity.this, OrbotService.class);
stopService(intent);
@@ -467,7 +465,7 @@ public class MiniMainActivity extends AppCompatActivity
private void refreshVPNApps ()
{
- TorVpnService.start(this);
+ TorVpnService.stop(this);
startActivity(new Intent(MiniMainActivity.this, VPNEnableActivity.class));
}
@@ -714,14 +712,13 @@ public class MiniMainActivity extends AppCompatActivity
sendIntentToService(TorServiceConstants.CMD_SIGNAL_HUP);
}
+
@Override
protected void onResume() {
super.onResume();
-// mBtnBridges.setChecked(Prefs.bridgesEnabled());
- mBtnVPN.setChecked(Prefs.useVpn());
-
-// setCountrySpinner();
+ if (mBtnVPN.isChecked()!=Prefs.useVpn())
+ mBtnVPN.setChecked(Prefs.useVpn());
requestTorStatus();
1
0

[orbot/master] ports can be set to "auto" so allow letters as well
by n8fr8@torproject.org 28 Apr '20
by n8fr8@torproject.org 28 Apr '20
28 Apr '20
commit 361ea26d47810cd3bb43b1184385cbf2d0eeb497
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Tue Jul 9 14:27:25 2019 -0400
ports can be set to "auto" so allow letters as well
---
app/src/main/res/xml/preferences.xml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index ac596cf3..49b90dfa 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -246,7 +246,6 @@
<EditTextPreference
android:defaultValue="9050"
android:dialogTitle="@string/pref_socks_dialog"
- android:inputType="number"
android:key="pref_socks"
android:summary="@string/pref_socks_summary"
android:title="@string/pref_socks_title" />
@@ -254,7 +253,6 @@
<EditTextPreference
android:defaultValue="8118"
android:dialogTitle="@string/pref_http_dialog"
- android:inputType="number"
android:key="pref_http"
android:summary="@string/pref_http_summary"
android:title="@string/pref_http_title" />
@@ -262,7 +260,6 @@
<EditTextPreference
android:defaultValue="auto"
android:dialogTitle="@string/pref_transport_dialog"
- android:inputType="number"
android:key="pref_transport"
android:summary="@string/pref_transport_summary"
android:title="@string/pref_transport_title" />
@@ -270,7 +267,6 @@
<EditTextPreference
android:defaultValue="auto"
android:dialogTitle="@string/pref_dnsport_dialog"
- android:inputType="number"
android:key="pref_dnsport"
android:summary="@string/pref_dnsport_summary"
android:title="@string/pref_dnsport_title" />
1
0

28 Apr '20
commit 9ff0b00cb26b0f4c09e9420ad4d992fa7de26c82
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Tue Jul 9 14:28:11 2019 -0400
fix VPN code to support dynamic DNS port for Tor
---
.../org/torproject/android/service/TorService.java | 55 +++----
.../android/service/TorServiceConstants.java | 3 +
.../android/service/vpn/OrbotVpnManager.java | 180 +++++++++++----------
.../android/service/vpn/TorVpnService.java | 42 +++++
.../torproject/android/service/vpn/VpnUtils.java | 26 ++-
orbotservice/src/main/res/values/pdnsd.xml | 4 +-
6 files changed, 180 insertions(+), 130 deletions(-)
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index be1e18e2..c83c252e 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -811,11 +811,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
reply.setPackage(packageName);
sendBroadcast(reply);
}
- else
- {
- LocalBroadcastManager.getInstance(this).sendBroadcast(reply);
- }
+ LocalBroadcastManager.getInstance(this).sendBroadcast(reply);
}
@@ -1105,21 +1102,22 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
String confDns = conn.getInfo("net/listeners/dns");
st = new StringTokenizer(confDns," ");
-
- confDns = st.nextToken().split(":")[1];
- confDns = confDns.substring(0,confDns.length()-1);
- mPortDns = Integer.parseInt(confDns);
- getSharedPrefs(getApplicationContext()).edit().putInt(VpnPrefs.PREFS_DNS_PORT, mPortDns).apply();
-
+ if (st.hasMoreTokens()) {
+ confDns = st.nextToken().split(":")[1];
+ confDns = confDns.substring(0, confDns.length() - 1);
+ mPortDns = Integer.parseInt(confDns);
+ getSharedPrefs(getApplicationContext()).edit().putInt(VpnPrefs.PREFS_DNS_PORT, mPortDns).apply();
+ }
String confTrans = conn.getInfo("net/listeners/trans");
st = new StringTokenizer(confTrans," ");
+ if (st.hasMoreTokens()) {
+ confTrans = st.nextToken().split(":")[1];
+ confTrans = confTrans.substring(0, confTrans.length() - 1);
+ mPortTrans = Integer.parseInt(confTrans);
+ }
- confTrans = st.nextToken().split(":")[1];
- confTrans = confDns.substring(0,confTrans.length()-1);
- mPortTrans = Integer.parseInt(confTrans);
-
- sendCallbackPorts(mPortSOCKS, mPortHTTP);
+ sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans);
return Integer.parseInt(torProcId);
@@ -1434,13 +1432,15 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
}
- private void sendCallbackPorts (int socksPort, int httpPort)
+ private void sendCallbackPorts (int socksPort, int httpPort, int dnsPort, int transPort)
{
Intent intent = new Intent(LOCAL_ACTION_PORTS);
// You can also include some extra data.
- intent.putExtra("socks",socksPort);
- intent.putExtra("http",httpPort);
+ intent.putExtra(EXTRA_SOCKS_PROXY_PORT,socksPort);
+ intent.putExtra(EXTRA_HTTP_PROXY_PORT,httpPort);
+ intent.putExtra(EXTRA_DNS_PORT,dnsPort);
+ intent.putExtra(EXTRA_TRANS_PORT,transPort);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
@@ -1970,21 +1970,10 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
private void startVPNService ()
{
- if (mPortSOCKS != -1) {
- Intent intentVpn = new Intent(this, TorVpnService.class);
- intentVpn.setAction("start");
- intentVpn.putExtra("torSocks", mPortSOCKS);
- startService(intentVpn);
- }
- else
- {
- mHandler.postDelayed(new Runnable() {
- public void run ()
- {
- startVPNService();
- }
- },5000);
- }
+ Intent intentVpn = new Intent(this, TorVpnService.class);
+ intentVpn.setAction("start");
+ startService(intentVpn);
+
}
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
index 8fd9eeca..b805cd6a 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
@@ -65,6 +65,9 @@ public interface TorServiceConstants {
String EXTRA_HTTP_PROXY_HOST = "org.torproject.android.intent.extra.HTTP_PROXY_HOST";
String EXTRA_HTTP_PROXY_PORT = "org.torproject.android.intent.extra.HTTP_PROXY_PORT";
+ String EXTRA_DNS_PORT = "org.torproject.android.intent.extra.DNS_PORT";
+ String EXTRA_TRANS_PORT = "org.torproject.android.intent.extra.TRANS_PORT";
+
String LOCAL_ACTION_LOG = "log";
String LOCAL_ACTION_BANDWIDTH = "bandwidth";
String LOCAL_EXTRA_LOG = "log";
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
index 7233159f..cf9b8b71 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
@@ -19,8 +19,10 @@ package org.torproject.android.service.vpn;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.app.Service;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.VpnService;
@@ -29,6 +31,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
+import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
@@ -36,12 +39,15 @@ import com.runjva.sourceforge.jsocks.protocol.ProxyServer;
import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
import org.torproject.android.service.R;
+import org.torproject.android.service.TorService;
+import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.service.util.CustomNativeLoader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
@@ -63,30 +69,25 @@ public class OrbotVpnManager implements Handler.Callback {
private ParcelFileDescriptor mInterface;
private int mTorSocks = -1;
+ private int mTorDns = -1;
- public static int sSocksProxyServerPort = -1;
+ public static int sSocksProxyServerPort = -1;
public static String sSocksProxyLocalhost = null;
private ProxyServer mSocksProxyServer;
private final static int VPN_MTU = 1500;
private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
-
- //this is the actual DNS server we talk to over UDP or TCP (now using Tor's DNS port)
- //private final static String DEFAULT_ACTUAL_DNS_HOST = "127.0.0.1";
- //private final static int DEFAULT_ACTUAL_DNS_PORT = TorServiceConstants.TOR_DNS_PORT_DEFAULT;
-
-
- File filePdnsd = null;
+ private File filePdnsd = null;
private final static String PDNSD_BIN = "pdnsd";
- private final static int PDNSD_PORT = 8091;
private boolean isRestart = false;
private VpnService mService;
+ private Builder mLastBuilder;
public OrbotVpnManager (VpnService service) throws IOException, TimeoutException {
mService = service;
@@ -96,6 +97,7 @@ public class OrbotVpnManager implements Handler.Callback {
Tun2Socks.init();
+
}
//public int onStartCommand(Intent intent, int flags, int startId) {
@@ -107,40 +109,45 @@ public class OrbotVpnManager implements Handler.Callback {
if (action.equals("start"))
{
-
// Stop the previous session by interrupting the thread.
- if (mThreadVPN == null || (!mThreadVPN.isAlive()))
- {
- Log.d(TAG,"starting OrbotVPNService service!");
-
- mTorSocks = intent.getIntExtra("torSocks", -1);
-
- if (!mIsLollipop)
- {
- startSocksBypass();
- }
-
- setupTun2Socks(builder);
- }
+ if (mThreadVPN != null && mThreadVPN.isAlive())
+ stopVPN();
+
+ mLastBuilder = builder;
+
+ if (mTorSocks != -1)
+ {
+ if (!mIsLollipop)
+ {
+ startSocksBypass();
+ }
+
+ setupTun2Socks(builder);
+ }
+
+
}
else if (action.equals("stop"))
{
Log.d(TAG,"stop OrbotVPNService service!");
- stopVPN();
- //if (mHandler != null)
- //mHandler.postDelayed(new Runnable () { public void run () { stopSelf(); }}, 1000);
- }
- else if (action.equals("refresh"))
- {
- Log.d(TAG,"refresh OrbotVPNService service!");
-
- if (!mIsLollipop)
- startSocksBypass();
-
- if (!isRestart)
- setupTun2Socks(builder);
+ stopVPN();
}
+ else if (action.equals(TorServiceConstants.LOCAL_ACTION_PORTS))
+ {
+ Log.d(TAG,"starting OrbotVPNService service!");
+
+ mTorSocks = intent.getIntExtra(TorService.EXTRA_SOCKS_PROXY_PORT,-1);
+ mTorDns = intent.getIntExtra(TorService.EXTRA_DNS_PORT,-1);
+
+ if (!mIsLollipop)
+ {
+ startSocksBypass();
+ }
+
+ setupTun2Socks(builder);
+ }
+
}
@@ -204,27 +211,7 @@ public class OrbotVpnManager implements Handler.Callback {
}
-
- /**
- @Override
- public void onCreate() {
- super.onCreate();
-
- // Set the locale to English (or probably any other language that^M
- // uses Hindu-Arabic (aka Latin) numerals).^M
- // We have found that VpnService.Builder does something locale-dependent^M
- // internally that causes errors when the locale uses its own numerals^M
- // (i.e., Farsi and Arabic).^M
- Locale.setDefault(new Locale("en"));
-
- }
-
- @Override
- public void onDestroy() {
- stopVPN();
- }*/
-
private void stopVPN ()
{
if (mIsLollipop)
@@ -248,15 +235,11 @@ public class OrbotVpnManager implements Handler.Callback {
Log.d(TAG,"error stopping tun2socks",e);
}
}
+
+ stopDns();
Tun2Socks.Stop();
-
- try {
- killProcess(filePdnsd);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
+
mThreadVPN = null;
@@ -278,10 +261,11 @@ public class OrbotVpnManager implements Handler.Callback {
{
isRestart = true;
Tun2Socks.Stop();
+
+ stopDns();
+
}
- final int localDns = getSharedPrefs(this.mService.getApplicationContext()).getInt(VpnPrefs.PREFS_DNS_PORT, 0);
-
mThreadVPN = new Thread ()
{
@@ -306,23 +290,20 @@ public class OrbotVpnManager implements Handler.Callback {
final String defaultRoute = "0.0.0.0";
final String localSocks = localhost + ':' + mTorSocks;
-
- final String localDNS = virtualGateway + ':' + PDNSD_PORT;
- final boolean localDnsTransparentProxy = true;
-
- builder.setMtu(VPN_MTU);
+ builder.setMtu(VPN_MTU);
builder.addAddress(virtualGateway,32);
- builder.setSession(vpnName);
+ builder.setSession(vpnName);
+
+ //route all traffic through VPN (we might offer country specific exclude lists in the future)
+ builder.addRoute(defaultRoute,0);
builder.addDnsServer(dummyDNS);
builder.addRoute(dummyDNS,32);
-
- //route all traffic through VPN (we might offer country specific exclude lists in the future)
- builder.addRoute(defaultRoute,0);
-
- //handle ipv6
+
+
+ //handle ipv6
//builder.addAddress("fdfe:dcba:9876::1", 126);
//builder.addRoute("::", 0);
@@ -346,9 +327,11 @@ public class OrbotVpnManager implements Handler.Callback {
isRestart = false;
//start PDNSD daemon pointing to actual DNS
- startDNS(filePdnsd.getCanonicalPath(), "127.0.0.1",localDns);
+ int pdnsdPort = 8091;
+ startDNS(filePdnsd.getCanonicalPath(), localhost,mTorDns, "0.0.0.0", pdnsdPort);
+ final boolean localDnsTransparentProxy = true;
- Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , localDnsTransparentProxy);
+ Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , virtualGateway + ":" + pdnsdPort , localDnsTransparentProxy);
}
@@ -406,13 +389,10 @@ public class OrbotVpnManager implements Handler.Callback {
}
-
- private void startDNS (String pdnsPath, String dns, int port) throws IOException, TimeoutException
+ private void startDNS (String pdnsPath, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws IOException, TimeoutException
{
- File fileConf = makePdnsdConf(mService, dns, port,mService.getFilesDir());
-
- // ArrayList<String> customEnv = new ArrayList<String>();
+ File fileConf = makePdnsdConf(mService, mService.getFilesDir(), torDnsHost, torDnsPort, pdnsdHost, pdnsdPort);
String[] cmdString = {pdnsPath,"-c",fileConf.toString()};
ProcessBuilder pb = new ProcessBuilder(cmdString);
@@ -424,21 +404,46 @@ public class OrbotVpnManager implements Handler.Callback {
if (proc.exitValue() != 0)
{
-
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = br.readLine ()) != null) {
Log.d(TAG,"pdnsd: " + line);
}
-
}
}
+
+ private boolean stopDns ()
+ {
+ File filePid = new File(mService.getFilesDir(),"pdnsd.pid");
+ String pid = null;
+
+ if (filePid.exists())
+ {
+
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(filePid));
+ pid = reader.readLine().trim();
+
+ VpnUtils.killProcess(pid,"-9");
+ filePid.delete();
+ return true;
+
+ } catch (Exception e) {
+ Log.e(TAG,"error killing DNS Process: " + pid,e);
+ }
+ }
+
+ return false;
+
+ }
- public static File makePdnsdConf(Context context, String dns, int port, File fileDir) throws FileNotFoundException, IOException {
- String conf = String.format(context.getString(R.string.pdnsd_conf), dns, port, fileDir.getCanonicalPath());
+ public static File makePdnsdConf(Context context, File fileDir, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws FileNotFoundException, IOException {
+ String conf = String.format(context.getString(R.string.pdnsd_conf), torDnsHost, torDnsPort, fileDir.getCanonicalPath(), pdnsdHost, pdnsdPort);
+
+ Log.d(TAG,"pdsnd conf:" + conf);
File f = new File(fileDir,"pdnsd.conf");
@@ -464,5 +469,6 @@ public class OrbotVpnManager implements Handler.Callback {
return f;
}
+
}
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
index b02fd71a..e70753f6 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
@@ -1,8 +1,15 @@
package org.torproject.android.service.vpn;
import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.net.VpnService;
+import android.support.v4.content.LocalBroadcastManager;
+
+import org.torproject.android.service.TorService;
+import org.torproject.android.service.TorServiceConstants;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
@@ -23,6 +30,10 @@ public class TorVpnService extends VpnService {
} catch (TimeoutException e) {
e.printStackTrace();
}
+
+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
+ lbm.registerReceiver(mLocalBroadcastReceiver,
+ new IntentFilter(TorServiceConstants.LOCAL_ACTION_PORTS));
}
/* (non-Javadoc)
@@ -34,4 +45,35 @@ public class TorVpnService extends VpnService {
return Service.START_STICKY;
}
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
+ lbm.unregisterReceiver(mLocalBroadcastReceiver);
+ }
+
+ /**
+ * The state and log info from {@link TorService} are sent to the UI here in
+ * the form of a local broadcast. Regular broadcasts can be sent by any app,
+ * so local ones are used here so other apps cannot interfere with Orbot's
+ * operation.
+ */
+ private BroadcastReceiver mLocalBroadcastReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action == null)
+ return;
+
+ if (action.equals(TorServiceConstants.LOCAL_ACTION_PORTS)) {
+
+ mVpnManager.handleIntent(new Builder(),intent);
+ }
+ }
+ };
+
+
}
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java
index ce862b04..5a9901ff 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java
@@ -58,6 +58,22 @@ public class VpnUtils {
());
} catch (IOException ioe) {
}
+ killProcess(pidString, signal);
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // ignored
+ }
+
+ if (killAttempts > 4)
+ throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath());
+ }
+ }
+
+ public static void killProcess(String pidString, String signal) throws Exception {
+
+
try {
getRuntime().exec("toolbox kill " + signal + " " + pidString);
} catch (IOException ioe) {
@@ -71,14 +87,8 @@ public class VpnUtils {
} catch (IOException ioe) {
}
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // ignored
- }
- if (killAttempts > 4)
- throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath());
- }
+
+
}
}
diff --git a/orbotservice/src/main/res/values/pdnsd.xml b/orbotservice/src/main/res/values/pdnsd.xml
index 89122ebc..ce4609bc 100644
--- a/orbotservice/src/main/res/values/pdnsd.xml
+++ b/orbotservice/src/main/res/values/pdnsd.xml
@@ -4,8 +4,8 @@
global {
perm_cache=0;
cache_dir="%3$s";
- server_port = 8091;
- server_ip = 192.168.200.1;
+ server_port = %5$d;
+ server_ip = %4$s;
query_method=udp_only;
min_ttl=1m;
max_ttl=1w;
1
0

28 Apr '20
commit 79afbe05fb20e3f4fc1f77a89df9e1f683111d5a
Author: n8fr8 <nathan(a)guardianproject.info>
Date: Tue Jul 9 14:37:27 2019 -0400
bind pdnsd to virtual address within VPN
---
.../main/java/org/torproject/android/service/vpn/OrbotVpnManager.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
index cf9b8b71..40ea51af 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
@@ -328,7 +328,7 @@ public class OrbotVpnManager implements Handler.Callback {
//start PDNSD daemon pointing to actual DNS
int pdnsdPort = 8091;
- startDNS(filePdnsd.getCanonicalPath(), localhost,mTorDns, "0.0.0.0", pdnsdPort);
+ startDNS(filePdnsd.getCanonicalPath(), localhost,mTorDns, virtualGateway, pdnsdPort);
final boolean localDnsTransparentProxy = true;
Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , virtualGateway + ":" + pdnsdPort , localDnsTransparentProxy);
1
0