commit 4d0fe27ea3ed88a1c8cf6cefb28acce075ae17da Author: arrase arrase@gmail.com Date: Sun Dec 4 21:10:44 2016 +0100
adds optional HiddenServiceAuthorizeClient option for each hidden service --- .../org/torproject/android/OrbotMainActivity.java | 8 ++++++-- .../ui/hiddenservices/HiddenServicesActivity.java | 8 ++++++++ .../ui/hiddenservices/backup/BackupUtils.java | 15 ++++++++++++++ .../ui/hiddenservices/database/HSDatabase.java | 2 ++ .../ui/hiddenservices/dialogs/HSActionsDialog.java | 24 ++++++++++++++++++++++ .../ui/hiddenservices/dialogs/HSDataDialog.java | 9 ++++++-- .../providers/HSContentProvider.java | 4 ++++ app/src/main/res/layout/layout_hs_actions.xml | 6 ++++++ app/src/main/res/layout/layout_hs_data_dialog.xml | 8 ++++++++ app/src/main/res/values/strings.xml | 4 ++++ .../org/torproject/android/service/TorService.java | 23 ++++++++++++++++++--- 11 files changed, 104 insertions(+), 7 deletions(-)
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java index 2cb44c4..07d0199 100644 --- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java +++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java @@ -593,7 +593,8 @@ public class OrbotMainActivity extends AppCompatActivity
private void enableHiddenServicePort( String hsName, final int hsPort, int hsRemotePort, - final String backupToPackage, final Uri hsKeyPath + final String backupToPackage, final Uri hsKeyPath, + final Boolean authCookie ) throws RemoteException, InterruptedException {
String onionHostname = null; @@ -608,6 +609,7 @@ public class OrbotMainActivity extends AppCompatActivity fields.put(HSContentProvider.HiddenService.NAME, hsName); fields.put(HSContentProvider.HiddenService.PORT, hsPort); fields.put(HSContentProvider.HiddenService.ONION_PORT, hsRemotePort); + fields.put(HSContentProvider.HiddenService.AUTH_COOKIE, authCookie);
ContentResolver cr = getContentResolver();
@@ -725,6 +727,7 @@ public class OrbotMainActivity extends AppCompatActivity final int hiddenServiceRemotePort = intent.getIntExtra("hs_onion_port", -1); final String hiddenServiceName = intent.getStringExtra("hs_name"); final String backupToPackage = intent.getStringExtra("hs_backup_to_package"); + final Boolean authCookie = intent.getBooleanExtra("hs_auth_cookie", false); final Uri mKeyUri = intent.getData();
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { @@ -735,7 +738,8 @@ public class OrbotMainActivity extends AppCompatActivity try { enableHiddenServicePort( hiddenServiceName, hiddenServicePort, - hiddenServiceRemotePort, backupToPackage, mKeyUri + hiddenServiceRemotePort, backupToPackage, + mKeyUri, authCookie ); } catch (RemoteException e) { // TODO Auto-generated catch block 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 99af182..c4f55a1 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 @@ -90,6 +90,14 @@ public class HiddenServicesActivity extends AppCompatActivity { "onion", item.getString(item.getColumnIndex(HSContentProvider.HiddenService.DOMAIN)) );
+ arguments.putInt( + "auth_cookie", item.getInt(item.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE)) + ); + + arguments.putString( + "auth_cookie_value", item.getString(item.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE_VALUE)) + ); + HSActionsDialog dialog = new HSActionsDialog(); dialog.setArguments(arguments); dialog.show(getSupportFragmentManager(), "HSActionsDialog"); diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java index 5a1185c..1dccbf8 100644 --- a/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java +++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java @@ -89,6 +89,16 @@ public class BackupUtils { );
config.put( + HSContentProvider.HiddenService.AUTH_COOKIE, + portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE)) + ); + + config.put( + HSContentProvider.HiddenService.AUTH_COOKIE_VALUE, + portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE_VALUE)) + ); + + config.put( HSContentProvider.HiddenService.CREATED_BY_USER, portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.CREATED_BY_USER)) ); @@ -174,6 +184,11 @@ public class BackupUtils { );
fields.put( + HSContentProvider.HiddenService.AUTH_COOKIE, + savedValues.getInt(HSContentProvider.HiddenService.AUTH_COOKIE) + ); + + fields.put( HSContentProvider.HiddenService.CREATED_BY_USER, savedValues.getInt(HSContentProvider.HiddenService.CREATED_BY_USER) ); 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 8f1123f..93ccd25 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 @@ -16,6 +16,8 @@ public class HSDatabase extends SQLiteOpenHelper { "name TEXT, " + "domain TEXT, " + "onion_port INTEGER, " + + "auth_cookie INTEGER DEFAULT 0, " + + "auth_cookie_value TEXT, " + "created_by_user INTEGER DEFAULT 0, " + "port INTEGER);";
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 e1b9dd3..06b650b 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 @@ -83,6 +83,30 @@ public class HSActionsDialog extends DialogFragment { } });
+ Button showAuth = (Button) dialog_view.findViewById(R.id.bt_hs_show_auth); + showAuth.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + String auth_cookie_value = arguments.getString("auth_cookie_value"); + if (arguments.getInt("auth_cookie") == 1) { + if (auth_cookie_value == null || auth_cookie_value.length() < 1) { + Toast.makeText( + v.getContext(), R.string.please_restart_Orbot_to_enable_the_changes, Toast.LENGTH_LONG + ).show(); + } else { + new AlertDialog.Builder(getActivity()) + .setMessage(auth_cookie_value) + .show(); + } + } else { + Toast.makeText( + v.getContext(), R.string.auth_cookie_was_not_configured, Toast.LENGTH_LONG + ).show(); + } + + actionDialog.dismiss(); + } + }); + Button delete = (Button) dialog_view.findViewById(R.id.btn_hs_delete); delete.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { 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 329d6a8..56c6d3f 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 @@ -10,6 +10,7 @@ import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; import android.view.View; import android.widget.Button; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast;
@@ -42,8 +43,10 @@ public class HSDataDialog extends DialogFragment { ((EditText) dialog_view.findViewById(R.id.hsOnionPort)).getText().toString() );
+ Boolean authCookie = ((CheckBox) dialog_view.findViewById(R.id.hsAuth)).isChecked(); + if (checkInput(serverName, localPort, onionPort)) { - saveData(serverName, localPort, onionPort); + saveData(serverName, localPort, onionPort, authCookie); serviceDataDialog.dismiss(); } } @@ -80,11 +83,13 @@ public class HSDataDialog extends DialogFragment { return is_ok; }
- private void saveData(String name, Integer local, Integer remote) { + private void saveData(String name, Integer local, Integer remote, Boolean authCookie) { + ContentValues fields = new ContentValues(); fields.put(HSContentProvider.HiddenService.NAME, name); fields.put(HSContentProvider.HiddenService.PORT, local); fields.put(HSContentProvider.HiddenService.ONION_PORT, remote); + fields.put(HSContentProvider.HiddenService.AUTH_COOKIE, authCookie); fields.put(HSContentProvider.HiddenService.CREATED_BY_USER, 1);
ContentResolver cr = getContext().getContentResolver(); 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 fe6dbf1..a0e85dd 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 @@ -22,6 +22,8 @@ public class HSContentProvider extends ContentProvider { HiddenService.PORT, HiddenService.DOMAIN, HiddenService.ONION_PORT, + HiddenService.AUTH_COOKIE, + HiddenService.AUTH_COOKIE_VALUE, HiddenService.CREATED_BY_USER }; private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers"; @@ -130,6 +132,8 @@ public class HSContentProvider extends ContentProvider { public static final String PORT = "port"; public static final String ONION_PORT = "onion_port"; public static final String DOMAIN = "domain"; + public static final String AUTH_COOKIE = "auth_cookie"; + public static final String AUTH_COOKIE_VALUE = "auth_cookie_value"; public static final String CREATED_BY_USER = "created_by_user";
private HiddenService() { diff --git a/app/src/main/res/layout/layout_hs_actions.xml b/app/src/main/res/layout/layout_hs_actions.xml index 64bda7d..0e5a668 100644 --- a/app/src/main/res/layout/layout_hs_actions.xml +++ b/app/src/main/res/layout/layout_hs_actions.xml @@ -10,6 +10,12 @@ android:id="@+id/btn_hs_clipboard" />
<Button + android:text="@string/show_auth_cookie" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/bt_hs_show_auth" /> + + <Button android:text="@string/backup_service" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/app/src/main/res/layout/layout_hs_data_dialog.xml b/app/src/main/res/layout/layout_hs_data_dialog.xml index d791b1b..524d69a 100644 --- a/app/src/main/res/layout/layout_hs_data_dialog.xml +++ b/app/src/main/res/layout/layout_hs_data_dialog.xml @@ -53,6 +53,14 @@ android:id="@+id/hsOnionPort" android:inputType="number" />
+ <CheckBox + android:text="@string/auth_cookie" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/hsAuth" + android:paddingTop="5dp" + android:paddingBottom="10dp"/> + <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c8af6bb..b8192b8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -347,6 +347,7 @@ <string name="done">Done!</string> <string name="invalid_port">Invalid Port</string> <string name="copy_address_to_clipboard">Copy address to clipboard</string> + <string name="show_auth_cookie">Show auth cookie</string> <string name="backup_service">Backup Service</string> <string name="delete_service">Delete Service</string> <string name="backup_saved_at_external_storage">Backup saved at external storage</string> @@ -362,4 +363,7 @@ <string name="confirm_service_deletion">Confirm service deletion</string> <string name="click_again_for_backup">Click again for backup</string> <string name="service_type">Service type</string> + <string name="auth_cookie">Auth cookie</string> + <string name="auth_cookie_was_not_configured">Auth cookie was not configured</string> + <string name="please_restart_Orbot_to_enable_the_changes">Please restart Orbot to enable the changes</string> </resources> 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 b7eab99..ff37d8c 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java +++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java @@ -139,6 +139,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon public static final String PORT = "port"; public static final String ONION_PORT = "onion_port"; public static final String DOMAIN = "domain"; + public static final String AUTH_COOKIE = "auth_cookie"; + public static final String AUTH_COOKIE_VALUE = "auth_cookie_value"; public static final String CREATED_BY_USER = "created_by_user";
private HiddenService() { @@ -147,8 +149,11 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
private String[] mProjection = new String[]{ HiddenService._ID, + HiddenService.NAME, HiddenService.DOMAIN, HiddenService.PORT, + HiddenService.AUTH_COOKIE, + HiddenService.AUTH_COOKIE_VALUE, HiddenService.ONION_PORT};
public void debug(String msg) @@ -777,9 +782,11 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon while (hidden_services.moveToNext()) { String HSDomain = hidden_services.getString(hidden_services.getColumnIndex(HiddenService.DOMAIN)); Integer HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.PORT)); + Integer HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.AUTH_COOKIE)); + String HSAuthCookieValue = hidden_services.getString(hidden_services.getColumnIndex(HiddenService.AUTH_COOKIE_VALUE));
- // Update only new domains - if(HSDomain == null || HSDomain.length() < 1) { + // 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(); File file = new File(hsDirPath, "hostname");
@@ -789,7 +796,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try { String onionHostname = Utils.readString(new FileInputStream(file)).trim(); - fields.put("domain", onionHostname); + if(HSAuthCookie == 1) { + String[] aux = onionHostname.split(" "); + onionHostname = aux[0]; + fields.put(HiddenService.AUTH_COOKIE_VALUE, aux[1]); + } + fields.put(HiddenService.DOMAIN, onionHostname); mCR.update(CONTENT_URI, fields, "port=" + HSLocalPort , null); } catch (FileNotFoundException e) { logException("unable to read onion hostname file",e); @@ -1784,14 +1796,19 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon if(hidden_services != null) { try { while (hidden_services.moveToNext()) { + String HSname = hidden_services.getString(hidden_services.getColumnIndex(HiddenService.NAME)); Integer HSLocalPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.PORT)); Integer HSOnionPort = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.ONION_PORT)); + Integer HSAuthCookie = hidden_services.getInt(hidden_services.getColumnIndex(HiddenService.AUTH_COOKIE)); String hsDirPath = new File(mHSBasePath.getAbsolutePath(),"hs" + HSLocalPort).getCanonicalPath();
debug("Adding hidden service on port: " + HSLocalPort);
extraLines.append("HiddenServiceDir" + ' ' + hsDirPath).append('\n'); extraLines.append("HiddenServicePort" + ' ' + HSOnionPort + " 127.0.0.1:" + HSLocalPort).append('\n'); + + if(HSAuthCookie == 1) + extraLines.append("HiddenServiceAuthorizeClient stealth " + HSname).append('\n'); } } catch (NumberFormatException e) { Log.e(OrbotConstants.TAG,"error parsing hsport",e);
tor-commits@lists.torproject.org