[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [orbot/master] Fix bug where Orbot couldn't host multiple onion services of the same version (v2 or v3) off the same local port



commit 8db5c3a0b4ebaf0bc5f1cf67fb8f2cea590f53fe
Author: bim <dsnake@xxxxxxxxxxxxxx>
Date:   Sat Apr 24 20:55:52 2021 -0400

    Fix bug where Orbot couldn't host multiple onion services of the same version (v2 or v3) off the same local port
---
 .../ui/hiddenservices/database/HSDatabase.java     | 11 ++--
 .../ui/v3onionservice/OnionServiceDatabase.java    |  8 ++-
 .../torproject/android/service/OrbotService.java   | 61 +++++++++++++++++-----
 3 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/database/HSDatabase.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/database/HSDatabase.java
index 18bc7aa0..d9a398bd 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/database/HSDatabase.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/database/HSDatabase.java
@@ -9,7 +9,7 @@ public class HSDatabase extends SQLiteOpenHelper {
 
     public static final String HS_DATA_TABLE_NAME = "hs_data";
     public static final String HS_CLIENT_COOKIE_TABLE_NAME = "hs_client_cookie";
-    private static final int DATABASE_VERSION = 2;
+    private static final int DATABASE_VERSION = 4;
     private static final String DATABASE_NAME = "hidden_services";
     private static final String HS_DATA_TABLE_CREATE =
             "CREATE TABLE " + HS_DATA_TABLE_NAME + " (" +
@@ -21,7 +21,8 @@ public class HSDatabase extends SQLiteOpenHelper {
                     "auth_cookie_value TEXT, " +
                     "created_by_user INTEGER DEFAULT 0, " +
                     "enabled INTEGER DEFAULT 1, " +
-                    "port INTEGER);";
+                    "port INTEGER, " +
+                    "filepath TEXT);";
 
     private static final String HS_CLIENT_COOKIE_TABLE_CREATE =
             "CREATE TABLE " + HS_CLIENT_COOKIE_TABLE_NAME + " (" +
@@ -42,6 +43,8 @@ public class HSDatabase extends SQLiteOpenHelper {
 
     @Override
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        if (newVersion > oldVersion) {
+            db.execSQL("ALTER TABLE " + HS_DATA_TABLE_NAME + " ADD COLUMN filepath TEXT");
+        }
     }
-}
-
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/torproject/android/ui/v3onionservice/OnionServiceDatabase.java b/app/src/main/java/org/torproject/android/ui/v3onionservice/OnionServiceDatabase.java
index 558babac..d2c62a9d 100644
--- a/app/src/main/java/org/torproject/android/ui/v3onionservice/OnionServiceDatabase.java
+++ b/app/src/main/java/org/torproject/android/ui/v3onionservice/OnionServiceDatabase.java
@@ -8,7 +8,7 @@ public class OnionServiceDatabase extends SQLiteOpenHelper {
 
     static final String DATABASE_NAME = "onion_service",
             ONION_SERVICE_TABLE_NAME = "onion_services";
-    private static final int DATABASE_VERSION = 1;
+    private static final int DATABASE_VERSION = 2;
 
     private static final String ONION_SERVICES_CREATE_SQL =
             "CREATE TABLE " + ONION_SERVICE_TABLE_NAME + " (" +
@@ -18,7 +18,8 @@ public class OnionServiceDatabase extends SQLiteOpenHelper {
                     "onion_port INTEGER, " +
                     "created_by_user INTEGER DEFAULT 0, " +
                     "enabled INTEGER DEFAULT 1, " +
-                    "port INTEGER);";
+                    "port INTEGER, " +
+                    "filepath TEXT);";
 
     OnionServiceDatabase(Context context) {
         super(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -31,6 +32,9 @@ public class OnionServiceDatabase extends SQLiteOpenHelper {
 
     @Override
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        if (newVersion > oldVersion) {
+            db.execSQL("ALTER TABLE " + ONION_SERVICE_TABLE_NAME + " ADD COLUMN filepath text");
+        }
     }
 
 
diff --git a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java
index 5d5eb3fd..6808f088 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java
@@ -72,6 +72,7 @@ import java.util.HashMap;
 import java.util.Objects;
 import java.util.Random;
 import java.util.StringTokenizer;
+import java.util.UUID;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeoutException;
@@ -98,7 +99,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             OnionService.AUTH_COOKIE,
             OnionService.AUTH_COOKIE_VALUE,
             OnionService.ONION_PORT,
-            OnionService.ENABLED};
+            OnionService.ENABLED,
+            OnionService.PATH};
     private static final String[] V3_ONION_SERVICE_PROJECTION = new String[]{
             OnionService._ID,
             OnionService.NAME,
@@ -106,6 +108,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             OnionService.PORT,
             OnionService.ONION_PORT,
             OnionService.ENABLED,
+            OnionService.PATH
     };
     private static final String[] LEGACY_COOKIE_PROJECTION = new String[]{
             ClientCookie._ID,
@@ -841,16 +844,16 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             try {
                 while (onionServices.moveToNext()) {
                     String domain = onionServices.getString(onionServices.getColumnIndex(OnionService.DOMAIN));
-                    int localPort = onionServices.getInt(onionServices.getColumnIndex(OnionService.PORT));
-
                     if (domain == null || TextUtils.isEmpty(domain)) {
-                        String v3OnionDirPath = new File(mV3OnionBasePath.getAbsolutePath(), "v3" + localPort).getCanonicalPath();
+                        String path = onionServices.getString(onionServices.getColumnIndex(OnionService.PATH));
+                        String v3OnionDirPath = new File(mV3OnionBasePath.getAbsolutePath(), path).getCanonicalPath();
                         File hostname = new File(v3OnionDirPath, "hostname");
                         if (hostname.exists()) {
+                            int id = onionServices.getInt(onionServices.getColumnIndex(OnionService._ID));
                             domain = Utils.readString(new FileInputStream(hostname)).trim();
                             ContentValues fields = new ContentValues();
                             fields.put(OnionService.DOMAIN, domain);
-                            contentResolver.update(V3_ONION_SERVICES_CONTENT_URI, fields, "port=" + localPort, null);
+                            contentResolver.update(V3_ONION_SERVICES_CONTENT_URI, fields, OnionService._ID + "=" + id, null);
                         }
                     }
 
@@ -870,19 +873,18 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             try {
                 while (hidden_services.moveToNext()) {
                     String HSDomain = hidden_services.getString(hidden_services.getColumnIndex(OnionService.DOMAIN));
-                    Integer HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.PORT));
-                    Integer HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.AUTH_COOKIE));
+                    int HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.AUTH_COOKIE));
                     String HSAuthCookieValue = hidden_services.getString(hidden_services.getColumnIndex(OnionService.AUTH_COOKIE_VALUE));
-
                     // Update only new domains or restored from backup with auth cookie
                     if ((HSDomain == null || HSDomain.length() < 1) || (HSAuthCookie == 1 && (HSAuthCookieValue == null || HSAuthCookieValue.length() < 1))) {
-                        String hsDirPath = new File(mHSBasePath.getAbsolutePath(), "hs" + HSLocalPort).getCanonicalPath();
+                        String hsDirPath = new File(mHSBasePath.getAbsolutePath(), hidden_services.getString(hidden_services.getColumnIndex(OnionService.PATH))).getCanonicalPath();
                         File file = new File(hsDirPath, "hostname");
 
                         if (file.exists()) {
                             ContentValues fields = new ContentValues();
 
                             try {
+                                int id = hidden_services.getInt(hidden_services.getColumnIndex(OnionService._ID));
                                 String onionHostname = Utils.readString(new FileInputStream(file)).trim();
                                 if (HSAuthCookie == 1) {
                                     String[] aux = onionHostname.split(" ");
@@ -890,14 +892,13 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
                                     fields.put(OnionService.AUTH_COOKIE_VALUE, aux[1]);
                                 }
                                 fields.put(OnionService.DOMAIN, onionHostname);
-                                mCR.update(V2_HS_CONTENT_URI, fields, "port=" + HSLocalPort, null);
+                                mCR.update(V2_HS_CONTENT_URI, fields, OnionService._ID + "=" + id, null);
                             } catch (FileNotFoundException e) {
                                 logException("unable to read onion hostname file", e);
                                 showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
                             }
                         } else {
                             showToolbarNotification(getString(R.string.unable_to_read_hidden_service_name), HS_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
-
                         }
                     }
                 }
@@ -1390,9 +1391,22 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             Cursor onionServices = contentResolver.query(V3_ONION_SERVICES_CONTENT_URI, V3_ONION_SERVICE_PROJECTION, OnionService.ENABLED + "=1", null, null);
             if (onionServices != null) {
                 while (onionServices.moveToNext()) {
+                    int id = onionServices.getInt(onionServices.getColumnIndex(OnionService._ID));
                     int localPort = onionServices.getInt(onionServices.getColumnIndex(OnionService.PORT));
                     int onionPort = onionServices.getInt(onionServices.getColumnIndex(OnionService.ONION_PORT));
-                    String v3DirPath = new File(mV3OnionBasePath.getAbsolutePath(), "v3" + localPort).getCanonicalPath();
+                    String path = onionServices.getString(onionServices.getColumnIndex(OnionService.PATH));
+                    String domain = onionServices.getString(onionServices.getColumnIndex(OnionService.DOMAIN));
+                    if (path == null) {
+                        path = "v3";
+                        if (domain == null)
+                            path += UUID.randomUUID().toString();
+                        else
+                            path += localPort;
+                        ContentValues cv = new ContentValues();
+                        cv.put(OnionService.PATH, path);
+                        contentResolver.update(V3_ONION_SERVICES_CONTENT_URI, cv, OnionService._ID + "=" + id, null);
+                    }
+                    String v3DirPath = new File(mV3OnionBasePath.getAbsolutePath(), path).getCanonicalPath();
                     torrc.append("HiddenServiceDir ").append(v3DirPath).append("\n");
                     torrc.append("HiddenServiceVersion 3").append("\n");
                     torrc.append("HiddenServicePort ").append(onionPort).append(" 127.0.0.1:").append(localPort).append("\n");
@@ -1404,18 +1418,36 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
         }
     }
 
-    // todo needs modifications to set hidden service version back after doing v3 stuff...
     private void addV2HiddenServicesToTorrc(StringBuffer torrc, ContentResolver contentResolver) {
         try {
             Cursor hidden_services = contentResolver.query(V2_HS_CONTENT_URI, LEGACY_V2_ONION_SERVICE_PROJECTION, OnionService.ENABLED + "=1", null, null);
             if (hidden_services != null) {
                 try {
                     while (hidden_services.moveToNext()) {
+                        int id = hidden_services.getInt(hidden_services.getColumnIndex(OnionService._ID));
                         String HSname = hidden_services.getString(hidden_services.getColumnIndex(OnionService.NAME));
+                        String domain = hidden_services.getString(hidden_services.getColumnIndex(OnionService.DOMAIN));
                         int HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.PORT));
                         int HSOnionPort = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.ONION_PORT));
                         int HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(OnionService.AUTH_COOKIE));
-                        String hsDirPath = new File(mHSBasePath.getAbsolutePath(), "hs" + HSLocalPort).getCanonicalPath();
+                        String path = hidden_services.getString(hidden_services.getColumnIndex(OnionService.PATH));
+
+                        // logic to fix bug where you can't have 2+ hidden services on same local port without breaking services that were configured before the bug fix
+                        if (path == null) {
+                            String newPath = "hs";
+                            if (domain == null)
+                                newPath +=UUID.randomUUID().toString();
+                            else
+                                newPath += HSLocalPort;
+
+                            ContentValues cv = new ContentValues();
+                            cv.put(OnionService.PATH, newPath);
+                            contentResolver.update(V2_HS_CONTENT_URI, cv, OnionService._ID + "=" + id, null);
+                            path = newPath;
+                        }
+
+                        String hsDirPath = new File(mHSBasePath.getAbsolutePath(), path).getCanonicalPath();
+
 
                         debug("Adding hidden service on port: " + HSLocalPort);
 
@@ -1656,6 +1688,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
         public static final String AUTH_COOKIE = "auth_cookie";
         public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
         public static final String ENABLED = "enabled";
+        public static final String PATH = "filepath";
     }
 
     public static final class V3ClientAuth implements BaseColumns {



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits