[tor-commits] [orbot/master] Merge branch 'master' into hidden_services
n8fr8 at torproject.org
n8fr8 at torproject.org
Thu Mar 2 04:10:21 UTC 2017
commit 3ba1d395ead1eddcd2ab7404a4c80bb314a70783
Merge: f6f4d26 ff61d66
Author: Juan Ezquerro LLanes <juan at paynopain.com>
Date: Tue Nov 29 11:09:49 2016 +0100
Merge branch 'master' into hidden_services
# Conflicts:
# app/src/main/java/org/torproject/android/OrbotMainActivity.java
.../org/torproject/android/OrbotMainActivity.java | 1571 +++++++++++---------
app/src/main/res/layout/layout_main.xml | 15 +-
app/src/main/res/layout/layout_orbot_control.xml | 12 +-
.../org/torproject/android/service/TorService.java | 27 +-
4 files changed, 866 insertions(+), 759 deletions(-)
diff --cc app/src/main/java/org/torproject/android/OrbotMainActivity.java
index a4bb32e,7706c0f..020bcb8
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@@ -99,20 -90,20 +93,20 @@@ public class OrbotMainActivity extends
private TextView downloadText = null;
private TextView uploadText = null;
private TextView mTxtOrbotLog = null;
-
+
private Button mBtnBrowser = null;
- private Button mBtnStart = null;
+ private Button mBtnStart = null;
- private SwitchCompat mBtnVPN = null;
+ private SwitchCompat mBtnVPN = null;
private SwitchCompat mBtnBridges = null;
-
+
private Spinner spnCountries = null;
- private DrawerLayout mDrawer;
- private ActionBarDrawerToggle mDrawerToggle;
-
+ private DrawerLayout mDrawer;
+ private ActionBarDrawerToggle mDrawerToggle;
+
/* Some tracking bits */
- private String torStatus = TorServiceConstants.STATUS_OFF; //latest status reported from the tor service
+ private String torStatus = null; //latest status reported from the tor service
private Intent lastStatusIntent; // the last ACTION_STATUS Intent received
private SharedPreferences mPrefs = null;
@@@ -129,62 -120,39 +123,63 @@@
private final static int STATUS_UPDATE = 1;
private static final int MESSAGE_TRAFFIC_COUNT = 2;
- public final static String INTENT_ACTION_REQUEST_HIDDEN_SERVICE = "org.torproject.android.REQUEST_HS_PORT";
- public final static String INTENT_ACTION_REQUEST_START_TOR = "org.torproject.android.START_TOR";
+ public final static String INTENT_ACTION_REQUEST_HIDDEN_SERVICE = "org.torproject.android.REQUEST_HS_PORT";
+ public final static String INTENT_ACTION_REQUEST_START_TOR = "org.torproject.android.START_TOR";
- // for bridge loading from the assets default bridges.txt file
- class Bridge {
- String type;
- String config;
+ // for bridge loading from the assets default bridges.txt file
+ class Bridge
+ {
+ String type;
+ String config;
}
-
+
private ArrayList<Bridge> alBridges = null;
-
-
+
//this is needed for backwards compat back to Android 2.3.*
@SuppressLint("NewApi")
- public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
- if (Build.VERSION.SDK_INT >= 11)
- return super.onCreateView(parent, name, context, attrs);
+ public View onCreateView(View parent, String name, Context context, AttributeSet attrs)
+ {
+ if(Build.VERSION.SDK_INT >= 11)
+ return super.onCreateView(parent, name, context, attrs);
return null;
}
-
- /** Called when the activity is first created. */
+
+ private void migratePreferences() {
+ String hsPortString = mPrefs.getString("pref_hs_ports", "");
+ if (hsPortString.length() > 0) {
+ StringTokenizer st = new StringTokenizer(hsPortString, ",");
+ ContentResolver cr = getContentResolver();
+ while (st.hasMoreTokens()) {
+ int hsPort = Integer.parseInt(st.nextToken().split(" ")[0]);
+ ContentValues fields = new ContentValues();
+ fields.put("name", hsPort);
+ fields.put("port", hsPort);
+ fields.put("onion_port", hsPort);
+ cr.insert(HSContentProvider.CONTENT_URI, fields);
+ }
+
+ Editor pEdit = mPrefs.edit();
+ pEdit.remove("pref_hs_ports");
+ pEdit.commit();
+ }
+ }
+
+ /**
+ * Called when the activity is first created.
+ */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPrefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
+ migratePreferences(); // Migrate old preferences
+
/* Create the widgets before registering for broadcasts to guarantee
* that the widgets exist when the status updates try to update them */
- doLayout();
+ doLayout();
/* receive the internal status broadcasts, which are separate from the public
- * status broadcasts to prevent other apps from sending fake/wrong status
+ * status broadcasts to prevent other apps from sending fake/wrong status
* info to this app */
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.registerReceiver(mLocalBroadcastReceiver,
@@@ -559,264 -555,227 +582,273 @@@
} else
stopVpnService();
}
-
- private void enableHiddenServicePort (int hsPort) throws RemoteException, InterruptedException
- {
-
- Editor pEdit = mPrefs.edit();
-
- String hsPortString = mPrefs.getString("pref_hs_ports", "");
- String onionHostname = mPrefs.getString("pref_hs_hostname","");
-
- if (hsPortString.indexOf(hsPort+"")==-1)
- {
- if (hsPortString.length() > 0 && hsPortString.indexOf(hsPort+"")==-1)
- hsPortString += ',' + hsPort;
- else
- hsPortString = hsPort + "";
-
- pEdit.putString("pref_hs_ports", hsPortString);
- pEdit.putBoolean("pref_hs_enable", true);
-
- pEdit.commit();
- }
- if (onionHostname == null || onionHostname.length() == 0)
- {
- requestTorRereadConfig();
+ private void enableHiddenServicePort(
+ String hsName, final int hsPort, int hsRemotePort,
+ final String backupToPackage, final Uri hsKeyPath
+ ) throws RemoteException, InterruptedException {
- new Thread () {
+ String onionHostname = null;
- public void run ()
- {
- String onionHostname = mPrefs.getString("pref_hs_hostname","");
+ if (hsName == null)
+ hsName = "hs" + hsPort;
- while (onionHostname.length() == 0)
- {
- //we need to stop and start Tor
- try {
- Thread.sleep(3000); //wait three seconds
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- onionHostname = mPrefs.getString("pref_hs_hostname","");
- }
-
- Intent nResult = new Intent();
- nResult.putExtra("hs_host", onionHostname);
- setResult(RESULT_OK, nResult);
- finish();
- }
- }.start();
-
- }
- else
- {
- Intent nResult = new Intent();
- nResult.putExtra("hs_host", onionHostname);
- setResult(RESULT_OK, nResult);
- finish();
- }
-
- }
-
- private synchronized void handleIntents ()
- {
- if (getIntent() == null)
- return;
-
- // Get intent, action and MIME type
- Intent intent = getIntent();
- String action = intent.getAction();
- Log.d(TAG, "handleIntents " + action);
+ if (hsRemotePort == -1)
+ hsRemotePort = hsPort;
- //String type = intent.getType();
-
- if (action == null)
- return;
-
- if (action.equals(INTENT_ACTION_REQUEST_HIDDEN_SERVICE))
- {
- final int hiddenServicePortRequest = getIntent().getIntExtra("hs_port", -1);
-
- DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
-
- public void onClick(DialogInterface dialog, int which) {
- switch (which){
- case DialogInterface.BUTTON_POSITIVE:
-
- try {
- enableHiddenServicePort (hiddenServicePortRequest);
-
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ ContentValues fields = new ContentValues();
+ fields.put(HSContentProvider.HiddenService.NAME, hsName);
+ fields.put(HSContentProvider.HiddenService.PORT, hsPort);
+ fields.put(HSContentProvider.HiddenService.ONION_PORT, hsRemotePort);
-
- break;
-
- case DialogInterface.BUTTON_NEGATIVE:
- //No button clicked
- finish();
- break;
- }
- }
- };
-
- String requestMsg = getString(R.string.hidden_service_request, hiddenServicePortRequest);
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(requestMsg).setPositiveButton("Allow", dialogClickListener)
- .setNegativeButton("Deny", dialogClickListener).show();
-
- return; //don't null the setIntent() as we need it later
- }
- else if (action.equals(INTENT_ACTION_REQUEST_START_TOR))
- {
- autoStartFromIntent = true;
-
- startTor();
-
- //never allow backgrounds start from this type of intent start
- //app devs who want background starts, can use the service intents
- /**
- if (Prefs.allowBackgroundStarts())
- {
- Intent resultIntent;
- if (lastStatusIntent == null) {
- resultIntent = new Intent(intent);
- } else {
- resultIntent = lastStatusIntent;
- }
- resultIntent.putExtra(TorServiceConstants.EXTRA_STATUS, torStatus);
- setResult(RESULT_OK, resultIntent);
- finish();
- }*/
-
- }
- else if (action.equals(Intent.ACTION_VIEW))
- {
- String urlString = intent.getDataString();
-
- if (urlString != null)
- {
-
- if (urlString.toLowerCase().startsWith("bridge://"))
+ ContentResolver cr = getContentResolver();
- {
- String newBridgeValue = urlString.substring(9); //remove the bridge protocol piece
- newBridgeValue = URLDecoder.decode(newBridgeValue); //decode the value here
+ Cursor row = cr.query(
+ HSContentProvider.CONTENT_URI,
+ HSContentProvider.PROJECTION,
+ HSContentProvider.HiddenService.ONION_PORT + "=" + hsPort,
+ null,
+ null
+ );
- showAlert(getString(R.string.bridges_updated),getString(R.string.restart_orbot_to_use_this_bridge_) + newBridgeValue,false);
-
- setNewBridges(newBridgeValue);
- }
- }
- }
-
- updateStatus(null);
-
- setIntent(null);
-
-
- }
-
- private void setNewBridges (String newBridgeValue)
- {
+ if (row == null || row.getCount() < 1) {
+ cr.insert(HSContentProvider.CONTENT_URI, fields);
+ } else {
+ onionHostname = row.getString(row.getColumnIndex(HSContentProvider.HiddenService.DOMAIN));
+ row.close();
+ }
- Prefs.setBridgesList(newBridgeValue); //set the string to a preference
- Prefs.putBridgesEnabled(true);
-
- setResult(RESULT_OK);
-
- mBtnBridges.setChecked(true);
-
- enableBridges(true);
- }
+ if (onionHostname == null || onionHostname.length() < 1) {
+
+ if (hsKeyPath != null) {
+ BackupUtils hsutils = new BackupUtils(getApplicationContext());
+ hsutils.restoreKeyBackup(hsPort, hsKeyPath);
+ }
+
+ if (torStatus.equals(TorServiceConstants.STATUS_OFF)) {
+ startTor();
+ } else {
+ stopTor();
+ Toast.makeText(
+ this, R.string.start_tor_again_for_finish_the_process, Toast.LENGTH_LONG
+ ).show();
+ }
+
+ new Thread() {
+
+ public void run() {
+ String hostname = null;
+ Intent nResult = new Intent();
+
+ while (hostname == null) {
+ try {
+ Thread.sleep(3000); //wait three seconds
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ Cursor onion = getContentResolver().query(
+ HSContentProvider.CONTENT_URI,
+ HSContentProvider.PROJECTION,
+ HSContentProvider.HiddenService.ONION_PORT + "=" + hsPort,
+ null,
+ null
+ );
+
+ if (onion != null && onion.getCount() > 0) {
+ onion.moveToNext();
+ hostname = onion.getString(onion.getColumnIndex(HSContentProvider.HiddenService.DOMAIN));
+
+ if(hostname == null || hostname.length() < 1)
+ continue;
+
+ nResult.putExtra("hs_host", hostname);
+
+ if (backupToPackage != null && backupToPackage.length() > 0) {
+ String servicePath = getFilesDir() + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR + "/hs" + hsPort;
+ File hidden_service_key = new File(servicePath, "private_key");
+ Context context = getApplicationContext();
+
+ Uri contentUri = getUriForFile(
+ context,
+ "org.torproject.android.ui.hiddenservices.storage",
+ hidden_service_key
+ );
+
+ context.grantUriPermission(backupToPackage, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ nResult.setData(contentUri);
+ nResult.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
+
+ onion.close();
+ setResult(RESULT_OK, nResult);
+ finish();
+ }
+ }
+ }
+ }.start();
+
+ } else {
+ Intent nResult = new Intent();
+ nResult.putExtra("hs_host", onionHostname);
+ setResult(RESULT_OK, nResult);
+ finish();
+ }
+ }
+
+ private synchronized void handleIntents() {
+ if (getIntent() == null)
+ return;
+
+ // Get intent, action and MIME type
+ Intent intent = getIntent();
+ String action = intent.getAction();
+ Log.d(TAG, "handleIntents " + action);
+
+ //String type = intent.getType();
+
+ if (action == null)
+ return;
+
+ switch (action) {
+ case INTENT_ACTION_REQUEST_HIDDEN_SERVICE:
+ final int hiddenServicePort = intent.getIntExtra("hs_port", -1);
+ 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 Uri mKeyUri = intent.getData();
+
+ DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ case DialogInterface.BUTTON_POSITIVE:
+ try {
+ enableHiddenServicePort(
+ hiddenServiceName, hiddenServicePort,
+ hiddenServiceRemotePort, backupToPackage, mKeyUri
+ );
+ } catch (RemoteException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ break;
+ }
+ }
+ };
+
+ String requestMsg = getString(R.string.hidden_service_request, hiddenServicePort);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(requestMsg).setPositiveButton("Allow", dialogClickListener)
+ .setNegativeButton("Deny", dialogClickListener).show();
+
+ return; //don't null the setIntent() as we need it later
+
+ case INTENT_ACTION_REQUEST_START_TOR:
+ autoStartFromIntent = true;
+
+ startTor();
+
+ //never allow backgrounds start from this type of intent start
+ //app devs who want background starts, can use the service intents
+ /**
+ if (Prefs.allowBackgroundStarts())
+ {
+ Intent resultIntent;
+ if (lastStatusIntent == null) {
+ resultIntent = new Intent(intent);
+ } else {
+ resultIntent = lastStatusIntent;
+ }
+ resultIntent.putExtra(TorServiceConstants.EXTRA_STATUS, torStatus);
+ setResult(RESULT_OK, resultIntent);
+ finish();
+ }*/
+
+ break;
+ case Intent.ACTION_VIEW:
+ String urlString = intent.getDataString();
+
+ if (urlString != null) {
+
+ if (urlString.toLowerCase().startsWith("bridge://"))
+
+ {
+ String newBridgeValue = urlString.substring(9); //remove the bridge protocol piece
+ newBridgeValue = URLDecoder.decode(newBridgeValue); //decode the value here
+
+ showAlert(getString(R.string.bridges_updated), getString(R.string.restart_orbot_to_use_this_bridge_) + newBridgeValue, false);
+
+ setNewBridges(newBridgeValue);
+ }
+ }
+ break;
+ }
+
+ updateStatus(null);
+
+ setIntent(null);
+
+ }
+
+ private void setNewBridges(String newBridgeValue) {
+
+ Prefs.setBridgesList(newBridgeValue); //set the string to a preference
+ Prefs.putBridgesEnabled(true);
+
+ setResult(RESULT_OK);
+
+ mBtnBridges.setChecked(true);
+
+ enableBridges(true);
+ }
- /*
- * Launch the system activity for Uri viewing with the provided url
- */
- private void openBrowser(final String browserLaunchUrl, boolean forceExternal) {
- boolean isBrowserInstalled = appInstalledOrNot(TorServiceConstants.BROWSER_APP_USERNAME);
-
- if (isBrowserInstalled) {
- startIntent(TorServiceConstants.BROWSER_APP_USERNAME, Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
- } else if (mBtnVPN.isChecked() || forceExternal) {
- //use the system browser since VPN is on
- startIntent(null, Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
- } else if (Prefs.useTransparentProxying()) {
- startIntent(null, Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
- } else {
- AlertDialog aDialog = new AlertDialog.Builder(OrbotMainActivity.this)
- .setTitle(R.string.install_apps_)
- .setMessage(R.string.it_doesn_t_seem_like_you_have_orweb_installed_want_help_with_that_or_should_we_just_open_the_browser_)
- .setPositiveButton(R.string.install_orweb, new Dialog.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- //prompt to install Orweb
- //Intent intent = new Intent(OrbotMainActivity.this,PromoAppsActivity.class);
- //startActivity(intent);
-
- startActivity(PromoAppsActivity.getInstallIntent(TorServiceConstants.BROWSER_APP_USERNAME, OrbotMainActivity.this));
+ /*
+ * Launch the system activity for Uri viewing with the provided url
+ */
+ private void openBrowser(final String browserLaunchUrl,boolean forceExternal)
+ {
+ boolean isBrowserInstalled = appInstalledOrNot(TorServiceConstants.BROWSER_APP_USERNAME);
+ if (isBrowserInstalled)
+ {
+ startIntent(TorServiceConstants.BROWSER_APP_USERNAME,Intent.ACTION_VIEW,Uri.parse(browserLaunchUrl));
+ }
+ else if (mBtnVPN.isChecked()||forceExternal)
+ {
+ //use the system browser since VPN is on
+ startIntent(null,Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
+ }
+ else if (Prefs.useTransparentProxying())
+ {
+ startIntent(null,Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
+ }
+ else
+ {
+ AlertDialog aDialog = new AlertDialog.Builder(OrbotMainActivity.this)
+ .setTitle(R.string.install_apps_)
+ .setMessage(R.string.it_doesn_t_seem_like_you_have_orweb_installed_want_help_with_that_or_should_we_just_open_the_browser_)
+ .setPositiveButton(R.string.install_orweb, new Dialog.OnClickListener ()
+ {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ //prompt to install Orweb
+ //Intent intent = new Intent(OrbotMainActivity.this,PromoAppsActivity.class);
+ //startActivity(intent);
+
+ startActivity(PromoAppsActivity.getInstallIntent(TorServiceConstants.BROWSER_APP_USERNAME,OrbotMainActivity.this));
- }
- })
+ }
+
+ })
.setNeutralButton(R.string.apps_mode, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@@@ -1173,11 -1190,16 +1263,12 @@@
getString(R.string.connect_first_time), true);
}
- if (autoStartFromIntent) {
+ if (autoStartFromIntent)
+ {
autoStartFromIntent = false;
-- Intent resultIntent = lastStatusIntent;
- resultIntent.putExtra(TorServiceConstants.EXTRA_STATUS, torStatus);
- setResult(RESULT_OK, resultIntent);
-
- if (resultIntent == null)
- resultIntent = new Intent(TorServiceConstants.ACTION_START);
-
++ Intent resultIntent = lastStatusIntent;
+ resultIntent.putExtra(TorServiceConstants.EXTRA_STATUS, torStatus);
+ setResult(RESULT_OK, resultIntent);
finish();
Log.d(TAG, "autoStartFromIntent finish");
}
More information about the tor-commits
mailing list