commit b12efdb779fe26c4b6d4c0d500b55d1fdced9d07 Author: bim dsnake@protonmail.com Date: Tue Sep 15 20:35:00 2020 -0400
ran android studio IDE code formatter --- .../java/org/torproject/android/MainConstants.java | 2 +- .../main/java/org/torproject/android/OrbotApp.java | 2 +- .../org/torproject/android/OrbotMainActivity.java | 307 ++-- .../torproject/android/ui/AppManagerActivity.java | 94 +- .../android/ui/dialog/AboutDialogFragment.java | 33 +- .../ui/onboarding/BridgeWizardActivity.java | 151 +- .../ui/onboarding/CustomBridgesActivity.java | 32 +- .../android/ui/onboarding/CustomSlideBigText.java | 7 +- .../android/ui/onboarding/MoatActivity.java | 24 +- .../torproject/android/service/OrbotConstants.java | 32 +- .../torproject/android/service/OrbotService.java | 1552 +++++++++----------- .../android/service/StartTorReceiver.java | 2 +- .../android/service/TorEventHandler.java | 86 +- .../android/service/TorServiceConstants.java | 1 - .../android/service/util/CustomNativeLoader.java | 10 +- .../android/service/util/CustomShell.java | 25 +- .../service/util/CustomTorResourceInstaller.java | 164 +-- .../android/service/util/DummyActivity.java | 10 +- .../android/service/util/ExternalIPFetcher.java | 26 +- .../android/service/util/NativeLoader.java | 17 +- .../android/service/util/PortForwarder.java | 20 +- .../org/torproject/android/service/util/Prefs.java | 1 - .../android/service/util/TCPSourceApp.java | 135 +- .../android/service/util/TorServiceUtils.java | 8 +- .../org/torproject/android/service/util/Utils.java | 326 ++-- .../android/service/vpn/OrbotVpnManager.java | 532 ++++--- .../android/service/vpn/TorifiedApp.java | 465 +++--- .../torproject/android/service/vpn/Tun2Socks.java | 88 +- .../torproject/android/service/vpn/VpnUtils.java | 29 +- 29 files changed, 1917 insertions(+), 2264 deletions(-)
diff --git a/app/src/main/java/org/torproject/android/MainConstants.java b/app/src/main/java/org/torproject/android/MainConstants.java index 06e99861..d3188308 100644 --- a/app/src/main/java/org/torproject/android/MainConstants.java +++ b/app/src/main/java/org/torproject/android/MainConstants.java @@ -3,7 +3,7 @@ package org.torproject.android; public interface MainConstants {
//EXIT COUNTRY CODES - String[] COUNTRY_CODES = {"DE","AT","SE","CH","IS","CA","US","ES","FR","BG","PL","AU","BR","CZ","DK","FI","GB","HU","NL","JP","RO","RU","SG","SK"}; + String[] COUNTRY_CODES = {"DE", "AT", "SE", "CH", "IS", "CA", "US", "ES", "FR", "BG", "PL", "AU", "BR", "CZ", "DK", "FI", "GB", "HU", "NL", "JP", "RO", "RU", "SG", "SK"};
//path to check Tor against String URL_TOR_CHECK = "https://check.torproject.org"; diff --git a/app/src/main/java/org/torproject/android/OrbotApp.java b/app/src/main/java/org/torproject/android/OrbotApp.java index d037efa9..ca6459d0 100644 --- a/app/src/main/java/org/torproject/android/OrbotApp.java +++ b/app/src/main/java/org/torproject/android/OrbotApp.java @@ -4,10 +4,10 @@ import android.app.Application; import android.content.Context; import android.content.res.Configuration;
+import org.torproject.android.core.Languages; import org.torproject.android.core.LocaleHelper; import org.torproject.android.service.OrbotConstants; import org.torproject.android.service.util.Prefs; -import org.torproject.android.core.Languages;
import java.util.Locale;
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java index 61b6333d..2e7809f1 100644 --- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java +++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java @@ -4,7 +4,6 @@ package org.torproject.android;
import android.app.AlertDialog; - import android.app.Application; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -54,17 +53,17 @@ import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult;
import org.json.JSONArray; +import org.torproject.android.core.Languages; import org.torproject.android.core.LocaleHelper; +import org.torproject.android.core.ui.Rotate3dAnimation; +import org.torproject.android.core.ui.SettingsPreferencesActivity; import org.torproject.android.service.OrbotConstants; import org.torproject.android.service.OrbotService; import org.torproject.android.service.TorServiceConstants; import org.torproject.android.service.util.Prefs; import org.torproject.android.service.util.Utils; import org.torproject.android.service.vpn.VpnPrefs; -import org.torproject.android.core.Languages; -import org.torproject.android.core.ui.SettingsPreferencesActivity; import org.torproject.android.ui.AppManagerActivity; -import org.torproject.android.core.ui.Rotate3dAnimation; import org.torproject.android.ui.dialog.AboutDialogFragment; import org.torproject.android.ui.hiddenservices.ClientCookiesActivity; import org.torproject.android.ui.hiddenservices.HiddenServicesActivity; @@ -98,49 +97,149 @@ import static org.torproject.android.service.vpn.VpnPrefs.PREFS_KEY_TORIFIED;
public class OrbotMainActivity extends AppCompatActivity implements OrbotConstants {
+ 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"; + private final static int REQUEST_VPN = 8888; + private final static int REQUEST_SETTINGS = 0x9874; + private final static int REQUEST_VPN_APPS_SELECT = 8889; + private final static int LOG_DRAWER_GRAVITY = GravityCompat.END; + // message types for mStatusUpdateHandler + private final static int STATUS_UPDATE = 1; + private static final int MESSAGE_TRAFFIC_COUNT = 2; + private static final int MESSAGE_PORTS = 3; + private static final float ROTATE_FROM = 0.0f; + private static final float ROTATE_TO = 360.0f * 4f;// 3.141592654f * 32.0f; + PulsatorLayout mPulsator; + AlertDialog aDialog = null; /* Useful UI bits */ private TextView lblStatus = null; //the main text display widget private TextView lblPorts = null; private ImageView imgStatus = null; //the main touchable image for activating Orbot - private TextView downloadText = null; private TextView uploadText = null; private TextView mTxtOrbotLog = null; - private Button mBtnStart = null; - private SwitchCompat mBtnVPN = null; private SwitchCompat mBtnBridges = null; - private Spinner spnCountries = null; - private DrawerLayout mDrawer; - /* Some tracking bits */ private String torStatus = null; //latest status reported from the tor service private Intent lastStatusIntent; // the last ACTION_STATUS Intent received - private SharedPreferences mPrefs = null; - private boolean autoStartFromIntent = false; + // this is what takes messages or values from the callback threads or other non-mainUI threads +//and passes them back into the main UI thread for display to the user + private Handler mStatusUpdateHandler = new Handler() {
- private final static int REQUEST_VPN = 8888; - private final static int REQUEST_SETTINGS = 0x9874; - private final static int REQUEST_VPN_APPS_SELECT = 8889; + @Override + public void handleMessage(final Message msg) {
- private final static int LOG_DRAWER_GRAVITY = GravityCompat.END;
- // message types for mStatusUpdateHandler - private final static int STATUS_UPDATE = 1; - private static final int MESSAGE_TRAFFIC_COUNT = 2; - private static final int MESSAGE_PORTS = 3; + Bundle data = msg.getData();
+ switch (msg.what) { + case MESSAGE_TRAFFIC_COUNT:
- 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"; + DataCount datacount = new DataCount(data.getLong("upload"), data.getLong("download"));
+ long totalRead = data.getLong("readTotal"); + long totalWrite = data.getLong("writeTotal");
- PulsatorLayout mPulsator; + downloadText.setText(String.format("%s / %s", formatCount(datacount.Download), formatTotal(totalRead))); + uploadText.setText(String.format("%s / %s", formatCount(datacount.Upload), formatTotal(totalWrite))); + + break; + case MESSAGE_PORTS: + + int socksPort = data.getInt("socks"); + int httpPort = data.getInt("http"); + + lblPorts.setText(String.format(Locale.getDefault(), "SOCKS: %d | HTTP: %d", socksPort, httpPort)); + + break; + default: + String newTorStatus = msg.getData().getString("status"); + String log = (String) msg.obj; + + if (torStatus == null && newTorStatus != null) //first time status + { + findViewById(R.id.frameMain).setVisibility(View.VISIBLE); + updateStatus(log, newTorStatus); + + } else + updateStatus(log, newTorStatus); + super.handleMessage(msg); + break; + } + } + }; + /** + * The state and log info from {@link OrbotService} 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; + + switch (action) { + case TorServiceConstants.LOCAL_ACTION_LOG: { + Message msg = mStatusUpdateHandler.obtainMessage(STATUS_UPDATE); + msg.obj = intent.getStringExtra(TorServiceConstants.LOCAL_EXTRA_LOG); + msg.getData().putString("status", intent.getStringExtra(TorServiceConstants.EXTRA_STATUS)); + mStatusUpdateHandler.sendMessage(msg); + + break; + } + case TorServiceConstants.LOCAL_ACTION_BANDWIDTH: { + long upload = intent.getLongExtra("up", 0); + long download = intent.getLongExtra("down", 0); + long written = intent.getLongExtra("written", 0); + long read = intent.getLongExtra("read", 0); + + Message msg = mStatusUpdateHandler.obtainMessage(MESSAGE_TRAFFIC_COUNT); + msg.getData().putLong("download", download); + msg.getData().putLong("upload", upload); + msg.getData().putLong("readTotal", read); + msg.getData().putLong("writeTotal", written); + msg.getData().putString("status", intent.getStringExtra(TorServiceConstants.EXTRA_STATUS)); + + mStatusUpdateHandler.sendMessage(msg); + + break; + } + case TorServiceConstants.ACTION_STATUS: { + lastStatusIntent = intent; + + Message msg = mStatusUpdateHandler.obtainMessage(STATUS_UPDATE); + msg.getData().putString("status", intent.getStringExtra(TorServiceConstants.EXTRA_STATUS)); + + mStatusUpdateHandler.sendMessage(msg); + break; + } + case TorServiceConstants.LOCAL_ACTION_PORTS: { + + Message msg = mStatusUpdateHandler.obtainMessage(MESSAGE_PORTS); + msg.getData().putInt("socks", intent.getIntExtra(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1)); + msg.getData().putInt("http", intent.getIntExtra(OrbotService.EXTRA_HTTP_PROXY_PORT, -1)); + + mStatusUpdateHandler.sendMessage(msg); + + break; + } + case ACTION_STOP_VPN: { + mBtnVPN.setChecked(false); + break; + } + } + } + };
private void migratePreferences() { String hsPortString = mPrefs.getString("pref_hs_ports", ""); @@ -225,73 +324,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan
}
- /** - * The state and log info from {@link OrbotService} 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; - - switch (action) { - case TorServiceConstants.LOCAL_ACTION_LOG: { - Message msg = mStatusUpdateHandler.obtainMessage(STATUS_UPDATE); - msg.obj = intent.getStringExtra(TorServiceConstants.LOCAL_EXTRA_LOG); - msg.getData().putString("status", intent.getStringExtra(TorServiceConstants.EXTRA_STATUS)); - mStatusUpdateHandler.sendMessage(msg); - - break; - } - case TorServiceConstants.LOCAL_ACTION_BANDWIDTH: { - long upload = intent.getLongExtra("up", 0); - long download = intent.getLongExtra("down", 0); - long written = intent.getLongExtra("written", 0); - long read = intent.getLongExtra("read", 0); - - Message msg = mStatusUpdateHandler.obtainMessage(MESSAGE_TRAFFIC_COUNT); - msg.getData().putLong("download", download); - msg.getData().putLong("upload", upload); - msg.getData().putLong("readTotal", read); - msg.getData().putLong("writeTotal", written); - msg.getData().putString("status", intent.getStringExtra(TorServiceConstants.EXTRA_STATUS)); - - mStatusUpdateHandler.sendMessage(msg); - - break; - } - case TorServiceConstants.ACTION_STATUS: { - lastStatusIntent = intent; - - Message msg = mStatusUpdateHandler.obtainMessage(STATUS_UPDATE); - msg.getData().putString("status", intent.getStringExtra(TorServiceConstants.EXTRA_STATUS)); - - mStatusUpdateHandler.sendMessage(msg); - break; - } - case TorServiceConstants.LOCAL_ACTION_PORTS: { - - Message msg = mStatusUpdateHandler.obtainMessage(MESSAGE_PORTS); - msg.getData().putInt("socks", intent.getIntExtra(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1)); - msg.getData().putInt("http", intent.getIntExtra(OrbotService.EXTRA_HTTP_PROXY_PORT, -1)); - - mStatusUpdateHandler.sendMessage(msg); - - break; - } - case ACTION_STOP_VPN: { - mBtnVPN.setChecked(false); - break; - } - } - } - }; - private void doLayout() { setContentView(R.layout.layout_main);
@@ -443,7 +475,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan return true; }
- @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.menu_newnym) { @@ -508,7 +539,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan } }
- @Override public void onBackPressed() { // check to see if the log is open, if so close it @@ -875,7 +905,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan
}
- private void enableBridges(boolean enable) { Prefs.putBridgesEnabled(enable);
@@ -932,8 +961,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan mBtnVPN.setChecked(Prefs.useVpn()); }
- AlertDialog aDialog = null; - //general alert dialog for mostly Tor warning messages //sometimes this can go haywire or crazy with too many error //messages from Tor, and the user cannot stop or exit Orbot @@ -1075,54 +1102,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan sendIntentToService(TorServiceConstants.ACTION_STATUS); }
- - // this is what takes messages or values from the callback threads or other non-mainUI threads -//and passes them back into the main UI thread for display to the user - private Handler mStatusUpdateHandler = new Handler() { - - @Override - public void handleMessage(final Message msg) { - - - Bundle data = msg.getData(); - - switch (msg.what) { - case MESSAGE_TRAFFIC_COUNT: - - DataCount datacount = new DataCount(data.getLong("upload"), data.getLong("download")); - - long totalRead = data.getLong("readTotal"); - long totalWrite = data.getLong("writeTotal"); - - downloadText.setText(String.format("%s / %s", formatCount(datacount.Download), formatTotal(totalRead))); - uploadText.setText(String.format("%s / %s", formatCount(datacount.Upload), formatTotal(totalWrite))); - - break; - case MESSAGE_PORTS: - - int socksPort = data.getInt("socks"); - int httpPort = data.getInt("http"); - - lblPorts.setText(String.format(Locale.getDefault(), "SOCKS: %d | HTTP: %d", socksPort, httpPort)); - - break; - default: - String newTorStatus = msg.getData().getString("status"); - String log = (String) msg.obj; - - if (torStatus == null && newTorStatus != null) //first time status - { - findViewById(R.id.frameMain).setVisibility(View.VISIBLE); - updateStatus(log, newTorStatus); - - } else - updateStatus(log, newTorStatus); - super.handleMessage(msg); - break; - } - } - }; - @Override protected void onDestroy() { super.onDestroy(); @@ -1130,18 +1109,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocalBroadcastReceiver); }
- public static class DataCount { - // data uploaded - long Upload; - // data downloaded - long Download; - - DataCount(long Upload, long Download) { - this.Upload = Upload; - this.Download = Download; - } - } - private String formatCount(long count) { NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); // Converts the supplied argument into a string. @@ -1170,9 +1137,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan + getString(R.string.mb); }
- private static final float ROTATE_FROM = 0.0f; - private static final float ROTATE_TO = 360.0f * 4f;// 3.141592654f * 32.0f; - private void requestNewTorIdentity() { sendIntentToService(TorServiceConstants.CMD_NEWNYM);
@@ -1251,7 +1215,6 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan iv.setOnClickListener(v -> startActivityForResult(new Intent(OrbotMainActivity.this, AppManagerActivity.class), REQUEST_VPN_APPS_SELECT)); }
- private void addFullDeviceVpnView(LinearLayout llBoxShortcuts) { TextView tv = new TextView(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); @@ -1262,20 +1225,30 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) - private void exportTorData () - { + private void exportTorData() { File fileTorData = null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { - fileTorData = new File(getDataDir(),DIRECTORY_TOR_DATA); - } - else { + fileTorData = new File(getDataDir(), DIRECTORY_TOR_DATA); + } else { fileTorData = getDir(DIRECTORY_TOR_DATA, Application.MODE_PRIVATE); }
- File fileZip = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS),"orbotdata" + new Date().getTime() + ".zip"); + File fileZip = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "orbotdata" + new Date().getTime() + ".zip"); Utils.zipFileAtPath(fileTorData.getAbsolutePath(), fileZip.getAbsolutePath()); - fileZip.setReadable(true,false); - Log.d (TAG,"debugdata: " + fileZip.getAbsolutePath()); + fileZip.setReadable(true, false); + Log.d(TAG, "debugdata: " + fileZip.getAbsolutePath()); + + } + + public static class DataCount { + // data uploaded + long Upload; + // data downloaded + long Download;
+ DataCount(long Upload, long Download) { + this.Upload = Upload; + this.Download = Download; + } } } 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 07c36ac7..1871a061 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,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Bundle; -import androidx.appcompat.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -28,6 +27,8 @@ import android.widget.ListAdapter; import android.widget.ProgressBar; import android.widget.TextView;
+import androidx.appcompat.app.AppCompatActivity; + import org.torproject.android.BuildConfig; import org.torproject.android.R; import org.torproject.android.service.OrbotConstants; @@ -45,10 +46,19 @@ import static org.torproject.android.service.vpn.VpnPrefs.PREFS_KEY_TORIFIED;
public class AppManagerActivity extends AppCompatActivity implements OnClickListener, OrbotConstants {
+ static ArrayList<TorifiedApp> mApps = null; + PackageManager pMgr = null; + SharedPreferences mPrefs = null; private GridView listApps; private ListAdapter adapterApps; private ProgressBar progressBar; - PackageManager pMgr = null; + + // returns true if the given app is enabled and not orbot + public static boolean includeAppInUi(ApplicationInfo applicationInfo) { + if (!applicationInfo.enabled) return false; + if (BuildConfig.APPLICATION_ID.equals(applicationInfo.packageName)) return false; + return true; + }
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -62,7 +72,6 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList progressBar = findViewById(R.id.progressBar); }
- @Override protected void onResume() { super.onResume(); @@ -70,7 +79,6 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList reloadApps(); }
- /* * Create the UI Options Menu (non-Javadoc) * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) @@ -83,16 +91,13 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList return true; }
- @Override public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.menu_refresh_apps) - { + if (item.getItemId() == R.id.menu_refresh_apps) { mApps = null; reloadApps(); - } - else if (item.getItemId() == android.R.id.home) { + } else if (item.getItemId() == android.R.id.home) { finish(); return true; } @@ -100,16 +105,18 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList return super.onOptionsItemSelected(item); }
- private void reloadApps () { + private void reloadApps() { new AsyncTask<Void, Void, Void>() { protected void onPreExecute() { // Pre Code progressBar.setVisibility(View.VISIBLE); } + protected Void doInBackground(Void... unused) { loadApps(mPrefs); return null; } + protected void onPostExecute(Void unused) { listApps.setAdapter(adapterApps); progressBar.setVisibility(View.GONE); @@ -119,10 +126,7 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList
}
- SharedPreferences mPrefs = null; - static ArrayList<TorifiedApp> mApps = null; - - private void loadApps (SharedPreferences prefs) { + private void loadApps(SharedPreferences prefs) { if (mApps == null) mApps = getApps(prefs);
@@ -139,7 +143,7 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList
final LayoutInflater inflater = getLayoutInflater();
- adapterApps = new ArrayAdapter<TorifiedApp>(this, R.layout.layout_apps_item, R.id.itemtext,mApps) { + adapterApps = new ArrayAdapter<TorifiedApp>(this, R.layout.layout_apps_item, R.id.itemtext, mApps) {
@Override public View getView(int position, View convertView, ViewGroup parent) { @@ -194,23 +198,16 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList
}
- private static class ListEntry { - private CheckBox box; - private TextView text; - private ImageView icon; - } - public ArrayList<TorifiedApp> getApps(SharedPreferences prefs) {
String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, "");
String[] tordApps;
- StringTokenizer st = new StringTokenizer(tordAppString,"|"); + StringTokenizer st = new StringTokenizer(tordAppString, "|"); tordApps = new String[st.countTokens()]; int tordIdx = 0; - while (st.hasMoreTokens()) - { + while (st.hasMoreTokens()) { tordApps[tordIdx++] = st.nextToken(); } Arrays.sort(tordApps); @@ -225,8 +222,7 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList
TorifiedApp app;
- while (itAppInfo.hasNext()) - { + while (itAppInfo.hasNext()) { aInfo = itAppInfo.next(); if (!includeAppInUi(aInfo)) continue; app = new TorifiedApp(); @@ -235,12 +231,9 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList try { PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS);
- if (pInfo != null && pInfo.requestedPermissions != null) - { - for (String permInfo:pInfo.requestedPermissions) - { - if (permInfo.equals(Manifest.permission.INTERNET)) - { + if (pInfo != null && pInfo.requestedPermissions != null) { + for (String permInfo : pInfo.requestedPermissions) { + if (permInfo.equals(Manifest.permission.INTERNET)) { app.setUsesInternet(true); } } @@ -252,12 +245,9 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList e.printStackTrace(); }
- try - { + try { app.setName(pMgr.getApplicationLabel(aInfo).toString()); - } - catch (Exception e) - { + } catch (Exception e) { // no name continue; //we only show apps with names } @@ -265,8 +255,7 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList
if (!app.usesInternet()) continue; - else - { + else { apps.add(app); }
@@ -280,9 +269,7 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList // check if this application is allowed if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) { app.setTorified(true); - } - else - { + } else { app.setTorified(false); }
@@ -299,13 +286,11 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList StringBuilder tordApps = new StringBuilder(); Intent response = new Intent();
- for (TorifiedApp tApp:mApps) - { - if (tApp.isTorified()) - { + for (TorifiedApp tApp : mApps) { + if (tApp.isTorified()) { tordApps.append(tApp.getUsername()); tordApps.append("|"); - response.putExtra(tApp.getUsername(),true); + response.putExtra(tApp.getUsername(), true); } }
@@ -313,7 +298,7 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList edit.putString(PREFS_KEY_TORIFIED, tordApps.toString()); edit.commit();
- setResult(RESULT_OK,response); + setResult(RESULT_OK, response); }
@@ -322,9 +307,9 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList CheckBox cbox = null;
if (v instanceof CheckBox) - cbox = (CheckBox)v; + cbox = (CheckBox) v; else if (v.getTag() instanceof CheckBox) - cbox = (CheckBox)v.getTag(); + cbox = (CheckBox) v.getTag();
if (cbox != null) { final TorifiedApp app = (TorifiedApp) cbox.getTag(); @@ -337,11 +322,10 @@ public class AppManagerActivity extends AppCompatActivity implements OnClickList } }
- // returns true if the given app is enabled and not orbot - public static boolean includeAppInUi(ApplicationInfo applicationInfo) { - if (!applicationInfo.enabled) return false; - if (BuildConfig.APPLICATION_ID.equals(applicationInfo.packageName)) return false; - return true; + private static class ListEntry { + private CheckBox box; + private TextView text; + private ImageView icon; }
} diff --git a/app/src/main/java/org/torproject/android/ui/dialog/AboutDialogFragment.java b/app/src/main/java/org/torproject/android/ui/dialog/AboutDialogFragment.java index 10ad06b6..d83b556e 100644 --- a/app/src/main/java/org/torproject/android/ui/dialog/AboutDialogFragment.java +++ b/app/src/main/java/org/torproject/android/ui/dialog/AboutDialogFragment.java @@ -21,9 +21,23 @@ import java.io.InputStreamReader; public class AboutDialogFragment extends DialogFragment {
public static final String TAG = AboutDialogFragment.class.getSimpleName(); - - private TextView tvAbout; private static final String BUNDLE_KEY_TV_ABOUT_TEXT = "about_tv_txt"; + private TextView tvAbout; + + @SuppressWarnings("SameParameterValue") + private static String readFromAssets(Context context, String filename) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filename))); + + // do reading, usually loop until end of file reading + StringBuilder sb = new StringBuilder(); + String mLine = reader.readLine(); + while (mLine != null) { + sb.append(mLine).append('\n'); // process line + mLine = reader.readLine(); + } + reader.close(); + return sb.toString(); + }
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { @@ -67,21 +81,6 @@ public class AboutDialogFragment extends DialogFragment { .create(); }
- @SuppressWarnings("SameParameterValue") - private static String readFromAssets(Context context, String filename) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filename))); - - // do reading, usually loop until end of file reading - StringBuilder sb = new StringBuilder(); - String mLine = reader.readLine(); - while (mLine != null) { - sb.append(mLine).append('\n'); // process line - mLine = reader.readLine(); - } - reader.close(); - return sb.toString(); - } - @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); 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 d8f35f86..4ffb7d36 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 @@ -33,19 +33,45 @@ public class BridgeWizardActivity extends AppCompatActivity {
private static final int MOAT_REQUEST_CODE = 666; private static final int CUSTOM_BRIDGES_REQUEST_CODE = 1312; - + private static final String BUNDLE_KEY_TV_STATUS_VISIBILITY = "visibility"; + private static final String BUNDLE_KEY_TV_STATUS_TEXT = "text"; private static TextView mTvStatus; private static HostTester runningHostTest; - private RadioButton mBtDirect; private RadioButton mBtObfs4; private RadioButton mBtMeek; private RadioButton mBtCustom; - private View mBtnConfgiureCustomBridges;
- private static final String BUNDLE_KEY_TV_STATUS_VISIBILITY = "visibility"; - private static final String BUNDLE_KEY_TV_STATUS_TEXT = "text"; + @SuppressWarnings("SameParameterValue") + private static boolean isHostReachable(String serverAddress, int serverTCPport, int timeoutMS) { + boolean connected = false; + + try { + Socket socket = new Socket(); + SocketAddress socketAddress = new InetSocketAddress(serverAddress, serverTCPport); + socket.connect(socketAddress, timeoutMS); + if (socket.isConnected()) { + connected = true; + socket.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return connected; + } + + private static void cancelHostTestIfRunning() { + if (runningHostTest != null) { + runningHostTest.cancel(true); + runningHostTest = null; + } + } + + private static boolean noBridgesSet() { + return !Prefs.bridgesEnabled() || Prefs.getBridgesList().trim().equals(""); + }
@Override protected void onCreate(Bundle savedInstanceState) { @@ -166,34 +192,30 @@ public class BridgeWizardActivity extends AppCompatActivity {
ArrayList alBridges = new ArrayList<String>();
- try - { - BufferedReader in= + try { + BufferedReader in = new BufferedReader(new InputStreamReader(getResources().openRawResource(org.torproject.android.service.R.raw.bridges), "UTF-8")); String str;
- while ((str=in.readLine()) != null) { + while ((str = in.readLine()) != null) {
- StringTokenizer st = new StringTokenizer (str," "); + StringTokenizer st = new StringTokenizer(str, " "); String type = st.nextToken();
if (type.equals("obfs4")) { String[] hostport = st.nextToken().split(":"); - hostTester.execute(hostport[0],hostport[1]); + hostTester.execute(hostport[0], hostport[1]); break; }
}
in.close(); - } - catch (Exception e) - { + } catch (Exception e) { e.printStackTrace(); }
- } else { hostTester = null; mTvStatus.setText(""); @@ -201,6 +223,39 @@ public class BridgeWizardActivity extends AppCompatActivity { if (hostTester != null) runningHostTest = hostTester; }
+ @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + + if (mTvStatus != null) { + savedInstanceState.putInt(BUNDLE_KEY_TV_STATUS_VISIBILITY, mTvStatus.getVisibility()); + + if (!TextUtils.isEmpty(mTvStatus.getText())) + savedInstanceState.putString(BUNDLE_KEY_TV_STATUS_TEXT, mTvStatus.getText().toString()); + } + + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void onDestroy() { + cancelHostTestIfRunning(); + mTvStatus = null; + super.onDestroy(); + } + + private void evaluateBridgeListState() { + Log.d(getClass().getSimpleName(), String.format("bridgesEnabled=%b, bridgesList=%s", Prefs.bridgesEnabled(), Prefs.getBridgesList())); + if (noBridgesSet()) { + mBtDirect.setChecked(true); + } else if (Prefs.getBridgesList().equals("meek")) { + mBtMeek.setChecked(true); + } else if (Prefs.getBridgesList().equals("obfs4")) { + mBtObfs4.setChecked(true); + } else { + mBtCustom.setChecked(true); + } + } + private class HostTester extends AsyncTask<String, Void, Boolean> { @Override protected void onPreExecute() { @@ -231,8 +286,7 @@ public class BridgeWizardActivity extends AppCompatActivity { @Override protected void onPostExecute(Boolean result) { // Post Code - if (mTvStatus != null) - { + if (mTvStatus != null) { runningHostTest = null; if (result) { int stringRes = mBtDirect.isChecked() ? R.string.testing_tor_direct_success : R.string.testing_bridges_success; @@ -243,67 +297,4 @@ public class BridgeWizardActivity extends AppCompatActivity { } } } - - @Override - public void onSaveInstanceState(Bundle savedInstanceState) { - - if (mTvStatus != null) { - savedInstanceState.putInt(BUNDLE_KEY_TV_STATUS_VISIBILITY, mTvStatus.getVisibility()); - - if (!TextUtils.isEmpty(mTvStatus.getText())) - savedInstanceState.putString(BUNDLE_KEY_TV_STATUS_TEXT, mTvStatus.getText().toString()); - } - - super.onSaveInstanceState(savedInstanceState); - } - - @Override - public void onDestroy() { - cancelHostTestIfRunning(); - mTvStatus = null; - super.onDestroy(); - } - - @SuppressWarnings("SameParameterValue") - private static boolean isHostReachable(String serverAddress, int serverTCPport, int timeoutMS) { - boolean connected = false; - - try { - Socket socket = new Socket(); - SocketAddress socketAddress = new InetSocketAddress(serverAddress, serverTCPport); - socket.connect(socketAddress, timeoutMS); - if (socket.isConnected()) { - connected = true; - socket.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - - return connected; - } - - private void evaluateBridgeListState() { - Log.d(getClass().getSimpleName(), String.format("bridgesEnabled=%b, bridgesList=%s", Prefs.bridgesEnabled(), Prefs.getBridgesList())); - if (noBridgesSet()) { - mBtDirect.setChecked(true); - } else if (Prefs.getBridgesList().equals("meek")) { - mBtMeek.setChecked(true); - } else if (Prefs.getBridgesList().equals("obfs4")) { - mBtObfs4.setChecked(true); - } else { - mBtCustom.setChecked(true); - } - } - - private static void cancelHostTestIfRunning() { - if (runningHostTest != null) { - runningHostTest.cancel(true); - runningHostTest = null; - } - } - - private static boolean noBridgesSet() { - return !Prefs.bridgesEnabled() || Prefs.getBridgesList().trim().equals(""); - } } diff --git a/app/src/main/java/org/torproject/android/ui/onboarding/CustomBridgesActivity.java b/app/src/main/java/org/torproject/android/ui/onboarding/CustomBridgesActivity.java index c581fd53..6d8ec842 100644 --- a/app/src/main/java/org/torproject/android/ui/onboarding/CustomBridgesActivity.java +++ b/app/src/main/java/org/torproject/android/ui/onboarding/CustomBridgesActivity.java @@ -46,6 +46,22 @@ public class CustomBridgesActivity extends AppCompatActivity implements View.OnC
private EditText mEtPastedBridges;
+ // configures an EditText we assume to be multiline and nested in a ScrollView to be independently scrollable + @SuppressLint("ClickableViewAccessibility") + private static void configureMultilineEditTextInScrollView(EditText et) { + et.setVerticalScrollBarEnabled(true); + et.setOverScrollMode(View.OVER_SCROLL_ALWAYS); + et.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET); + et.setMovementMethod(ScrollingMovementMethod.getInstance()); + et.setOnTouchListener((v, event) -> { + v.getParent().requestDisallowInterceptTouchEvent(true); + if ((event.getAction() & MotionEvent.ACTION_UP) != 0 && (event.getActionMasked() & MotionEvent.ACTION_UP) != 0) { + v.getParent().requestDisallowInterceptTouchEvent(false); + } + return false; + }); + } + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -218,20 +234,4 @@ public class CustomBridgesActivity extends AppCompatActivity implements View.OnC intent.setAction(TorServiceConstants.CMD_SIGNAL_HUP); startService(intent); } - - // configures an EditText we assume to be multiline and nested in a ScrollView to be independently scrollable - @SuppressLint("ClickableViewAccessibility") - private static void configureMultilineEditTextInScrollView(EditText et) { - et.setVerticalScrollBarEnabled(true); - et.setOverScrollMode(View.OVER_SCROLL_ALWAYS); - et.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET); - et.setMovementMethod(ScrollingMovementMethod.getInstance()); - et.setOnTouchListener((v, event) -> { - v.getParent().requestDisallowInterceptTouchEvent(true); - if ((event.getAction() & MotionEvent.ACTION_UP) != 0 && (event.getActionMasked() & MotionEvent.ACTION_UP) != 0) { - v.getParent().requestDisallowInterceptTouchEvent(false); - } - return false; - }); - } } 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 c5d21efa..0b4ec931 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 @@ -15,16 +15,15 @@ import org.torproject.android.R;
public class CustomSlideBigText extends Fragment {
+ private static final String BUNDLE_KEY_LAYOUT_RES_ID = "layoutResId"; + private static final String BUNDLE_KEY_TITLE = "Title"; + private static final String BUNDLE_KEY_SUBTITLE = "Subtitle"; private int layoutResId; private String mTitle; private String mButtonText; private String mSubTitle; private View.OnClickListener mButtonListener;
- private static final String BUNDLE_KEY_LAYOUT_RES_ID = "layoutResId"; - private static final String BUNDLE_KEY_TITLE = "Title"; - private static final String BUNDLE_KEY_SUBTITLE = "Subtitle"; - public static CustomSlideBigText newInstance(int layoutResId, String title) { return newInstance(layoutResId, title, null); } diff --git a/app/src/main/java/org/torproject/android/ui/onboarding/MoatActivity.java b/app/src/main/java/org/torproject/android/ui/onboarding/MoatActivity.java index 588c6952..8525659c 100644 --- a/app/src/main/java/org/torproject/android/ui/onboarding/MoatActivity.java +++ b/app/src/main/java/org/torproject/android/ui/onboarding/MoatActivity.java @@ -47,14 +47,14 @@ import org.torproject.android.service.util.Prefs; import org.torproject.android.ui.dialog.MoatErrorDialogFragment;
/** - Implements the MOAT protocol: Fetches OBFS4 bridges via Meek Azure. - - The bare minimum of the communication is implemented. E.g. no check, if OBFS4 is possible or which - protocol version the server wants to speak. The first should be always good, as OBFS4 is the most widely - supported bridge type, the latter should be the same as we requested (0.1.0) anyway. - - API description: - https://github.com/NullHypothesis/bridgedb#accessing-the-moat-interface + * Implements the MOAT protocol: Fetches OBFS4 bridges via Meek Azure. + * <p> + * The bare minimum of the communication is implemented. E.g. no check, if OBFS4 is possible or which + * protocol version the server wants to speak. The first should be always good, as OBFS4 is the most widely + * supported bridge type, the latter should be the same as we requested (0.1.0) anyway. + * <p> + * API description: + * https://github.com/NullHypothesis/bridgedb#accessing-the-moat-interface */ public class MoatActivity extends AppCompatActivity implements View.OnClickListener, TextView.OnEditorActionListener {
@@ -81,7 +81,7 @@ public class MoatActivity extends AppCompatActivity implements View.OnClickListe @Override public void onReceive(Context context, Intent intent) { String host = intent.getStringExtra(OrbotService.EXTRA_SOCKS_PROXY_HOST); - int port = intent.getIntExtra(OrbotService.EXTRA_SOCKS_PROXY_PORT,-1); + int port = intent.getIntExtra(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1); String status = intent.getStringExtra(TorServiceConstants.EXTRA_STATUS);
if (TextUtils.isEmpty(host)) { @@ -136,8 +136,7 @@ public class MoatActivity extends AppCompatActivity implements View.OnClickListe mRequestInProgress = false; mEtSolution.setEnabled(true); } - } - else { + } else { mIvCaptcha.setVisibility(View.GONE); mEtSolution.setEnabled(false); mBtRequest.setEnabled(false); @@ -308,8 +307,7 @@ public class MoatActivity extends AppCompatActivity implements View.OnClickListe mSuccess = true; setResult(RESULT_OK); finish(); - } - catch (JSONException e) { + } catch (JSONException e) { Log.d(MoatActivity.class.getSimpleName(), "Error decoding answer: " + response.toString());
displayError(e, response); diff --git a/orbotservice/src/main/java/org/torproject/android/service/OrbotConstants.java b/orbotservice/src/main/java/org/torproject/android/service/OrbotConstants.java index 6d8ff1ea..3960fb6c 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/OrbotConstants.java +++ b/orbotservice/src/main/java/org/torproject/android/service/OrbotConstants.java @@ -5,7 +5,7 @@ package org.torproject.android.service;
public interface OrbotConstants {
- String TAG = "Orbot"; + String TAG = "Orbot";
String PREF_OR = "pref_or"; String PREF_OR_PORT = "pref_or_port"; @@ -13,28 +13,26 @@ public interface OrbotConstants { String PREF_REACHABLE_ADDRESSES = "pref_reachable_addresses"; String PREF_REACHABLE_ADDRESSES_PORTS = "pref_reachable_addresses_ports";
- String PREF_DISABLE_NETWORK = "pref_disable_network"; + String PREF_DISABLE_NETWORK = "pref_disable_network";
- String PREF_TOR_SHARED_PREFS = "org.torproject.android_preferences"; + String PREF_TOR_SHARED_PREFS = "org.torproject.android_preferences";
- String PREF_SOCKS = "pref_socks"; + String PREF_SOCKS = "pref_socks";
- String PREF_HTTP = "pref_http"; + String PREF_HTTP = "pref_http";
- String PREF_ISOLATE_DEST = "pref_isolate_dest"; + String PREF_ISOLATE_DEST = "pref_isolate_dest";
- String PREF_CONNECTION_PADDING = "pref_connection_padding"; - String PREF_REDUCED_CONNECTION_PADDING = "pref_reduced_connection_padding"; - String PREF_CIRCUIT_PADDING = "pref_circuit_padding"; - String PREF_REDUCED_CIRCUIT_PADDING = "pref_reduced_circuit_padding"; + String PREF_CONNECTION_PADDING = "pref_connection_padding"; + String PREF_REDUCED_CONNECTION_PADDING = "pref_reduced_connection_padding"; + String PREF_CIRCUIT_PADDING = "pref_circuit_padding"; + String PREF_REDUCED_CIRCUIT_PADDING = "pref_reduced_circuit_padding";
- String PREF_PREFER_IPV6 = "pref_prefer_ipv6"; - String PREF_DISABLE_IPV4 = "pref_disable_ipv4"; - - - String APP_TOR_KEY = "_app_tor"; - String APP_DATA_KEY = "_app_data"; - String APP_WIFI_KEY = "_app_wifi"; + String PREF_PREFER_IPV6 = "pref_prefer_ipv6"; + String PREF_DISABLE_IPV4 = "pref_disable_ipv4";
+ String APP_TOR_KEY = "_app_tor"; + String APP_DATA_KEY = "_app_data"; + String APP_WIFI_KEY = "_app_wifi"; } 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 5f816815..c2a51326 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java +++ b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java @@ -30,11 +30,12 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.provider.BaseColumns; +import android.text.TextUtils; +import android.util.Log; + 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;
@@ -51,9 +52,6 @@ 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; @@ -80,128 +78,98 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeoutException;
+import info.pluggabletransports.dispatch.util.TransportListener; +import info.pluggabletransports.dispatch.util.TransportManager; + public class OrbotService extends VpnService implements TorServiceConstants, OrbotConstants {
public final static String BINARY_TOR_VERSION = org.torproject.android.binary.TorServiceConstants.BINARY_TOR_VERSION; - private String mCurrentStatus = STATUS_OFF; - private final static int CONTROL_SOCKET_TIMEOUT = 60000; - - private TorControlConnection conn = null; - private int mLastProcessId = -1; - + private static final int NOTIFY_ID = 1; + private static final int ERROR_NOTIFY_ID = 3; + private static final int HS_NOTIFY_ID = 4; + private static final Uri HS_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers/hs"); + private static final Uri COOKIE_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers.cookie/cookie"); + private final static String NOTIFICATION_CHANNEL_ID = "orbot_channel_1"; + private final static String RESET_STRING = "="""; public static int mPortSOCKS = -1; public static int mPortHTTP = -1; public static int mPortDns = TOR_DNS_PORT_DEFAULT; public static int mPortTrans = TOR_TRANSPROXY_PORT_DEFAULT; - - private static final int NOTIFY_ID = 1; - private static final int ERROR_NOTIFY_ID = 3; - private static final int HS_NOTIFY_ID = 4; - + public static File appBinHome; + public static File appCacheHome; + public static File fileTor; + public static File fileObfsclient; + public static File fileTorRc; + boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + TorEventHandler mEventHandler; + OrbotVpnManager mVpnManager; + Handler mHandler; + //we should randomly sort alBridges so we don't have the same bridge order each time + Random bridgeSelectRandom = new Random(System.nanoTime()); + ActionBroadcastReceiver mActionBroadcastReceiver; + private String mCurrentStatus = STATUS_OFF; + private TorControlConnection conn = null; + private int mLastProcessId = -1; private ArrayList<String> configBuffer = null; private ArrayList<String> resetBuffer = null; - private File fileControlPort, filePid; - private boolean mConnectivity = true; - private NotificationManager mNotificationManager = null; private NotificationCompat.Builder mNotifyBuilder; private Notification mNotification; private boolean mNotificationShowing = false; - - boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - private ExecutorService mExecutor = Executors.newFixedThreadPool(3); - - TorEventHandler mEventHandler; - - public static File appBinHome; - public static File appCacheHome; - - public static File fileTor; - public static File fileObfsclient; - public static File fileTorRc; private File mHSBasePath; - private ArrayList<Bridge> alBridges = null; - - private static final Uri HS_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers/hs"); - private static final Uri COOKIE_CONTENT_URI = Uri.parse("content://org.torproject.android.ui.hiddenservices.providers.cookie/cookie"); - - OrbotVpnManager mVpnManager; - - Handler mHandler; - - public static final class HiddenService implements BaseColumns { - public static final String NAME = "name"; - 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"; - public static final String ENABLED = "enabled"; - - private HiddenService() { - } - } - - public static final class ClientCookie implements BaseColumns { - public static final String DOMAIN = "domain"; - public static final String AUTH_COOKIE_VALUE = "auth_cookie_value"; - public static final String ENABLED = "enabled"; - - private ClientCookie() { - } - } - private String[] hsProjection = new String[]{ - HiddenService._ID, - HiddenService.NAME, - HiddenService.DOMAIN, - HiddenService.PORT, - HiddenService.AUTH_COOKIE, - HiddenService.AUTH_COOKIE_VALUE, - HiddenService.ONION_PORT, + HiddenService._ID, + HiddenService.NAME, + HiddenService.DOMAIN, + HiddenService.PORT, + HiddenService.AUTH_COOKIE, + HiddenService.AUTH_COOKIE_VALUE, + HiddenService.ONION_PORT, HiddenService.ENABLED}; - private String[] cookieProjection = new String[]{ ClientCookie._ID, ClientCookie.DOMAIN, ClientCookie.AUTH_COOKIE_VALUE, ClientCookie.ENABLED};
- public void debug(String msg) - { + /** + * @param bridgeList bridges that were manually entered into Orbot settings + * @return Array with each bridge as an element, no whitespace entries see issue #289... + */ + private static String[] parseBridgesFromSettings(String bridgeList) { + // this regex replaces lines that only contain whitespace with an empty String + bridgeList = bridgeList.trim().replaceAll("(?m)^[ \t]*\r?\n", ""); + return bridgeList.split("\n"); + } + + public void debug(String msg) {
- Log.d(OrbotConstants.TAG,msg); + Log.d(OrbotConstants.TAG, msg);
- if (Prefs.useDebugLogging()) - { - sendCallbackLogMessage(msg); + if (Prefs.useDebugLogging()) { + sendCallbackLogMessage(msg);
} }
- public void logException(String msg, Exception e) - { - if (Prefs.useDebugLogging()) - { - Log.e(OrbotConstants.TAG,msg,e); + public void logException(String msg, Exception e) { + if (Prefs.useDebugLogging()) { + Log.e(OrbotConstants.TAG, msg, e); ByteArrayOutputStream baos = new ByteArrayOutputStream(); e.printStackTrace(new PrintStream(baos));
- sendCallbackLogMessage(msg + '\n'+ new String(baos.toByteArray())); + sendCallbackLogMessage(msg + '\n' + new String(baos.toByteArray()));
- } - else + } else sendCallbackLogMessage(msg);
}
- private boolean findExistingTorDaemon() { try { mLastProcessId = initControlConnection(3, true); @@ -209,7 +177,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb if (mLastProcessId != -1 && conn != null) { sendCallbackLogMessage(getString(R.string.found_existing_tor_process)); sendCallbackStatus(STATUS_ON); - showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor); + showToolbarNotification(getString(R.string.status_activated), NOTIFY_ID, R.drawable.ic_stat_tor);
return true; } @@ -225,12 +193,11 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb public void onLowMemory() { super.onLowMemory();
- logNotice( "Low Memory Warning!"); + logNotice("Low Memory Warning!");
}
- private void clearNotifications () - { + private void clearNotifications() { if (mNotificationManager != null) mNotificationManager.cancelAll();
@@ -240,11 +207,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb mNotificationShowing = false; }
- private final static String NOTIFICATION_CHANNEL_ID = "orbot_channel_1"; - @RequiresApi(api = Build.VERSION_CODES.O) - private void createNotificationChannel () - { + private void createNotificationChannel() { NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // The id of the channel. @@ -265,31 +229,27 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb }
@SuppressLint("NewApi") - protected void showToolbarNotification (String notifyMsg, int notifyType, int icon) - { + protected void showToolbarNotification(String notifyMsg, int notifyType, int icon) {
- //Reusable code. - PackageManager pm = getPackageManager(); - Intent intent = pm.getLaunchIntentForPackage(getPackageName()); - PendingIntent pendIntent = PendingIntent.getActivity(OrbotService.this, 0, intent, 0); + //Reusable code. + PackageManager pm = getPackageManager(); + Intent intent = pm.getLaunchIntentForPackage(getPackageName()); + PendingIntent pendIntent = PendingIntent.getActivity(OrbotService.this, 0, intent, 0);
- if (mNotifyBuilder == null) - { + if (mNotifyBuilder == null) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- if (mNotifyBuilder == null) - { + if (mNotifyBuilder == null) { mNotifyBuilder = new NotificationCompat.Builder(this) - .setContentTitle(getString(R.string.app_name)) - .setSmallIcon(R.drawable.ic_stat_tor); + .setContentTitle(getString(R.string.app_name)) + .setSmallIcon(R.drawable.ic_stat_tor);
mNotifyBuilder.setContentIntent(pendIntent);
}
- mNotifyBuilder.setCategory(Notification.CATEGORY_SERVICE);
mNotifyBuilder.setChannelId(NOTIFICATION_CHANNEL_ID); @@ -308,147 +268,58 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb mNotifyBuilder.setContentText(notifyMsg); mNotifyBuilder.setSmallIcon(icon);
- if (notifyType != NOTIFY_ID) - { + if (notifyType != NOTIFY_ID) { mNotifyBuilder.setTicker(notifyMsg); - } - else - { + } else { mNotifyBuilder.setTicker(null); }
- if (!Prefs.persistNotifications()) - mNotifyBuilder.setPriority(Notification.PRIORITY_LOW); + if (!Prefs.persistNotifications()) + mNotifyBuilder.setPriority(Notification.PRIORITY_LOW);
- mNotification = mNotifyBuilder.build(); + mNotification = mNotifyBuilder.build();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForeground(NOTIFY_ID, mNotification); - } - else if (Prefs.persistNotifications() && (!mNotificationShowing)) - { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForeground(NOTIFY_ID, mNotification); + } else if (Prefs.persistNotifications() && (!mNotificationShowing)) { startForeground(NOTIFY_ID, mNotification); logNotice("Set background service to FOREGROUND"); - } - else - { + } else { mNotificationManager.notify(NOTIFY_ID, mNotification); }
mNotificationShowing = true; - } - + }
/* (non-Javadoc) * @see android.app.Service#onStart(android.content.Intent, int) */ public int onStartCommand(Intent intent, int flags, int startId) {
- showToolbarNotification("",NOTIFY_ID,R.drawable.ic_stat_tor); + showToolbarNotification("", NOTIFY_ID, R.drawable.ic_stat_tor);
if (intent != null) - exec (new IncomingIntentRouter(intent)); + exec(new IncomingIntentRouter(intent)); else Log.d(OrbotConstants.TAG, "Got null onStartCommand() intent");
return Service.START_STICKY; }
- private class IncomingIntentRouter implements Runnable - { - Intent mIntent; - - public IncomingIntentRouter (Intent intent) - { - mIntent = intent; - } - - public void run() { - - String action = mIntent.getAction(); - - if (!TextUtils.isEmpty(action)) { - if (action.equals(ACTION_START) || action.equals(ACTION_START_ON_BOOT)) { - startTor(); - replyWithStatus(mIntent); - - if (Prefs.useVpn()) - { - if (mVpnManager != null - && (!mVpnManager.isStarted())) { - //start VPN here - Intent vpnIntent = VpnService.prepare(OrbotService.this); - if (vpnIntent == null) //then we can run the VPN - { - mVpnManager.handleIntent(new Builder(), mIntent); - - } - } - - if (mPortSOCKS != -1 && mPortHTTP != -1) - sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans); - } - - } - else if (action.equals(ACTION_START_VPN)) { - if (mVpnManager != null && (!mVpnManager.isStarted())) { - //start VPN here - Intent vpnIntent = VpnService.prepare(OrbotService.this); - if (vpnIntent == null) //then we can run the VPN - { - mVpnManager.handleIntent(new Builder(), mIntent); - - - } - } - - if (mPortSOCKS != -1 && mPortHTTP != -1) - sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans); - - - } - else if (action.equals(ACTION_STOP_VPN)) { - if (mVpnManager != null) - mVpnManager.handleIntent(new Builder(),mIntent); - } - else if (action.equals(ACTION_STATUS)) { - replyWithStatus(mIntent); - } - else if (action.equals(CMD_SIGNAL_HUP)) { - requestTorRereadConfig(); - } else if (action.equals(CMD_NEWNYM)) { - newIdentity(); - } - else if (action.equals(CMD_ACTIVE)) { - sendSignalActive(); - } - else if (action.equals(CMD_SET_EXIT)) { - - setExitNode(mIntent.getStringExtra("exit")); - - } else { - Log.w(OrbotConstants.TAG, "unhandled OrbotService Intent: " + action); - } - } - } - } - @Override - public void onTaskRemoved(Intent rootIntent){ - Log.d(OrbotConstants.TAG,"task removed"); - Intent intent = new Intent( this, DummyActivity.class ); - intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ); - startActivity( intent ); + public void onTaskRemoved(Intent rootIntent) { + Log.d(OrbotConstants.TAG, "task removed"); + Intent intent = new Intent(this, DummyActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); }
@Override public void onDestroy() { try { - // unregisterReceiver(mNetworkStateReceiver); + // unregisterReceiver(mNetworkStateReceiver); unregisterReceiver(mActionBroadcastReceiver); - } - catch (IllegalArgumentException iae) - { + } catch (IllegalArgumentException iae) { //not registered yet }
@@ -461,7 +332,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb new Thread(this::stopTorAsync).start(); }
- private void stopTorAsync () { + private void stopTorAsync() { Log.i("OrbotService", "stopTor"); try { sendCallbackStatus(STATUS_STOPPING); @@ -473,9 +344,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb stopForeground(true);
sendCallbackLogMessage(getString(R.string.status_disabled)); - } - catch (Exception e) - { + } catch (Exception e) { logNotice("An error occured stopping Tor: " + e.getMessage()); sendCallbackLogMessage(getString(R.string.something_bad_happened)); } @@ -485,7 +354,6 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
- private void killAllDaemons() throws Exception {
if (conn != null) { @@ -515,18 +383,16 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb e.printStackTrace(); } /** - // if that fails, try again using native utils - try { - killProcess(fileTor, "-1"); // this is -HUP - } catch (Exception e) { - e.printStackTrace(); - }**/ + // if that fails, try again using native utils + try { + killProcess(fileTor, "-1"); // this is -HUP + } catch (Exception e) { + e.printStackTrace(); + }**/ }
- protected void logNotice (String msg) - { - if (msg != null && msg.trim().length() > 0) - { + protected void logNotice(String msg) { + if (msg != null && msg.trim().length() > 0) { if (Prefs.useDebugLogging()) Log.d(OrbotConstants.TAG, msg);
@@ -538,8 +404,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb public void onCreate() { super.onCreate();
- try - { + try { mHandler = new Handler();
appBinHome = getFilesDir();//getDir(TorServiceConstants.DIRECTORY_TOR_BINARY, Application.MODE_PRIVATE); @@ -547,9 +412,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb appBinHome.mkdirs();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - appCacheHome = new File(getDataDir(),DIRECTORY_TOR_DATA); - } - else { + appCacheHome = new File(getDataDir(), DIRECTORY_TOR_DATA); + } else { appCacheHome = getDir(DIRECTORY_TOR_DATA, Application.MODE_PRIVATE); }
@@ -558,9 +422,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
debug("listing files in DataDirectory: " + appCacheHome.getAbsolutePath()); - Iterator<File> files = FileUtils.iterateFiles(appCacheHome,null,true); - while (files.hasNext()) - { + Iterator<File> files = FileUtils.iterateFiles(appCacheHome, null, true); + while (files.hasNext()) { File fileNext = files.next(); debug(fileNext.getAbsolutePath() + " length=" + fileNext.length() @@ -584,13 +447,12 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
mEventHandler = new TorEventHandler(this);
- if (mNotificationManager == null) - { + if (mNotificationManager == null) { 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); @@ -606,13 +468,10 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb pluggableTransportInstall();
new Thread(() -> { - try - { + try { findExistingTorDaemon(); - } - catch (Exception e) - { - Log.e(OrbotConstants.TAG,"error onBind",e); + } catch (Exception e) { + Log.e(OrbotConstants.TAG, "error onBind", e); logNotice("error finding exiting process: " + e.toString()); }
@@ -625,23 +484,20 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb } catch (TimeoutException e) { e.printStackTrace(); } - } - catch (Exception e) - { + } catch (Exception e) { //what error here - Log.e(OrbotConstants.TAG, "Error installing Orbot binaries",e); + Log.e(OrbotConstants.TAG, "Error installing Orbot binaries", e); logNotice("There was an error installing Orbot binaries"); }
Log.i("OrbotService", "onCreate end"); }
- protected String getCurrentStatus () - { + protected String getCurrentStatus() { return mCurrentStatus; }
- private boolean pluggableTransportInstall () { + private boolean pluggableTransportInstall() {
fileObfsclient = new TransportManager() { @Override @@ -666,7 +522,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb private boolean torUpgradeAndConfig() throws IOException, TimeoutException {
SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); - String version = prefs.getString(PREF_BINARY_TOR_VERSION_INSTALLED,null); + String version = prefs.getString(PREF_BINARY_TOR_VERSION_INSTALLED, null);
logNotice("checking binary version: " + version);
@@ -678,7 +534,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb if (fileTor != null && fileTor.canExecute()) { prefs.edit().putString(PREF_BINARY_TOR_VERSION_INSTALLED, BINARY_TOR_VERSION).apply();
- fileTorRc = new File(appBinHome,"torrc");//installer.getTorrcFile(); + fileTorRc = new File(appBinHome, "torrc");//installer.getTorrcFile(); if (!fileTorRc.exists()) return false;
@@ -688,8 +544,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb return false; }
- private File updateTorrcCustomFile () throws IOException, TimeoutException - { + private File updateTorrcCustomFile() throws IOException, TimeoutException { SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext());
StringBuffer extraLines = new StringBuffer(); @@ -702,35 +557,32 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb extraLines.append("RunAsDaemon 1").append('\n'); extraLines.append("AvoidDiskWrites 1").append('\n');
- String socksPortPref = prefs.getString(OrbotConstants.PREF_SOCKS, (TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT)); + String socksPortPref = prefs.getString(OrbotConstants.PREF_SOCKS, (TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT));
- if (socksPortPref.indexOf(':')!=-1) - socksPortPref = socksPortPref.split(":")[1]; + if (socksPortPref.indexOf(':') != -1) + socksPortPref = socksPortPref.split(":")[1];
socksPortPref = checkPortOrAuto(socksPortPref);
String httpPortPref = prefs.getString(OrbotConstants.PREF_HTTP, (TorServiceConstants.HTTP_PROXY_PORT_DEFAULT));
- if (httpPortPref.indexOf(':')!=-1) + if (httpPortPref.indexOf(':') != -1) httpPortPref = httpPortPref.split(":")[1];
httpPortPref = checkPortOrAuto(httpPortPref);
String isolate = ""; - if(prefs.getBoolean(OrbotConstants.PREF_ISOLATE_DEST, false)) - { + if (prefs.getBoolean(OrbotConstants.PREF_ISOLATE_DEST, false)) { isolate += " IsolateDestAddr "; }
String ipv6Pref = "";
- if(prefs.getBoolean(OrbotConstants.PREF_PREFER_IPV6, true)) - { + if (prefs.getBoolean(OrbotConstants.PREF_PREFER_IPV6, true)) { ipv6Pref += " IPv6Traffic PreferIPv6 "; }
- if(prefs.getBoolean(OrbotConstants.PREF_DISABLE_IPV4, false)) - { + if (prefs.getBoolean(OrbotConstants.PREF_DISABLE_IPV4, false)) { ipv6Pref += " IPv6Traffic NoIPv4Traffic "; }
@@ -738,52 +590,48 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb extraLines.append("SafeSocks 0").append('\n'); extraLines.append("TestSocks 0").append('\n');
- if (Prefs.openProxyOnAllInterfaces()) - extraLines.append("SocksListenAddress 0.0.0.0").append('\n'); + if (Prefs.openProxyOnAllInterfaces()) + extraLines.append("SocksListenAddress 0.0.0.0").append('\n');
extraLines.append("HTTPTunnelPort ").append(httpPortPref).append('\n');
- if(prefs.getBoolean(OrbotConstants.PREF_CONNECTION_PADDING, false)) - { + if (prefs.getBoolean(OrbotConstants.PREF_CONNECTION_PADDING, false)) { extraLines.append("ConnectionPadding 1").append('\n'); }
- if(prefs.getBoolean(OrbotConstants.PREF_REDUCED_CONNECTION_PADDING, true)) - { + if (prefs.getBoolean(OrbotConstants.PREF_REDUCED_CONNECTION_PADDING, true)) { extraLines.append("ReducedConnectionPadding 1").append('\n'); }
- if(prefs.getBoolean(OrbotConstants.PREF_CIRCUIT_PADDING, true)) - { + if (prefs.getBoolean(OrbotConstants.PREF_CIRCUIT_PADDING, true)) { extraLines.append("CircuitPadding 1").append('\n'); } else { extraLines.append("CircuitPadding 0").append('\n'); }
- if(prefs.getBoolean(OrbotConstants.PREF_REDUCED_CIRCUIT_PADDING, true)) - { + if (prefs.getBoolean(OrbotConstants.PREF_REDUCED_CIRCUIT_PADDING, true)) { extraLines.append("ReducedCircuitPadding 1").append('\n'); }
- String transPort = prefs.getString("pref_transport", TorServiceConstants.TOR_TRANSPROXY_PORT_DEFAULT+""); - String dnsPort = prefs.getString("pref_dnsport", TorServiceConstants.TOR_DNS_PORT_DEFAULT+""); + String transPort = prefs.getString("pref_transport", TorServiceConstants.TOR_TRANSPROXY_PORT_DEFAULT + ""); + String dnsPort = prefs.getString("pref_dnsport", TorServiceConstants.TOR_DNS_PORT_DEFAULT + "");
extraLines.append("TransPort ").append(checkPortOrAuto(transPort)).append('\n'); - extraLines.append("DNSPort ").append(checkPortOrAuto(dnsPort)).append('\n'); + extraLines.append("DNSPort ").append(checkPortOrAuto(dnsPort)).append('\n');
extraLines.append("VirtualAddrNetwork 10.192.0.0/10").append('\n'); extraLines.append("AutomapHostsOnResolve 1").append('\n');
extraLines.append("DormantClientTimeout 10 minutes").append('\n'); - // extraLines.append("DormantOnFirstStartup 0").append('\n'); + // extraLines.append("DormantOnFirstStartup 0").append('\n'); extraLines.append("DormantCanceledByStartup 1").append('\n');
extraLines.append("DisableNetwork 0").append('\n');
if (Prefs.useDebugLogging()) { - extraLines.append("Log debug syslog").append('\n'); - extraLines.append("SafeLogging 0").append('\n'); + extraLines.append("Log debug syslog").append('\n'); + extraLines.append("SafeLogging 0").append('\n'); }
extraLines = processSettingsImpl(extraLines); @@ -801,20 +649,16 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb File fileTorRcCustom = new File(fileTorRc.getAbsolutePath() + ".custom"); boolean success = updateTorConfigCustom(fileTorRcCustom, extraLines.toString());
- if (success && fileTorRcCustom.exists()) - { - logNotice ("success."); + if (success && fileTorRcCustom.exists()) { + logNotice("success."); return fileTorRcCustom; - } - else + } else return null;
}
- private String checkPortOrAuto (String portString) - { - if (!portString.equalsIgnoreCase("auto")) - { + private String checkPortOrAuto(String portString) { + if (!portString.equalsIgnoreCase("auto")) { boolean isPortUsed = true; int port = Integer.parseInt(portString);
@@ -861,10 +705,9 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb reply.putExtra(EXTRA_HTTP_PROXY_HOST, "127.0.0.1"); reply.putExtra(EXTRA_HTTP_PROXY_PORT, mPortHTTP);
- if (packageName != null) - { - reply.setPackage(packageName); - sendBroadcast(reply); + if (packageName != null) { + reply.setPackage(packageName); + sendBroadcast(reply); }
LocalBroadcastManager.getInstance(this).sendBroadcast(reply); @@ -881,8 +724,10 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
String torProcId = null;
- try { if (conn != null) torProcId = conn.getInfo("process/pid"); } - catch (Exception e){} + try { + if (conn != null) torProcId = conn.getInfo("process/pid"); + } catch (Exception e) { + }
try {
@@ -894,39 +739,37 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb } else if (mCurrentStatus == STATUS_ON && (torProcId != null)) {
sendCallbackLogMessage("Ignoring start request, already started."); - // setTorNetworkEnabled (true); + // setTorNetworkEnabled (true);
return; }
- // make sure there are no stray daemons running - killAllDaemons(); + // make sure there are no stray daemons running + killAllDaemons();
SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); - String version = prefs.getString(PREF_BINARY_TOR_VERSION_INSTALLED,null); + String version = prefs.getString(PREF_BINARY_TOR_VERSION_INSTALLED, null); logNotice("checking binary version: " + version);
sendCallbackStatus(STATUS_STARTING); - showToolbarNotification(getString(R.string.status_starting_up),NOTIFY_ID,R.drawable.ic_stat_tor); - //sendCallbackLogMessage(getString(R.string.status_starting_up)); - //logNotice(getString(R.string.status_starting_up)); + showToolbarNotification(getString(R.string.status_starting_up), NOTIFY_ID, R.drawable.ic_stat_tor); + //sendCallbackLogMessage(getString(R.string.status_starting_up)); + //logNotice(getString(R.string.status_starting_up));
- ArrayList<String> customEnv = new ArrayList<String>(); + ArrayList<String> customEnv = new ArrayList<String>();
- if (Prefs.bridgesEnabled()) - if (Prefs.useVpn() && !mIsLollipop) - { - customEnv.add("TOR_PT_PROXY=socks5://" + OrbotVpnManager.sSocksProxyLocalhost + ":" + OrbotVpnManager.sSocksProxyServerPort); - } + if (Prefs.bridgesEnabled()) + if (Prefs.useVpn() && !mIsLollipop) { + customEnv.add("TOR_PT_PROXY=socks5://" + OrbotVpnManager.sSocksProxyLocalhost + ":" + OrbotVpnManager.sSocksProxyServerPort); + }
- boolean success = runTorShellCmd(); + boolean success = runTorShellCmd();
- if (success) - { - try { updateOnionNames (); } - catch (SecurityException se) - { + if (success) { + try { + updateOnionNames(); + } catch (SecurityException se) { logNotice("unable to upload onion names"); } } @@ -941,12 +784,11 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb } }
- private void updateOnionNames () throws SecurityException - { + private void updateOnionNames() throws SecurityException { // Tor is running, update new .onion names at db ContentResolver mCR = getApplicationContext().getContentResolver(); Cursor hidden_services = mCR.query(HS_CONTENT_URI, hsProjection, null, null, null); - if(hidden_services != null) { + if (hidden_services != null) { try { while (hidden_services.moveToNext()) { String HSDomain = hidden_services.getString(hidden_services.getColumnIndex(HiddenService.DOMAIN)); @@ -992,8 +834,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb } }
- private boolean runTorShellCmd() throws Exception - { + private boolean runTorShellCmd() throws Exception { boolean result = true;
File fileTorrcCustom = updateTorrcCustomFile(); @@ -1002,10 +843,10 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb if (fileTor == null || (!fileTor.exists()) || (!fileTor.canExecute())) return false;
- if ((!fileTorRc.exists()) || (!fileTorRc.canRead()) ) + if ((!fileTorRc.exists()) || (!fileTorRc.canRead())) return false;
- if ((!fileTorrcCustom.exists()) || (!fileTorrcCustom.canRead()) ) + if ((!fileTorrcCustom.exists()) || (!fileTorrcCustom.canRead())) return false;
sendCallbackLogMessage(getString(R.string.status_starting_up)); @@ -1019,9 +860,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
try { exitCode = exec(torCmdString + " --verify-config", true); - } - catch (Exception e) - { + } catch (Exception e) { logNotice("Tor configuration did not verify: " + e.getMessage()); return false; } @@ -1060,162 +899,149 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb return result; }
- protected void exec (Runnable runn) - { + protected void exec(Runnable runn) { mExecutor.execute(runn); }
- private int exec (String cmd, boolean wait) throws Exception - { - HashMap<String,String> mapEnv = new HashMap(); - mapEnv.put("HOME",appBinHome.getAbsolutePath()); + private int exec(String cmd, boolean wait) throws Exception { + HashMap<String, String> mapEnv = new HashMap(); + mapEnv.put("HOME", appBinHome.getAbsolutePath());
- CommandResult result = CustomShell.run("sh",wait, mapEnv, cmd); - debug("executing: " + cmd); - debug("stdout: " + result.getStdout()); - debug("stderr: " + result.getStderr()); + CommandResult result = CustomShell.run("sh", wait, mapEnv, cmd); + debug("executing: " + cmd); + debug("stdout: " + result.getStdout()); + debug("stderr: " + result.getStderr());
- return result.exitCode; + return result.exitCode; }
- private int initControlConnection (int maxTries, boolean isReconnect) throws Exception - { - int controlPort = -1; - int attempt = 0; - - logNotice( "Waiting for control port..."); - - while (conn == null && attempt++ < maxTries && (mCurrentStatus != STATUS_OFF)) - { - try - { + private int initControlConnection(int maxTries, boolean isReconnect) throws Exception { + int controlPort = -1; + int attempt = 0;
- controlPort = getControlPort(); + logNotice("Waiting for control port...");
- if (controlPort != -1) - { - logNotice( "Connecting to control port: " + controlPort); + while (conn == null && attempt++ < maxTries && (mCurrentStatus != STATUS_OFF)) { + try {
+ controlPort = getControlPort();
+ if (controlPort != -1) { + logNotice("Connecting to control port: " + controlPort);
- break; - }
+ break; } - catch (Exception ce) - { - conn = null; + + } catch (Exception ce) { + conn = null; // logException( "Error connecting to Tor local control port: " + ce.getMessage(),ce);
- } + }
- try { + try { // logNotice("waiting..."); - Thread.sleep(2000); } - catch (Exception e){} + Thread.sleep(2000); + } catch (Exception e) { } + }
- if (controlPort != -1) - { - Socket torConnSocket = new Socket(IP_LOCALHOST, controlPort); - torConnSocket.setSoTimeout(CONTROL_SOCKET_TIMEOUT); + if (controlPort != -1) { + Socket torConnSocket = new Socket(IP_LOCALHOST, controlPort); + torConnSocket.setSoTimeout(CONTROL_SOCKET_TIMEOUT);
- conn = new TorControlConnection(torConnSocket); + conn = new TorControlConnection(torConnSocket);
- conn.launchThread(true);//is daemon + conn.launchThread(true);//is daemon
- } + }
- if (conn != null) - { + if (conn != null) {
- logNotice( "SUCCESS connected to Tor control port."); + logNotice("SUCCESS connected to Tor control port.");
- File fileCookie = new File(appCacheHome, TOR_CONTROL_COOKIE); + File fileCookie = new File(appCacheHome, TOR_CONTROL_COOKIE);
- if (fileCookie.exists()) - { + if (fileCookie.exists()) {
- // We extend NullEventHandler so that we don't need to provide empty - // implementations for all the events we don't care about. - logNotice( "adding control port event handler"); + // We extend NullEventHandler so that we don't need to provide empty + // implementations for all the events we don't care about. + logNotice("adding control port event handler");
- conn.setEventHandler(mEventHandler); + conn.setEventHandler(mEventHandler);
- logNotice( "SUCCESS added control port event handler"); - byte[] cookie = new byte[(int)fileCookie.length()]; - DataInputStream fis = new DataInputStream(new FileInputStream(fileCookie)); - fis.read(cookie); - fis.close(); - conn.authenticate(cookie); + logNotice("SUCCESS added control port event handler"); + byte[] cookie = new byte[(int) fileCookie.length()]; + DataInputStream fis = new DataInputStream(new FileInputStream(fileCookie)); + fis.read(cookie); + fis.close(); + conn.authenticate(cookie);
- logNotice( "SUCCESS - authenticated to control port."); + logNotice("SUCCESS - authenticated to control port.");
- // conn.setEvents(Arrays.asList(new String[]{"DEBUG","STATUS_CLIENT","STATUS_GENERAL","BW"})); + // conn.setEvents(Arrays.asList(new String[]{"DEBUG","STATUS_CLIENT","STATUS_GENERAL","BW"}));
- if (Prefs.useDebugLogging()) - conn.setEvents(Arrays.asList(new String[]{ - "CIRC","STREAM", "ORCONN" , "BW" , "INFO" ,"NOTICE" , "WARN" , "DEBUG","ERR" , "NEWDESC" , "ADDRMAP"})); - else - conn.setEvents(Arrays.asList(new String[]{ - "CIRC","STREAM", "ORCONN" , "BW" , "NOTICE" ,"ERR" , "NEWDESC" , "ADDRMAP"})); + if (Prefs.useDebugLogging()) + conn.setEvents(Arrays.asList(new String[]{ + "CIRC", "STREAM", "ORCONN", "BW", "INFO", "NOTICE", "WARN", "DEBUG", "ERR", "NEWDESC", "ADDRMAP"})); + else + conn.setEvents(Arrays.asList(new String[]{ + "CIRC", "STREAM", "ORCONN", "BW", "NOTICE", "ERR", "NEWDESC", "ADDRMAP"}));
- // sendCallbackLogMessage(getString(R.string.tor_process_starting) + ' ' + getString(R.string.tor_process_complete)); + // sendCallbackLogMessage(getString(R.string.tor_process_starting) + ' ' + getString(R.string.tor_process_complete));
- String torProcId = conn.getInfo("process/pid"); + String torProcId = conn.getInfo("process/pid");
- String confSocks = conn.getInfo("net/listeners/socks"); - StringTokenizer st = new StringTokenizer(confSocks," "); + String confSocks = conn.getInfo("net/listeners/socks"); + StringTokenizer st = new StringTokenizer(confSocks, " ");
- confSocks = st.nextToken().split(":")[1]; - confSocks = confSocks.substring(0,confSocks.length()-1); - mPortSOCKS = Integer.parseInt(confSocks); + confSocks = st.nextToken().split(":")[1]; + confSocks = confSocks.substring(0, confSocks.length() - 1); + mPortSOCKS = Integer.parseInt(confSocks);
- String confHttp = conn.getInfo("net/listeners/httptunnel"); - st = new StringTokenizer(confHttp," "); + String confHttp = conn.getInfo("net/listeners/httptunnel"); + st = new StringTokenizer(confHttp, " ");
- confHttp = st.nextToken().split(":")[1]; - confHttp = confHttp.substring(0,confHttp.length()-1); - mPortHTTP = Integer.parseInt(confHttp); + confHttp = st.nextToken().split(":")[1]; + confHttp = confHttp.substring(0, confHttp.length() - 1); + mPortHTTP = Integer.parseInt(confHttp);
- String confDns = conn.getInfo("net/listeners/dns"); - st = new StringTokenizer(confDns," "); - if (st.hasMoreTokens()) { - confDns = st.nextToken().split(":")[1]; - confDns = confDns.substring(0, confDns.length() - 1); - mPortDns = Integer.parseInt(confDns); - Prefs.getSharedPrefs(getApplicationContext()).edit().putInt(VpnPrefs.PREFS_DNS_PORT, mPortDns).apply(); - } + String confDns = conn.getInfo("net/listeners/dns"); + st = new StringTokenizer(confDns, " "); + if (st.hasMoreTokens()) { + confDns = st.nextToken().split(":")[1]; + confDns = confDns.substring(0, confDns.length() - 1); + mPortDns = Integer.parseInt(confDns); + Prefs.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); - } + 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); + }
- sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans); + sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans);
- setTorNetworkEnabled(true); + setTorNetworkEnabled(true);
- return Integer.parseInt(torProcId); + return Integer.parseInt(torProcId);
- } - else - { - logNotice ("Tor authentication cookie does not exist yet"); - conn = null; + } else { + logNotice("Tor authentication cookie does not exist yet"); + conn = null;
- } - } + } + }
- throw new Exception("Tor control port could not be found"); + throw new Exception("Tor control port could not be found"); }
- private int getControlPort () { + private int getControlPort() { int result = -1;
try { @@ -1235,252 +1061,213 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb //store last valid control port SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); prefs.edit().putInt("controlport", result).commit(); - } - else { + } else { debug("Control Port config file does not yet exist (waiting for tor): " + fileControlPort.getCanonicalPath()); } - } - catch (FileNotFoundException e) { + } catch (FileNotFoundException e) { debug("unable to get control port; file not found"); - } - catch (Exception e) { + } catch (Exception e) { debug("unable to read control port config file"); }
return result; }
+ /** + * Returns the port number that the HTTP proxy is running on + */ + public int getHTTPPort() { + return mPortHTTP; + }
- /** - * Returns the port number that the HTTP proxy is running on - */ - public int getHTTPPort() { - return mPortHTTP; - } - - - /** - * Returns the port number that the HTTP proxy is running on - */ - public int getSOCKSPort() { - return mPortSOCKS; - } + /** + * Returns the port number that the HTTP proxy is running on + */ + public int getSOCKSPort() { + return mPortSOCKS; + }
- public String getInfo (String key) { - try { - if(conn !=null){ - String m = conn.getInfo(key); - return m; - } + public String getInfo(String key) { + try { + if (conn != null) { + String m = conn.getInfo(key); + return m; } - catch(Exception ioe){ + } catch (Exception ioe) { // Log.e(TAG,"Unable to get Tor information",ioe); - logNotice("Unable to get Tor information"+ioe.getMessage()); - } - return null; + logNotice("Unable to get Tor information" + ioe.getMessage()); } + return null; + }
- public String getConfiguration (String name) - { - try - { - if (conn != null) - { - StringBuffer result = new StringBuffer(); - - List<ConfigEntry> listCe = conn.getConf(name); - - Iterator<ConfigEntry> itCe = listCe.iterator(); - ConfigEntry ce = null; + public String getConfiguration(String name) { + try { + if (conn != null) { + StringBuffer result = new StringBuffer();
+ List<ConfigEntry> listCe = conn.getConf(name);
+ Iterator<ConfigEntry> itCe = listCe.iterator(); + ConfigEntry ce = null;
- while (itCe.hasNext()) - { - ce = itCe.next();
- result.append(ce.key); - result.append(' '); - result.append(ce.value); - result.append('\n'); - } + while (itCe.hasNext()) { + ce = itCe.next();
- return result.toString(); + result.append(ce.key); + result.append(' '); + result.append(ce.value); + result.append('\n'); } - } - catch (Exception ioe) - {
- logException("Unable to get Tor configuration: " + ioe.getMessage(),ioe); + return result.toString(); } + } catch (Exception ioe) {
- return null; + logException("Unable to get Tor configuration: " + ioe.getMessage(), ioe); }
- private final static String RESET_STRING = "="""; - /** - * Set configuration - **/ - public boolean updateConfiguration (String name, String value, boolean saveToDisk) - { + return null; + }
+ /** + * Set configuration + **/ + public boolean updateConfiguration(String name, String value, boolean saveToDisk) {
- if (configBuffer == null) - configBuffer = new ArrayList<String>();
- if (resetBuffer == null) - resetBuffer = new ArrayList<String>(); + if (configBuffer == null) + configBuffer = new ArrayList<String>();
- if (value == null || value.length() == 0) - { - resetBuffer.add(name + RESET_STRING); + if (resetBuffer == null) + resetBuffer = new ArrayList<String>();
- } - else - { - StringBuffer sbConf = new StringBuffer(); - sbConf.append(name); - sbConf.append(' '); - sbConf.append(value); + if (value == null || value.length() == 0) { + resetBuffer.add(name + RESET_STRING);
- configBuffer.add(sbConf.toString()); - } + } else { + StringBuffer sbConf = new StringBuffer(); + sbConf.append(name); + sbConf.append(' '); + sbConf.append(value);
- return false; + configBuffer.add(sbConf.toString()); }
+ return false; + }
- public void setTorNetworkEnabled (final boolean isEnabled) throws IOException - {
- //it is possible to not have a connection yet, and someone might try to newnym - if (conn != null) - { - new Thread () - { - public void run () - { - try { + public void setTorNetworkEnabled(final boolean isEnabled) throws IOException {
- final String newValue =isEnabled ? "0" : "1"; - conn.setConf("DisableNetwork", newValue); - } - catch (Exception ioe){ - debug("error requesting newnym: " + ioe.getLocalizedMessage()); - } + //it is possible to not have a connection yet, and someone might try to newnym + if (conn != null) { + new Thread() { + public void run() { + try { + + final String newValue = isEnabled ? "0" : "1"; + conn.setConf("DisableNetwork", newValue); + } catch (Exception ioe) { + debug("error requesting newnym: " + ioe.getLocalizedMessage()); } - }.start(); - } - + } + }.start(); }
- public void sendSignalActive () - { - if (conn != null && mCurrentStatus == STATUS_ON) { - try { - conn.signal("ACTIVE"); - } catch (IOException e) { - debug("error send active: " + e.getLocalizedMessage()); - } + } + + public void sendSignalActive() { + if (conn != null && mCurrentStatus == STATUS_ON) { + try { + conn.signal("ACTIVE"); + } catch (IOException e) { + debug("error send active: " + e.getLocalizedMessage()); } } + }
- public void newIdentity () - { - //it is possible to not have a connection yet, and someone might try to newnym - if (conn != null) - { - new Thread () - { - public void run () - { - try { + public void newIdentity() { + //it is possible to not have a connection yet, and someone might try to newnym + if (conn != null) { + new Thread() { + public void run() { + try {
- int iconId = R.drawable.ic_stat_tor; + int iconId = R.drawable.ic_stat_tor;
- if (hasConnectivity() && Prefs.expandedNotifications()) - showToolbarNotification(getString(R.string.newnym), getNotifyId(), iconId); + if (hasConnectivity() && Prefs.expandedNotifications()) + showToolbarNotification(getString(R.string.newnym), getNotifyId(), iconId);
- conn.signal("NEWNYM"); + conn.signal("NEWNYM");
- } - catch (Exception ioe){ + } catch (Exception ioe) {
- debug("error requesting newnym: " + ioe.getLocalizedMessage()); + debug("error requesting newnym: " + ioe.getLocalizedMessage());
- } } - }.start(); - } + } + }.start(); } + }
- public boolean saveConfiguration () - { - try - { - if (conn != null) - { + public boolean saveConfiguration() { + try { + if (conn != null) {
- if (resetBuffer != null && resetBuffer.size() > 0) - { - for (String value : configBuffer) - { + if (resetBuffer != null && resetBuffer.size() > 0) { + for (String value : configBuffer) {
- // debug("removing torrc conf: " + value); + // debug("removing torrc conf: " + value);
- } + }
- // conn.resetConf(resetBuffer); - resetBuffer = null; - } + // conn.resetConf(resetBuffer); + resetBuffer = null; + }
- if (configBuffer != null && configBuffer.size() > 0) - { + if (configBuffer != null && configBuffer.size() > 0) {
- for (String value : configBuffer) - { + for (String value : configBuffer) {
- debug("Setting torrc conf: " + value); + debug("Setting torrc conf: " + value);
- } + }
- conn.setConf(configBuffer); + conn.setConf(configBuffer);
- configBuffer = null; - } + configBuffer = null; + }
- // Flush the configuration to disk. - //this is doing bad things right now NF 22/07/10 - //conn.saveConf(); + // Flush the configuration to disk. + //this is doing bad things right now NF 22/07/10 + //conn.saveConf();
- return true; - } - } - catch (Exception ioe) - { - logException("Unable to update Tor configuration: " + ioe.getMessage(),ioe); + return true; } - - return false; + } catch (Exception ioe) { + logException("Unable to update Tor configuration: " + ioe.getMessage(), ioe); }
- protected void sendCallbackBandwidth(long upload, long download, long written, long read) { + return false; + } + + protected void sendCallbackBandwidth(long upload, long download, long written, long read) { Intent intent = new Intent(LOCAL_ACTION_BANDWIDTH);
- intent.putExtra("up",upload); - intent.putExtra("down",download); - intent.putExtra("written",written); - intent.putExtra("read",read); - intent.putExtra(EXTRA_STATUS, mCurrentStatus); + intent.putExtra("up", upload); + intent.putExtra("down", download); + intent.putExtra("written", written); + intent.putExtra("read", read); + intent.putExtra(EXTRA_STATUS, mCurrentStatus);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent); }
- private void sendCallbackLogMessage (final String logMessage) - { + private void sendCallbackLogMessage(final String logMessage) {
mHandler.post(() -> {
@@ -1494,20 +1281,19 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
- private void sendCallbackPorts (int socksPort, int httpPort, int dnsPort, int transPort) - { + 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(EXTRA_SOCKS_PROXY_PORT,socksPort); - intent.putExtra(EXTRA_HTTP_PROXY_PORT,httpPort); - intent.putExtra(EXTRA_DNS_PORT,dnsPort); - intent.putExtra(EXTRA_TRANS_PORT,transPort); + 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);
if (Prefs.useVpn()) - mVpnManager.handleIntent(new Builder(),intent); + mVpnManager.handleIntent(new Builder(), intent);
}
@@ -1522,6 +1308,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
/** * Send a secure broadcast only to Orbot itself + * * @see {@link ContextWrapper#sendBroadcast(Intent)} * @see {@link LocalBroadcastManager} */ @@ -1541,47 +1328,47 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb */
/** - private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - - if (mCurrentStatus == STATUS_OFF) - return; - - SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); - - boolean doNetworKSleep = prefs.getBoolean(OrbotConstants.PREF_DISABLE_NETWORK, true); - - final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - final NetworkInfo netInfo = cm.getActiveNetworkInfo(); - - boolean newConnectivityState = false; - int newNetType = -1; - - if (netInfo!=null) - newNetType = netInfo.getType(); - - if(netInfo != null && netInfo.isConnected()) { - // WE ARE CONNECTED: DO SOMETHING - newConnectivityState = true; - } - else { - // WE ARE NOT: DO SOMETHING ELSE - newConnectivityState = false; - } - - if (newConnectivityState != mConnectivity) { - mConnectivity = newConnectivityState; - - //if (mConnectivity) - // newIdentity(); - } - - } - };**/ - - private StringBuffer processSettingsImpl (StringBuffer extraLines) throws IOException - { + * private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() { + * + * @Override public void onReceive(Context context, Intent intent) { + * <p> + * if (mCurrentStatus == STATUS_OFF) + * return; + * <p> + * SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); + * <p> + * boolean doNetworKSleep = prefs.getBoolean(OrbotConstants.PREF_DISABLE_NETWORK, true); + * <p> + * final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + * final NetworkInfo netInfo = cm.getActiveNetworkInfo(); + * <p> + * boolean newConnectivityState = false; + * int newNetType = -1; + * <p> + * if (netInfo!=null) + * newNetType = netInfo.getType(); + * <p> + * if(netInfo != null && netInfo.isConnected()) { + * // WE ARE CONNECTED: DO SOMETHING + * newConnectivityState = true; + * } + * else { + * // WE ARE NOT: DO SOMETHING ELSE + * newConnectivityState = false; + * } + * <p> + * if (newConnectivityState != mConnectivity) { + * mConnectivity = newConnectivityState; + * <p> + * //if (mConnectivity) + * // newIdentity(); + * } + * <p> + * } + * }; + **/ + + private StringBuffer processSettingsImpl(StringBuffer extraLines) throws IOException { logNotice(getString(R.string.updating_settings_in_tor_service));
SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); @@ -1589,64 +1376,52 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb boolean useBridges = Prefs.bridgesEnabled();
boolean becomeRelay = prefs.getBoolean(OrbotConstants.PREF_OR, false); - boolean ReachableAddresses = prefs.getBoolean(OrbotConstants.PREF_REACHABLE_ADDRESSES,false); + boolean ReachableAddresses = prefs.getBoolean(OrbotConstants.PREF_REACHABLE_ADDRESSES, false);
boolean enableStrictNodes = prefs.getBoolean("pref_strict_nodes", false); String entranceNodes = prefs.getString("pref_entrance_nodes", ""); String exitNodes = prefs.getString("pref_exit_nodes", ""); String excludeNodes = prefs.getString("pref_exclude_nodes", "");
- if (!useBridges) - { + if (!useBridges) {
extraLines.append("UseBridges 0").append('\n');
- if (Prefs.useVpn()) //set the proxy here if we aren't using a bridge - { - - if (!mIsLollipop) - { - String proxyType = "socks5"; - extraLines.append(proxyType + "Proxy" + ' ' + OrbotVpnManager.sSocksProxyLocalhost + ':' + OrbotVpnManager.sSocksProxyServerPort).append('\n'); - }; - - } - else - { - String proxyType = prefs.getString("pref_proxy_type", null); - if (proxyType != null && proxyType.length() > 0) - { - String proxyHost = prefs.getString("pref_proxy_host", null); - String proxyPort = prefs.getString("pref_proxy_port", null); - String proxyUser = prefs.getString("pref_proxy_username", null); - String proxyPass = prefs.getString("pref_proxy_password", null); - - if ((proxyHost != null && proxyHost.length()>0) && (proxyPort != null && proxyPort.length() > 0)) - { - extraLines.append(proxyType + "Proxy" + ' ' + proxyHost + ':' + proxyPort).append('\n'); - - if (proxyUser != null && proxyPass != null) - { - if (proxyType.equalsIgnoreCase("socks5")) - { - extraLines.append("Socks5ProxyUsername" + ' ' + proxyUser).append('\n'); - extraLines.append("Socks5ProxyPassword" + ' ' + proxyPass).append('\n'); - } - else - extraLines.append(proxyType + "ProxyAuthenticator" + ' ' + proxyUser + ':' + proxyPort).append('\n'); - - } - else if (proxyPass != null) - extraLines.append(proxyType + "ProxyAuthenticator" + ' ' + proxyUser + ':' + proxyPort).append('\n'); - - - - } - } - } - } - else - { + if (Prefs.useVpn()) //set the proxy here if we aren't using a bridge + { + + if (!mIsLollipop) { + String proxyType = "socks5"; + extraLines.append(proxyType + "Proxy" + ' ' + OrbotVpnManager.sSocksProxyLocalhost + ':' + OrbotVpnManager.sSocksProxyServerPort).append('\n'); + } + ; + + } else { + String proxyType = prefs.getString("pref_proxy_type", null); + if (proxyType != null && proxyType.length() > 0) { + String proxyHost = prefs.getString("pref_proxy_host", null); + String proxyPort = prefs.getString("pref_proxy_port", null); + String proxyUser = prefs.getString("pref_proxy_username", null); + String proxyPass = prefs.getString("pref_proxy_password", null); + + if ((proxyHost != null && proxyHost.length() > 0) && (proxyPort != null && proxyPort.length() > 0)) { + extraLines.append(proxyType + "Proxy" + ' ' + proxyHost + ':' + proxyPort).append('\n'); + + if (proxyUser != null && proxyPass != null) { + if (proxyType.equalsIgnoreCase("socks5")) { + extraLines.append("Socks5ProxyUsername" + ' ' + proxyUser).append('\n'); + extraLines.append("Socks5ProxyPassword" + ' ' + proxyPass).append('\n'); + } else + extraLines.append(proxyType + "ProxyAuthenticator" + ' ' + proxyUser + ':' + proxyPort).append('\n'); + + } else if (proxyPass != null) + extraLines.append(proxyType + "ProxyAuthenticator" + ' ' + proxyUser + ':' + proxyPort).append('\n'); + + + } + } + } + } else { if (fileObfsclient != null && fileObfsclient.exists() && fileObfsclient.canExecute()) { @@ -1654,11 +1429,11 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb loadBridgeDefaults();
extraLines.append("UseBridges 1").append('\n'); - // extraLines.append("UpdateBridgesFromAuthority 1").append('\n'); + // extraLines.append("UpdateBridgesFromAuthority 1").append('\n');
String bridgeList = Prefs.getBridgesList(); boolean obfs3Bridges = bridgeList.contains("obfs3"); - boolean obfs4Bridges = bridgeList.contains("obfs4"); + boolean obfs4Bridges = bridgeList.contains("obfs4"); boolean meekBridges = bridgeList.contains("meek");
//check if any PT bridges are needed @@ -1676,20 +1451,20 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb if (bridgeList != null && bridgeList.length() > 5) //longer then 1 = some real values here { String[] bridgeListLines = parseBridgesFromSettings(bridgeList); - int bridgeIdx = (int)Math.floor(Math.random()*((double)bridgeListLines.length)); + int bridgeIdx = (int) Math.floor(Math.random() * ((double) bridgeListLines.length)); String bridgeLine = bridgeListLines[bridgeIdx]; extraLines.append("Bridge "); extraLines.append(bridgeLine); extraLines.append("\n"); /** - for (String bridgeConfigLine : bridgeListLines) { - if (!TextUtils.isEmpty(bridgeConfigLine)) { - extraLines.append("Bridge "); - extraLines.append(bridgeConfigLine.trim()); - extraLines.append("\n"); - } - - }**/ + for (String bridgeConfigLine : bridgeListLines) { + if (!TextUtils.isEmpty(bridgeConfigLine)) { + extraLines.append("Bridge "); + extraLines.append(bridgeConfigLine.trim()); + extraLines.append("\n"); + } + + }**/ } else {
String type = "obfs4"; @@ -1700,9 +1475,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb getBridges(type, extraLines);
} - } - else - { + } else { throw new IOException("Bridge binary does not exist: " + fileObfsclient.getCanonicalPath()); } } @@ -1712,50 +1485,43 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb File fileGeoIP = new File(appBinHome, GEOIP_ASSET_KEY); File fileGeoIP6 = new File(appBinHome, GEOIP6_ASSET_KEY);
- if (fileGeoIP.exists()) - { - extraLines.append("GeoIPFile" + ' ' + fileGeoIP.getCanonicalPath()).append('\n'); - extraLines.append("GeoIPv6File" + ' ' + fileGeoIP6.getCanonicalPath()).append('\n'); + if (fileGeoIP.exists()) { + extraLines.append("GeoIPFile" + ' ' + fileGeoIP.getCanonicalPath()).append('\n'); + extraLines.append("GeoIPv6File" + ' ' + fileGeoIP6.getCanonicalPath()).append('\n'); }
if (!TextUtils.isEmpty(entranceNodes)) - extraLines.append("EntryNodes" + ' ' + entranceNodes).append('\n'); + extraLines.append("EntryNodes" + ' ' + entranceNodes).append('\n');
if (!TextUtils.isEmpty(exitNodes)) - extraLines.append("ExitNodes" + ' ' + exitNodes).append('\n'); + extraLines.append("ExitNodes" + ' ' + exitNodes).append('\n');
if (!TextUtils.isEmpty(excludeNodes)) - extraLines.append("ExcludeNodes" + ' ' + excludeNodes).append('\n'); + extraLines.append("ExcludeNodes" + ' ' + excludeNodes).append('\n');
extraLines.append("StrictNodes" + ' ' + (enableStrictNodes ? "1" : "0")).append('\n');
- try - { - if (ReachableAddresses) - { + try { + if (ReachableAddresses) { String ReachableAddressesPorts = - prefs.getString(OrbotConstants.PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443"); + prefs.getString(OrbotConstants.PREF_REACHABLE_ADDRESSES_PORTS, "*:80,*:443");
extraLines.append("ReachableAddresses" + ' ' + ReachableAddressesPorts).append('\n');
}
- } - catch (Exception e) - { - showToolbarNotification (getString(R.string.your_reachableaddresses_settings_caused_an_exception_),ERROR_NOTIFY_ID,R.drawable.ic_stat_notifyerr); + } catch (Exception e) { + showToolbarNotification(getString(R.string.your_reachableaddresses_settings_caused_an_exception_), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
- return null; + return null; }
- try - { - if (becomeRelay && (!useBridges) && (!ReachableAddresses)) - { - int ORPort = Integer.parseInt(prefs.getString(OrbotConstants.PREF_OR_PORT, "9001")); + try { + if (becomeRelay && (!useBridges) && (!ReachableAddresses)) { + int ORPort = Integer.parseInt(prefs.getString(OrbotConstants.PREF_OR_PORT, "9001")); String nickname = prefs.getString(OrbotConstants.PREF_OR_NICKNAME, "Orbot");
- String dnsFile = writeDNSFile (); + String dnsFile = writeDNSFile();
extraLines.append("ServerDNSResolvConfFile" + ' ' + dnsFile).append('\n'); extraLines.append("ORPort" + ' ' + ORPort).append('\n'); @@ -1763,10 +1529,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb extraLines.append("ExitPolicy" + ' ' + "reject *:*").append('\n');
} - } - catch (Exception e) - { - showToolbarNotification (getString(R.string.your_relay_settings_caused_an_exception_),ERROR_NOTIFY_ID,R.drawable.ic_stat_notifyerr); + } catch (Exception e) { + showToolbarNotification(getString(R.string.your_relay_settings_caused_an_exception_), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr);
return null; @@ -1790,7 +1554,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
extraLines.append("HiddenServiceDir" + ' ' + hsDirPath).append('\n'); extraLines.append("HiddenServicePort" + ' ' + HSOnionPort + " 127.0.0.1:" + HSLocalPort).append('\n'); - extraLines.append("HiddenServiceVersion 2").append('\n'); + extraLines.append("HiddenServiceVersion 2").append('\n');
if (HSAuthCookie == 1) extraLines.append("HiddenServiceAuthorizeClient stealth " + HSname).append('\n'); @@ -1803,15 +1567,14 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
hidden_services.close(); } + } catch (SecurityException se) { } - catch (SecurityException se) {}
- try - { + try {
/* ---- Client Cookies ---- */ Cursor client_cookies = mCR.query(COOKIE_CONTENT_URI, cookieProjection, ClientCookie.ENABLED + "=1", null, null); - if(client_cookies != null) { + if (client_cookies != null) { try { while (client_cookies.moveToNext()) { String domain = client_cookies.getString(client_cookies.getColumnIndex(ClientCookie.DOMAIN)); @@ -1819,30 +1582,19 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb extraLines.append("HidServAuth" + ' ' + domain + ' ' + cookie).append('\n'); } } catch (Exception e) { - Log.e(OrbotConstants.TAG,"error starting share server",e); + Log.e(OrbotConstants.TAG, "error starting share server", e); }
client_cookies.close(); } + } catch (SecurityException se) { } - catch (SecurityException se) {}
return extraLines; }
- /** - * @param bridgeList bridges that were manually entered into Orbot settings - * @return Array with each bridge as an element, no whitespace entries see issue #289... - */ - private static String[] parseBridgesFromSettings(String bridgeList) { - // this regex replaces lines that only contain whitespace with an empty String - bridgeList = bridgeList.trim().replaceAll("(?m)^[ \t]*\r?\n", ""); - return bridgeList.split("\n"); - } - //using Google DNS for now as the public DNS server - private String writeDNSFile () throws IOException - { + private String writeDNSFile() throws IOException { File file = new File(appBinHome, "resolv.conf");
PrintWriter bw = new PrintWriter(new FileWriter(file)); @@ -1859,32 +1611,39 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb super.onTrimMemory(level);
switch (level) { - case TRIM_MEMORY_BACKGROUND: debug("trim memory requested: app in the background"); - return; + case TRIM_MEMORY_BACKGROUND: + debug("trim memory requested: app in the background"); + return;
- case TRIM_MEMORY_COMPLETE: debug("trim memory requested: cleanup all memory"); - return; + case TRIM_MEMORY_COMPLETE: + debug("trim memory requested: cleanup all memory"); + return;
- case TRIM_MEMORY_MODERATE: debug("trim memory requested: clean up some memory"); - return; + case TRIM_MEMORY_MODERATE: + debug("trim memory requested: clean up some memory"); + return;
- case TRIM_MEMORY_RUNNING_CRITICAL: debug("trim memory requested: memory on device is very low and critical"); - return; + case TRIM_MEMORY_RUNNING_CRITICAL: + debug("trim memory requested: memory on device is very low and critical"); + return;
- case TRIM_MEMORY_RUNNING_LOW: debug("trim memory requested: memory on device is running low"); - return; + case TRIM_MEMORY_RUNNING_LOW: + debug("trim memory requested: memory on device is running low"); + return;
- case TRIM_MEMORY_RUNNING_MODERATE: debug("trim memory requested: memory on device is moderate"); - return; + case TRIM_MEMORY_RUNNING_MODERATE: + debug("trim memory requested: memory on device is moderate"); + return;
- case TRIM_MEMORY_UI_HIDDEN: debug("trim memory requested: app is not showing UI anymore"); - return; + case TRIM_MEMORY_UI_HIDDEN: + debug("trim memory requested: app is not showing UI anymore"); + return; } }
@Override public IBinder onBind(Intent intent) { - Log.e( TAG, "onBind" ); + Log.e(TAG, "onBind"); //do nothing here return super.onBind(intent); // invoking super class will call onRevoke() when appropriate } @@ -1898,101 +1657,76 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_STOP_VPN)); }
- private void setExitNode (String newExits) - { - SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); - - if (TextUtils.isEmpty(newExits)) - { - prefs.edit().remove("pref_exit_nodes").apply(); - - if (conn != null) - { - try - { - ArrayList<String> resetBuffer = new ArrayList<String>(); - resetBuffer.add("ExitNodes"); - resetBuffer.add("StrictNodes"); - conn.resetConf(resetBuffer); - conn.setConf("DisableNetwork","1"); - conn.setConf("DisableNetwork","0"); - - } - catch (Exception ioe) - { - Log.e(OrbotConstants.TAG, "Connection exception occured resetting exits",ioe); - } - } - } - else - { - prefs.edit().putString("pref_exit_nodes", newExits).apply(); - - if (conn != null) - { - try - { + private void setExitNode(String newExits) { + SharedPreferences prefs = Prefs.getSharedPrefs(getApplicationContext()); + + if (TextUtils.isEmpty(newExits)) { + prefs.edit().remove("pref_exit_nodes").apply(); + + if (conn != null) { + try { + ArrayList<String> resetBuffer = new ArrayList<String>(); + resetBuffer.add("ExitNodes"); + resetBuffer.add("StrictNodes"); + conn.resetConf(resetBuffer); + conn.setConf("DisableNetwork", "1"); + conn.setConf("DisableNetwork", "0"); + + } catch (Exception ioe) { + Log.e(OrbotConstants.TAG, "Connection exception occured resetting exits", ioe); + } + } + } else { + prefs.edit().putString("pref_exit_nodes", newExits).apply(); + + if (conn != null) { + try { File fileGeoIP = new File(appBinHome, GEOIP_ASSET_KEY); File fileGeoIP6 = new File(appBinHome, GEOIP6_ASSET_KEY);
- conn.setConf("GeoIPFile",fileGeoIP.getCanonicalPath()); - conn.setConf("GeoIPv6File",fileGeoIP6.getCanonicalPath()); + conn.setConf("GeoIPFile", fileGeoIP.getCanonicalPath()); + conn.setConf("GeoIPv6File", fileGeoIP6.getCanonicalPath());
- conn.setConf("ExitNodes", newExits); - conn.setConf("StrictNodes","1"); + conn.setConf("ExitNodes", newExits); + conn.setConf("StrictNodes", "1");
- conn.setConf("DisableNetwork","1"); - conn.setConf("DisableNetwork","0"); + conn.setConf("DisableNetwork", "1"); + conn.setConf("DisableNetwork", "0");
- } - catch (Exception ioe) - { - Log.e(OrbotConstants.TAG, "Connection exception occured resetting exits",ioe); - } - } - } + } catch (Exception ioe) { + Log.e(OrbotConstants.TAG, "Connection exception occured resetting exits", ioe); + } + } + }
}
- public boolean hasConnectivity () - { + public boolean hasConnectivity() { return mConnectivity; }
- public int getNotifyId () - { + public int getNotifyId() { return NOTIFY_ID; }
- // for bridge loading from the assets default bridges.txt file - class Bridge - { - String type; - String config; - } - - - private void loadBridgeDefaults () - { - if (alBridges == null) - { + private void loadBridgeDefaults() { + if (alBridges == null) { alBridges = new ArrayList<>();
- try - { - BufferedReader in= + try { + BufferedReader in = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.bridges), "UTF-8")); String str;
- while ((str=in.readLine()) != null) { + while ((str = in.readLine()) != null) {
- StringTokenizer st = new StringTokenizer (str," "); + StringTokenizer st = new StringTokenizer(str, " "); Bridge b = new Bridge(); b.type = st.nextToken();
StringBuffer sbConfig = new StringBuffer();
- while(st.hasMoreTokens()) + while (st.hasMoreTokens()) sbConfig.append(st.nextToken()).append(' ');
b.config = sbConfig.toString().trim(); @@ -2002,20 +1736,14 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb }
in.close(); - } - catch (Exception e) - { + } catch (Exception e) { e.printStackTrace(); } }
}
- //we should randomly sort alBridges so we don't have the same bridge order each time - Random bridgeSelectRandom = new Random(System.nanoTime()); - - private void getBridges (String type, StringBuffer extraLines) - { + private void getBridges(String type, StringBuffer extraLines) {
Collections.shuffle(alBridges, bridgeSelectRandom);
@@ -2024,10 +1752,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb int bridgeCount = 0;
//now go through the list to find the bridges we want - for (Bridge b : alBridges) - { - if (b.type.equals(type)) - { + for (Bridge b : alBridges) { + if (b.type.equals(type)) { extraLines.append("Bridge "); extraLines.append(b.type); extraLines.append(' '); @@ -2043,21 +1769,113 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
}
- ActionBroadcastReceiver mActionBroadcastReceiver; + public static final class HiddenService implements BaseColumns { + public static final String NAME = "name"; + 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"; + public static final String ENABLED = "enabled";
- private class ActionBroadcastReceiver extends BroadcastReceiver - { - public void onReceive(Context context, Intent intent) - { - switch (intent.getAction()) - { - case CMD_NEWNYM: - { + private HiddenService() { + } + } + + public static final class ClientCookie implements BaseColumns { + public static final String DOMAIN = "domain"; + public static final String AUTH_COOKIE_VALUE = "auth_cookie_value"; + public static final String ENABLED = "enabled"; + + private ClientCookie() { + } + } + + private class IncomingIntentRouter implements Runnable { + Intent mIntent; + + public IncomingIntentRouter(Intent intent) { + mIntent = intent; + } + + public void run() { + + String action = mIntent.getAction(); + + if (!TextUtils.isEmpty(action)) { + if (action.equals(ACTION_START) || action.equals(ACTION_START_ON_BOOT)) { + startTor(); + replyWithStatus(mIntent); + + if (Prefs.useVpn()) { + if (mVpnManager != null + && (!mVpnManager.isStarted())) { + //start VPN here + Intent vpnIntent = VpnService.prepare(OrbotService.this); + if (vpnIntent == null) //then we can run the VPN + { + mVpnManager.handleIntent(new Builder(), mIntent); + + } + } + + if (mPortSOCKS != -1 && mPortHTTP != -1) + sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans); + } + + } else if (action.equals(ACTION_START_VPN)) { + if (mVpnManager != null && (!mVpnManager.isStarted())) { + //start VPN here + Intent vpnIntent = VpnService.prepare(OrbotService.this); + if (vpnIntent == null) //then we can run the VPN + { + mVpnManager.handleIntent(new Builder(), mIntent); + + + } + } + + if (mPortSOCKS != -1 && mPortHTTP != -1) + sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans); + + + } else if (action.equals(ACTION_STOP_VPN)) { + if (mVpnManager != null) + mVpnManager.handleIntent(new Builder(), mIntent); + } else if (action.equals(ACTION_STATUS)) { + replyWithStatus(mIntent); + } else if (action.equals(CMD_SIGNAL_HUP)) { + requestTorRereadConfig(); + } else if (action.equals(CMD_NEWNYM)) { + newIdentity(); + } else if (action.equals(CMD_ACTIVE)) { + sendSignalActive(); + } else if (action.equals(CMD_SET_EXIT)) { + + setExitNode(mIntent.getStringExtra("exit")); + + } else { + Log.w(OrbotConstants.TAG, "unhandled OrbotService Intent: " + action); + } + } + } + } + + // for bridge loading from the assets default bridges.txt file + class Bridge { + String type; + String config; + } + + private class ActionBroadcastReceiver extends BroadcastReceiver { + public void onReceive(Context context, Intent intent) { + switch (intent.getAction()) { + case CMD_NEWNYM: { newIdentity(); break; } - case CMD_ACTIVE: - { + case CMD_ACTIVE: { sendSignalActive(); break; } diff --git a/orbotservice/src/main/java/org/torproject/android/service/StartTorReceiver.java b/orbotservice/src/main/java/org/torproject/android/service/StartTorReceiver.java index 008caa1e..3fb77e91 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/StartTorReceiver.java +++ b/orbotservice/src/main/java/org/torproject/android/service/StartTorReceiver.java @@ -1,4 +1,3 @@ - package org.torproject.android.service;
import android.content.BroadcastReceiver; @@ -6,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.text.TextUtils; + import org.torproject.android.service.util.Prefs;
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 7cebd794..f473f51a 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java +++ b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java @@ -18,43 +18,25 @@ import java.util.StringTokenizer; */ public class TorEventHandler implements EventHandler, TorServiceConstants {
+ private final static int BW_THRESDHOLD = 10000; private OrbotService mService; - - private long lastRead = -1; private long lastWritten = -1; private long mTotalTrafficWritten = 0; private long mTotalTrafficRead = 0; - private NumberFormat mNumberFormat = null; + private HashMap<String, Node> hmBuiltNodes = new HashMap<String, Node>();
+ public TorEventHandler(OrbotService service) { + mService = service; + mNumberFormat = NumberFormat.getInstance(Locale.getDefault()); //localized numbers!
- private HashMap<String,Node> hmBuiltNodes = new HashMap<String,Node>(); - - public class Node - { - 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 () - { + public HashMap<String, Node> getNodes() { return hmBuiltNodes; }
- public TorEventHandler (OrbotService service) - { - mService = service; - mNumberFormat = NumberFormat.getInstance(Locale.getDefault()); //localized numbers! - - } - @Override public void message(String severity, String msg) {
@@ -77,7 +59,7 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
StringBuilder sb = new StringBuilder(); sb.append("orConnStatus ("); - sb.append(parseNodeName(orName) ); + sb.append(parseNodeName(orName)); sb.append("): "); sb.append(status);
@@ -108,13 +90,10 @@ public class TorEventHandler implements EventHandler, TorServiceConstants { mService.logNotice(sb.toString()); }
- private final static int BW_THRESDHOLD = 10000; - @Override public void bandwidthUsed(long read, long written) {
- if (lastWritten > BW_THRESDHOLD || lastRead > BW_THRESDHOLD) - { + if (lastWritten > BW_THRESDHOLD || lastRead > BW_THRESDHOLD) { StringBuilder sb = new StringBuilder(); sb.append(formatCount(read)); sb.append(" \u2193"); @@ -150,9 +129,9 @@ public class TorEventHandler implements EventHandler, TorServiceConstants { // Over 2Mb, returns "xxx.xxMb" if (mNumberFormat != null) if (count < 1e6) - return mNumberFormat.format(Math.round((float)((int)(count*10/1024))/10)) + "kbps"; + return mNumberFormat.format(Math.round((float) ((int) (count * 10 / 1024)) / 10)) + "kbps"; else - return mNumberFormat.format(Math.round((float)((int)(count*100/1024/1024))/100)) + "mbps"; + return mNumberFormat.format(Math.round((float) ((int) (count * 100 / 1024 / 1024)) / 100)) + "mbps"; else return "";
@@ -203,8 +182,7 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
node = hmBuiltNodes.get(nodeId);
- if (node == null) - { + if (node == null) { node = new Node(); node.id = nodeId; node.name = nodeName; @@ -220,11 +198,9 @@ public class TorEventHandler implements EventHandler, TorServiceConstants { if (st.hasMoreTokens()) sb.append(" > ");
- if (status.equals("EXTENDED")) - { + if (status.equals("EXTENDED")) {
- if (isFirstNode) - { + if (isFirstNode) { hmBuiltNodes.put(node.id, node);
if (node.ipAddress == null && (!node.isFetchingInfo) && Prefs.useDebugLogging()) { @@ -234,14 +210,12 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
isFirstNode = false; } - } - else if (status.equals("BUILT")) { - // mService.logNotice(sb.toString()); + } else if (status.equals("BUILT")) { + // mService.logNotice(sb.toString());
if (Prefs.useDebugLogging() && nodeCount > 3) mService.debug(sb.toString()); - } - else if (status.equals("CLOSED")) { + } else if (status.equals("CLOSED")) { // mService.logNotice(sb.toString()); hmBuiltNodes.remove(node.id); } @@ -252,21 +226,25 @@ public class TorEventHandler implements EventHandler, TorServiceConstants { }
+ }
+ private String parseNodeName(String node) { + if (node.indexOf('=') != -1) { + return (node.substring(node.indexOf("=") + 1)); + } else if (node.indexOf('~') != -1) { + return (node.substring(node.indexOf("~") + 1)); + } else + return node; }
+ public class Node { + public String status; + public String id; + public String name; + public String ipAddress; + public String country; + public String organization;
- private String parseNodeName(String node) - { - if (node.indexOf('=')!=-1) - { - return (node.substring(node.indexOf("=")+1)); - } - else if (node.indexOf('~')!=-1) - { - return (node.substring(node.indexOf("~")+1)); - } - else - return node; + public boolean isFetchingInfo = false; } } 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 dfd5a5f0..f1769687 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java +++ b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java @@ -7,7 +7,6 @@ import android.content.Intent;
public interface TorServiceConstants {
- String DIRECTORY_TOR_DATA = "tordata";
String TOR_CONTROL_PORT_FILE = "control.txt"; diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java b/orbotservice/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java index 50dc2825..6504b8c7 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/CustomNativeLoader.java @@ -74,16 +74,14 @@ public class CustomNativeLoader { try {
- File fileNativeBin = new File(getNativeLibraryDir(context),libname + ".so"); + File fileNativeBin = new File(getNativeLibraryDir(context), libname + ".so"); if (!fileNativeBin.exists()) - fileNativeBin = new File(getNativeLibraryDir(context),"lib" + libname + ".so"); + fileNativeBin = new File(getNativeLibraryDir(context), "lib" + libname + ".so");
- if (fileNativeBin.exists()) - { + if (fileNativeBin.exists()) { if (fileNativeBin.canExecute()) return fileNativeBin; - else - { + else { setExecutable(fileNativeBin);
if (fileNativeBin.canExecute()) 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 8007d047..bddfab2c 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 @@ -3,6 +3,7 @@ package org.torproject.android.service.util; 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; @@ -18,7 +19,7 @@ public class CustomShell extends Shell {
@WorkerThread - public static CommandResult run(@NonNull String shell, boolean waitFor, @Nullable Map<String,String> env, @NonNull String command) { + public static CommandResult run(@NonNull String shell, boolean waitFor, @Nullable Map<String, String> env, @NonNull String command) { List<String> stdout = Collections.synchronizedList(new ArrayList<String>()); List<String> stderr = Collections.synchronizedList(new ArrayList<String>()); int exitCode = -1; @@ -56,17 +57,17 @@ public class CustomShell extends Shell { // make sure our threads are done gobbling, our streams are closed, and the process is destroyed - while the // latter two shouldn't be needed in theory, and may even produce warnings, in "normal" Java they are required // for guaranteed cleanup of resources, so lets be safe and do this on Android as well - /** - try { - stdin.close(); - } catch (IOException e) { - // might be closed already - }**/ - - if (waitFor) { - stdoutGobbler.join(); - stderrGobbler.join(); - } + /** + try { + stdin.close(); + } catch (IOException e) { + // might be closed already + }**/ + + if (waitFor) { + stdoutGobbler.join(); + stderrGobbler.join(); + }
} catch (InterruptedException e) { exitCode = ShellExitCode.WATCHDOG_EXIT; diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java b/orbotservice/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java index 3c4c1fc3..8bec9ccc 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/CustomTorResourceInstaller.java @@ -3,6 +3,7 @@ package org.torproject.android.service.util; import android.content.Context; import android.content.pm.ApplicationInfo; import android.util.Log; + import org.torproject.android.binary.TorServiceConstants;
import java.io.File; @@ -24,20 +25,86 @@ public class CustomTorResourceInstaller implements TorServiceConstants { private File fileTorrc; private File fileTor;
- public CustomTorResourceInstaller (Context context, File installFolder) - { + public CustomTorResourceInstaller(Context context, File installFolder) { this.installFolder = installFolder; this.context = context; }
+ // Return Full path to the directory where native JNI libraries are stored. + private static String getNativeLibraryDir(Context context) { + ApplicationInfo appInfo = context.getApplicationInfo(); + return appInfo.nativeLibraryDir; + } + + /* + * Write the inputstream contents to the file + */ + private static boolean streamToFile(InputStream stm, File outFile, boolean append, boolean zip) throws IOException { + byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE]; + + int bytecount; + + OutputStream stmOut = new FileOutputStream(outFile.getAbsolutePath(), append); + ZipInputStream zis = null; + + if (zip) { + zis = new ZipInputStream(stm); + ZipEntry ze = zis.getNextEntry(); + stm = zis; + + } + + while ((bytecount = stm.read(buffer)) > 0) { + + stmOut.write(buffer, 0, bytecount); + + } + + stmOut.close(); + stm.close(); + + if (zis != null) + zis.close(); + + + return true; + + } + + + + + /* + * Extract the Tor binary from the APK file using ZIP + */ + + private static File[] listf(String directoryName) { + + // .............list file + File directory = new File(directoryName); + + // get all the files from a directory + File[] fList = directory.listFiles(); + + if (fList != null) + for (File file : fList) { + if (file.isFile()) { + Log.d(TAG, file.getAbsolutePath()); + } else if (file.isDirectory()) { + listf(file.getAbsolutePath()); + } + } + + return fList; + } + // /* * Extract the Tor resources from the APK file using ZIP * * @File path to the Tor executable */ - public File installResources () throws IOException, TimeoutException - { + public File installResources() throws IOException, TimeoutException {
fileTor = new File(installFolder, TOR_ASSET_KEY);
@@ -48,14 +115,12 @@ public class CustomTorResourceInstaller implements TorServiceConstants { fileTorrc = assetToFile(COMMON_ASSET_KEY + TORRC_ASSET_KEY, TORRC_ASSET_KEY, false, false);
File fileNativeDir = new File(getNativeLibraryDir(context)); - fileTor = new File(fileNativeDir,TOR_ASSET_KEY + ".so"); + fileTor = new File(fileNativeDir, TOR_ASSET_KEY + ".so");
- if (fileTor.exists()) - { + if (fileTor.exists()) { if (fileTor.canExecute()) return fileTor; - else - { + else { setExecutable(fileTor);
if (fileTor.canExecute()) @@ -76,7 +141,7 @@ public class CustomTorResourceInstaller implements TorServiceConstants { }
//let's try another approach - fileTor = CustomNativeLoader.loadNativeBinary(context,TOR_ASSET_KEY,fileTorBin); + fileTor = CustomNativeLoader.loadNativeBinary(context, TOR_ASSET_KEY, fileTorBin);
if (fileTor != null && fileTor.exists()) setExecutable(fileTor); @@ -87,22 +152,7 @@ public class CustomTorResourceInstaller implements TorServiceConstants { return null; }
- - // Return Full path to the directory where native JNI libraries are stored. - private static String getNativeLibraryDir(Context context) { - ApplicationInfo appInfo = context.getApplicationInfo(); - return appInfo.nativeLibraryDir; - } - - - - - /* - * Extract the Tor binary from the APK file using ZIP - */ - - private boolean installGeoIP () throws IOException - { + private boolean installGeoIP() throws IOException {
assetToFile(COMMON_ASSET_KEY + GEOIP_ASSET_KEY, GEOIP_ASSET_KEY, false, false);
@@ -124,73 +174,11 @@ public class CustomTorResourceInstaller implements TorServiceConstants { return outFile; }
- - /* - * Write the inputstream contents to the file - */ - private static boolean streamToFile(InputStream stm, File outFile, boolean append, boolean zip) throws IOException - - { - byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE]; - - int bytecount; - - OutputStream stmOut = new FileOutputStream(outFile.getAbsolutePath(), append); - ZipInputStream zis = null; - - if (zip) - { - zis = new ZipInputStream(stm); - ZipEntry ze = zis.getNextEntry(); - stm = zis; - - } - - while ((bytecount = stm.read(buffer)) > 0) - { - - stmOut.write(buffer, 0, bytecount); - - } - - stmOut.close(); - stm.close(); - - if (zis != null) - zis.close(); - - - return true; - - } - - - private void setExecutable(File fileBin) { fileBin.setReadable(true); fileBin.setExecutable(true); fileBin.setWritable(false); fileBin.setWritable(true, true); } - - private static File[] listf(String directoryName) { - - // .............list file - File directory = new File(directoryName); - - // get all the files from a directory - File[] fList = directory.listFiles(); - - if (fList != null) - for (File file : fList) { - if (file.isFile()) { - Log.d(TAG,file.getAbsolutePath()); - } else if (file.isDirectory()) { - listf(file.getAbsolutePath()); - } - } - - return fList; - } }
diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/DummyActivity.java b/orbotservice/src/main/java/org/torproject/android/service/util/DummyActivity.java index 20804b95..c818c96f 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/DummyActivity.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/DummyActivity.java @@ -7,9 +7,9 @@ import android.os.Bundle; * To combat background service being stopped/swiped */ public class DummyActivity extends Activity { - @Override - public void onCreate( Bundle icicle ) { - super.onCreate( icicle ); - finish(); - } + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + finish(); + } } \ No newline at end of file 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 index aa176b2c..745307d9 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java @@ -2,8 +2,8 @@ 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.OrbotService; +import org.torproject.android.service.TorEventHandler;
import java.io.BufferedReader; import java.io.InputStream; @@ -15,20 +15,18 @@ import java.net.URLConnection;
public class ExternalIPFetcher implements Runnable {
+ private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addres..."; private OrbotService mService; private TorEventHandler.Node mNode; - private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addres..."; private int mLocalHttpProxyPort = 8118;
- public ExternalIPFetcher (OrbotService service, TorEventHandler.Node node, int localProxyPort ) - { + public ExternalIPFetcher(OrbotService service, TorEventHandler.Node node, int localProxyPort) { mService = service; mNode = node; mLocalHttpProxyPort = localProxyPort; }
- public void run () - { + public void run() { try {
URLConnection conn = null; @@ -36,7 +34,7 @@ public class ExternalIPFetcher implements Runnable { 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.setRequestProperty("Connection", "Close"); conn.setConnectTimeout(60000); conn.setReadTimeout(60000);
@@ -49,15 +47,14 @@ public class ExternalIPFetcher implements Runnable { StringBuffer json = new StringBuffer(); String line = null;
- while ((line = reader.readLine())!=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) - { + 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"); @@ -80,16 +77,9 @@ public class ExternalIPFetcher implements Runnable { is.close();
- } catch (Exception e) {
- // mService.debug ("Error getting node details from onionoo: " + e.getMessage()); - - + // mService.debug ("Error getting node details from onionoo: " + e.getMessage()); } - - } - - } diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/NativeLoader.java b/orbotservice/src/main/java/org/torproject/android/service/util/NativeLoader.java index e79d4457..f97f68e0 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/NativeLoader.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/NativeLoader.java @@ -1,4 +1,3 @@ - package org.torproject.android.service.util;
import android.content.Context; @@ -25,19 +24,19 @@ public class NativeLoader { zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
/** - Enumeration<? extends ZipEntry> entries = zipFile.entries(); - while (entries.hasMoreElements()) - { - ZipEntry entry = entries.nextElement(); - Log.d("Zip","entry: " + entry.getName()); - } - **/ + Enumeration<? extends ZipEntry> entries = zipFile.entries(); + while (entries.hasMoreElements()) + { + ZipEntry entry = entries.nextElement(); + Log.d("Zip","entry: " + entry.getName()); + } + **/
ZipEntry entry = zipFile.getEntry("lib/" + folder + "/" + libName + ".so"); if (entry == null) { entry = zipFile.getEntry("lib/" + folder + "/" + libName); if (entry == null) - throw new Exception("Unable to find file in apk:" + "lib/" + folder + "/" + libName); + throw new Exception("Unable to find file in apk:" + "lib/" + folder + "/" + libName); } stream = zipFile.getInputStream(entry);
diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/PortForwarder.java b/orbotservice/src/main/java/org/torproject/android/service/util/PortForwarder.java index 052aeed0..26c3a3ff 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/PortForwarder.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/PortForwarder.java @@ -1,6 +1,7 @@ package org.torproject.android.service.util;
import android.util.Log; + import com.offbynull.portmapper.PortMapperFactory; import com.offbynull.portmapper.gateway.Bus; import com.offbynull.portmapper.gateway.Gateway; @@ -19,17 +20,14 @@ public class PortForwarder { private boolean shutdown = false; private Thread mThread = null;
- public void shutdown () - { + public void shutdown() { shutdown = true; }
- public void forward (final int internalPort, final int externalPort, final long lifetime) throws InterruptedException { + public void forward(final int internalPort, final int externalPort, final long lifetime) throws InterruptedException {
- mThread = new Thread () - { - public void run () - { + mThread = new Thread() { + public void run() { try { forwardSync(internalPort, externalPort, lifetime); } catch (InterruptedException e) { @@ -42,7 +40,7 @@ public class PortForwarder { }
- public void forwardSync (int internalPort, int externalPort, long lifetime) throws InterruptedException { + public void forwardSync(int internalPort, int externalPort, long lifetime) throws InterruptedException { // Start gateways Gateway network = NetworkGateway.create(); Gateway process = ProcessGateway.create(); @@ -59,13 +57,13 @@ public class PortForwarder { // (both internal and external ports). Be mindful of this when choosing which // ports you want to map. MappedPort mappedPort = mapper.mapPort(PortType.TCP, internalPort, externalPort, lifetime); - Log.d(getClass().getName(),"Port mapping added: " + mappedPort); + Log.d(getClass().getName(), "Port mapping added: " + mappedPort);
// Refresh mapping half-way through the lifetime of the mapping (for example, // if the mapping is available for 40 seconds, refresh it every 20 seconds) - while(!shutdown) { + while (!shutdown) { mappedPort = mapper.refreshPort(mappedPort, mappedPort.getLifetime() / 2L); - Log.d(getClass().getName(),"Port mapping refreshed: " + mappedPort); + Log.d(getClass().getName(), "Port mapping refreshed: " + mappedPort); Thread.sleep(mappedPort.getLifetime() * 1000L); }
diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/Prefs.java b/orbotservice/src/main/java/org/torproject/android/service/util/Prefs.java index 099e2677..cc4c9b98 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/Prefs.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/Prefs.java @@ -1,4 +1,3 @@ - package org.torproject.android.service.util;
import android.content.Context; diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/TCPSourceApp.java b/orbotservice/src/main/java/org/torproject/android/service/util/TCPSourceApp.java index 2985ae3d..1aa6445a 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/TCPSourceApp.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/TCPSourceApp.java @@ -49,71 +49,19 @@ import java.util.regex.Pattern;
/** * Main class for the TCPSourceApp library. - * @author Sebastiano Gottardo * + * @author Sebastiano Gottardo */ public class TCPSourceApp {
- /* - * This class represents an Android application. Each application is - * uniquely identified by its package name (e.g. com.megadevs.tcpsourceapp) - * and its version (e.g. 1.0). - */ - public static class AppDescriptor { - - private String packageName; - private String version; - private int uid; - - public AppDescriptor(int uid, String pName, String ver) { - this.uid = uid; - packageName = pName; - version = ver; - } - - public int getUid () { - return uid; - } - - public String getPackageName() { - return packageName; - } - - public String getVersion() { - return version; - } - - /* - * Override of the 'equals' method, in order to have a proper - * comparison between two AppDescriptor objects. - * - * (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object o) { - - if (o instanceof AppDescriptor) { - boolean c1 = ((AppDescriptor) o).packageName.compareTo(this.packageName) == 0; - boolean c2 = ((AppDescriptor) o).version.compareTo(this.version) == 0; - - return c1 && c2; - } - - return false; - } - - } - /* * In a Linux-based OS, each active TCP socket is mapped in the following * two files. A socket may be mapped in the '/proc/net/tcp' file in case * of a simple IPv4 address, or in the '/proc/net/tcp6' if an IPv6 address * is available. */ - private static final String TCP_4_FILE_PATH = "/proc/net/tcp"; - private static final String TCP_6_FILE_PATH = "/proc/net/tcp6"; - + private static final String TCP_4_FILE_PATH = "/proc/net/tcp"; + private static final String TCP_6_FILE_PATH = "/proc/net/tcp6"; /* * Two regular expressions that are able to extract valuable informations * from the two /proc/net/tcp* files. More specifically, there are three @@ -122,24 +70,20 @@ public class TCPSourceApp { * - port * - PID */ - private static final String TCP_6_PATTERN = "\d+:\s([0-9A-F]{32}):([0-9A-F]{4})\s[0-9A-F]{32}:[0-9A-F]{4}\s[0-9A-F]{2}\s[0-9]{8}:[0-9]{8}\s[0-9]{2}:[0-9]{8}\s[0-9]{8}\s+([0-9]+)"; + private static final String TCP_6_PATTERN = "\d+:\s([0-9A-F]{32}):([0-9A-F]{4})\s[0-9A-F]{32}:[0-9A-F]{4}\s[0-9A-F]{2}\s[0-9]{8}:[0-9]{8}\s[0-9]{2}:[0-9]{8}\s[0-9]{8}\s+([0-9]+)"; + private static final String TCP_4_PATTERN = "\d+:\s([0-9A-F]{8}):([0-9A-F]{4})\s[0-9A-F]{8}:[0-9A-F]{4}\s[0-9A-F]{2}\s[0-9A-F]{8}:[0-9A-F]{8}\s[0-9]{2}:[0-9]{8}\s[0-9A-F]{8}\s+([0-9]+)"; //sargo:/ $ cat /proc/net/tcp6 // sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode // 0: 00000000000000000000000000000000:C36A 00000000000000000000000000000000:0000 8A 00000000:00000000 00:00000000 00000000 1001 0 35059 1 0000000000000000 99 0 0 10 0 // 1: 00000000000000000000000000000000:A64B 00000000000000000000000000000000:0000 8A 00000000:00000000 00:00000000 00000000 1001 0 910009 1 0000000000000000 99 0 0 10 0 - - - private static final String TCP_4_PATTERN = "\d+:\s([0-9A-F]{8}):([0-9A-F]{4})\s[0-9A-F]{8}:[0-9A-F]{4}\s[0-9A-F]{2}\s[0-9A-F]{8}:[0-9A-F]{8}\s[0-9]{2}:[0-9]{8}\s[0-9A-F]{8}\s+([0-9]+)"; -// sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode -// 0: 00000000:C368 00000000:0000 8A 00000000:00000000 00:00000000 00000000 1001 0 34999 1 0000000000000000 99 0 0 10 0 - /* * Optimises the socket lookup by checking if the connected network * interface has a 'valid' IPv6 address (a global address, not a link-local * one). */ - private static boolean checkConnectedIfaces = true; - + private static boolean checkConnectedIfaces = true; +// sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode +// 0: 00000000:C368 00000000:0000 8A 00000000:00000000 00:00000000 00000000 1001 0 34999 1 0000000000000000 99 0 0 10 0
/** * The main method of the TCPSourceApp library. This method receives an @@ -150,8 +94,8 @@ public class TCPSourceApp { * find the originating application. * * @param context a valid Android Context instance - * @param daddr the (logical) address of the destination - * @param dport the (logical) port of the destination + * @param daddr the (logical) address of the destination + * @param dport the (logical) port of the destination * @return an AppDescriptor object, representing the found application; null * if no application could be found */ @@ -192,8 +136,8 @@ public class TCPSourceApp { if (hasIPv6) while (m6.find()) { String addressEntry = m6.group(1); - String portEntry = m6.group(2); - int pidEntry = Integer.valueOf(m6.group(3)); + String portEntry = m6.group(2); + int pidEntry = Integer.valueOf(m6.group(3));
if (Integer.parseInt(portEntry, 16) == dport) { PackageManager manager = context.getPackageManager(); @@ -240,8 +184,8 @@ public class TCPSourceApp {
while (m4.find()) { String addressEntry = m4.group(1); - String portEntry = m4.group(2); - int pidEntry = Integer.valueOf(m4.group(3)); + String portEntry = m4.group(2); + int pidEntry = Integer.valueOf(m4.group(3));
if (Integer.parseInt(portEntry, 16) == dport) { PackageManager manager = context.getPackageManager(); @@ -312,4 +256,55 @@ public class TCPSourceApp { checkConnectedIfaces = value; }
+ /* + * This class represents an Android application. Each application is + * uniquely identified by its package name (e.g. com.megadevs.tcpsourceapp) + * and its version (e.g. 1.0). + */ + public static class AppDescriptor { + + private String packageName; + private String version; + private int uid; + + public AppDescriptor(int uid, String pName, String ver) { + this.uid = uid; + packageName = pName; + version = ver; + } + + public int getUid() { + return uid; + } + + public String getPackageName() { + return packageName; + } + + public String getVersion() { + return version; + } + + /* + * Override of the 'equals' method, in order to have a proper + * comparison between two AppDescriptor objects. + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object o) { + + if (o instanceof AppDescriptor) { + boolean c1 = ((AppDescriptor) o).packageName.compareTo(this.packageName) == 0; + boolean c2 = ((AppDescriptor) o).version.compareTo(this.version) == 0; + + return c1 && c2; + } + + return false; + } + + } + } \ No newline at end of file diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/TorServiceUtils.java b/orbotservice/src/main/java/org/torproject/android/service/util/TorServiceUtils.java index 2efe5a9f..ebc829a0 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/TorServiceUtils.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/TorServiceUtils.java @@ -16,14 +16,10 @@ public class TorServiceUtils implements TorServiceConstants { socket.connect(new InetSocketAddress(ip, port), timeout); socket.close(); return true; - } - - catch(ConnectException ce){ + } catch (ConnectException ce) { //ce.printStackTrace(); return false; - } - - catch (Exception ex) { + } catch (Exception ex) { //ex.printStackTrace(); return false; } diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/Utils.java b/orbotservice/src/main/java/org/torproject/android/service/util/Utils.java index e6e203e3..64d912c1 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/util/Utils.java +++ b/orbotservice/src/main/java/org/torproject/android/service/util/Utils.java @@ -21,170 +21,164 @@ import java.util.zip.ZipOutputStream; public class Utils {
- public static String readString (InputStream stream) - { - String line = null; - - StringBuffer out = new StringBuffer(); - - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - - while ((line = reader.readLine()) != null) - { - out.append(line); - out.append('\n'); - - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return out.toString(); - - } - /* - * Load the log file text - */ - public static String loadTextFile (String path) - { - String line = null; - - StringBuffer out = new StringBuffer(); - - try { - BufferedReader reader = new BufferedReader((new FileReader(new File(path)))); - - while ((line = reader.readLine()) != null) - { - out.append(line); - out.append('\n'); - - } - - reader.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return out.toString(); - - } - - - /* - * Load the log file text - */ - public static boolean saveTextFile (String path, String contents) - { - - try { - - FileWriter writer = new FileWriter( path, false ); - writer.write( contents ); - - writer.close(); - - - - return true; - - } catch (IOException e) { - // Log.d(TAG, "error writing file: " + path, e); - e.printStackTrace(); - return false; - } - - - - } - - - /* - * - * Zips a file at a location and places the resulting zip file at the toLocation - * Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip"); - */ - - public static boolean zipFileAtPath(String sourcePath, String toLocation) { - final int BUFFER = 2048; - - File sourceFile = new File(sourcePath); - try { - BufferedInputStream origin = null; - FileOutputStream dest = new FileOutputStream(toLocation); - ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream( - dest)); - if (sourceFile.isDirectory()) { - zipSubFolder(out, sourceFile, sourceFile.getParent().length()); - } else { - byte data[] = new byte[BUFFER]; - FileInputStream fi = new FileInputStream(sourcePath); - origin = new BufferedInputStream(fi, BUFFER); - ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath)); - entry.setTime(sourceFile.lastModified()); // to keep modification time after unzipping - out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - } - } - out.close(); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - return true; - } - - /* - * - * Zips a subfolder - * - */ - - private static void zipSubFolder(ZipOutputStream out, File folder, - int basePathLength) throws IOException { - - final int BUFFER = 2048; - - File[] fileList = folder.listFiles(); - BufferedInputStream origin = null; - for (File file : fileList) { - if (file.isDirectory()) { - zipSubFolder(out, file, basePathLength); - } else { - byte data[] = new byte[BUFFER]; - String unmodifiedFilePath = file.getPath(); - String relativePath = unmodifiedFilePath - .substring(basePathLength); - FileInputStream fi = new FileInputStream(unmodifiedFilePath); - origin = new BufferedInputStream(fi, BUFFER); - ZipEntry entry = new ZipEntry(relativePath); - entry.setTime(file.lastModified()); // to keep modification time after unzipping - out.putNextEntry(entry); - int count; - while ((count = origin.read(data, 0, BUFFER)) != -1) { - out.write(data, 0, count); - } - origin.close(); - } - } - } - - /* - * gets the last path component - * - * Example: getLastPathComponent("downloads/example/fileToZip"); - * Result: "fileToZip" - */ - public static String getLastPathComponent(String filePath) { - String[] segments = filePath.split("/"); - if (segments.length == 0) - return ""; - String lastPathComponent = segments[segments.length - 1]; - return lastPathComponent; - } + public static String readString(InputStream stream) { + String line; + + StringBuffer out = new StringBuffer(); + + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + + while ((line = reader.readLine()) != null) { + out.append(line); + out.append('\n'); + + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return out.toString(); + + } + + /* + * Load the log file text + */ + public static String loadTextFile(String path) { + String line = null; + + StringBuffer out = new StringBuffer(); + + try { + BufferedReader reader = new BufferedReader((new FileReader(new File(path)))); + + while ((line = reader.readLine()) != null) { + out.append(line); + out.append('\n'); + + } + + reader.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return out.toString(); + + } + + + /* + * Load the log file text + */ + public static boolean saveTextFile(String path, String contents) { + + try { + + FileWriter writer = new FileWriter(path, false); + writer.write(contents); + + writer.close(); + + + return true; + + } catch (IOException e) { + // Log.d(TAG, "error writing file: " + path, e); + e.printStackTrace(); + return false; + } + + + } + + + /* + * + * Zips a file at a location and places the resulting zip file at the toLocation + * Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip"); + */ + + public static boolean zipFileAtPath(String sourcePath, String toLocation) { + final int BUFFER = 2048; + + File sourceFile = new File(sourcePath); + try { + BufferedInputStream origin = null; + FileOutputStream dest = new FileOutputStream(toLocation); + ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream( + dest)); + if (sourceFile.isDirectory()) { + zipSubFolder(out, sourceFile, sourceFile.getParent().length()); + } else { + byte data[] = new byte[BUFFER]; + FileInputStream fi = new FileInputStream(sourcePath); + origin = new BufferedInputStream(fi, BUFFER); + ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath)); + entry.setTime(sourceFile.lastModified()); // to keep modification time after unzipping + out.putNextEntry(entry); + int count; + while ((count = origin.read(data, 0, BUFFER)) != -1) { + out.write(data, 0, count); + } + } + out.close(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + /* + * + * Zips a subfolder + * + */ + + private static void zipSubFolder(ZipOutputStream out, File folder, + int basePathLength) throws IOException { + + final int BUFFER = 2048; + + File[] fileList = folder.listFiles(); + BufferedInputStream origin; + for (File file : fileList) { + if (file.isDirectory()) { + zipSubFolder(out, file, basePathLength); + } else { + byte data[] = new byte[BUFFER]; + String unmodifiedFilePath = file.getPath(); + String relativePath = unmodifiedFilePath + .substring(basePathLength); + FileInputStream fi = new FileInputStream(unmodifiedFilePath); + origin = new BufferedInputStream(fi, BUFFER); + ZipEntry entry = new ZipEntry(relativePath); + entry.setTime(file.lastModified()); // to keep modification time after unzipping + out.putNextEntry(entry); + int count; + while ((count = origin.read(data, 0, BUFFER)) != -1) { + out.write(data, 0, count); + } + origin.close(); + } + } + } + + /* + * gets the last path component + * + * Example: getLastPathComponent("downloads/example/fileToZip"); + * Result: "fileToZip" + */ + public static String getLastPathComponent(String filePath) { + String[] segments = filePath.split("/"); + if (segments.length == 0) + return ""; + String lastPathComponent = segments[segments.length - 1]; + return lastPathComponent; + } } 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 ea27af99..12c4162f 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 @@ -30,6 +30,7 @@ import android.os.ParcelFileDescriptor; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; + import com.runjva.sourceforge.jsocks.protocol.ProxyServer; import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
@@ -60,167 +61,174 @@ import static org.torproject.android.service.TorServiceConstants.ACTION_STOP_VPN
public class OrbotVpnManager implements Handler.Callback { private static final String TAG = "OrbotVpnService"; - + private final static int VPN_MTU = 1500; + private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + private final static String PDNSD_BIN = "pdnsd"; + public static int sSocksProxyServerPort = -1; + public static String sSocksProxyLocalhost = null; + boolean isStarted = false; + File filePdnsPid; private Thread mThreadVPN; - private String mSessionName = "OrbotVPN"; private ParcelFileDescriptor mInterface; - private int mTorSocks = -1; - private int mTorDns = -1; - private int pdnsdPort = 8091; - - public static int sSocksProxyServerPort = -1; - public static String sSocksProxyLocalhost = null; + private int mTorDns = -1; + private int pdnsdPort = 8091; private ProxyServer mSocksProxyServer; + private File filePdnsd; + private boolean isRestart = false; + private VpnService mService;
- private final static int VPN_MTU = 1500; - - private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + public OrbotVpnManager(VpnService service) throws IOException, TimeoutException { + mService = service; + filePdnsd = CustomNativeLoader.loadNativeBinary(service.getApplicationContext(), PDNSD_BIN, new File(service.getFilesDir(), PDNSD_BIN)); + Tun2Socks.init(); + }
- private File filePdnsd; + 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);
- private final static String PDNSD_BIN = "pdnsd"; + Log.d(TAG, "pdsnd conf:" + conf); + + File fPid = new File(fileDir, pdnsdPort + "pdnsd.conf"); + + if (fPid.exists()) { + fPid.delete(); + } + + FileOutputStream fos = new FileOutputStream(fPid, false); + PrintStream ps = new PrintStream(fos); + ps.print(conf); + ps.close(); + + File cache = new File(fileDir, "pdnsd.cache"); + + if (!cache.exists()) { + try { + cache.createNewFile(); + } catch (Exception e) { + } + } + return fPid; + }
- private boolean isRestart = false; - - private VpnService mService; - - public OrbotVpnManager (VpnService service) throws IOException, TimeoutException { - mService = service; - filePdnsd = CustomNativeLoader.loadNativeBinary(service.getApplicationContext(),PDNSD_BIN,new File(service.getFilesDir(),PDNSD_BIN)); - Tun2Socks.init(); - } - - boolean isStarted = false; - public int handleIntent(VpnService.Builder builder, Intent intent) { - if (intent != null) { - String action = intent.getAction(); + if (intent != null) { + String action = intent.getAction();
- if (!TextUtils.isEmpty(action)) { - if (action.equals(ACTION_START_VPN) || action.equals(ACTION_START)) { - Log.d(TAG, "starting VPN"); + if (!TextUtils.isEmpty(action)) { + if (action.equals(ACTION_START_VPN) || action.equals(ACTION_START)) { + Log.d(TAG, "starting VPN");
- isStarted = true; + isStarted = true;
- // Stop the previous session by interrupting the thread. - if (mThreadVPN != null && mThreadVPN.isAlive()) - stopVPN(); + // Stop the previous session by interrupting the thread. + if (mThreadVPN != null && mThreadVPN.isAlive()) + stopVPN();
- if (mTorSocks != -1) { - if (!mIsLollipop) { - startSocksBypass(); - } + if (mTorSocks != -1) { + if (!mIsLollipop) { + startSocksBypass(); + }
- setupTun2Socks(builder); - } + setupTun2Socks(builder); + }
- } else if (action.equals(ACTION_STOP_VPN)) { - isStarted = false; + } else if (action.equals(ACTION_STOP_VPN)) { + isStarted = false;
- Log.d(TAG, "stopping VPN"); + Log.d(TAG, "stopping VPN");
- stopVPN(); - } else if (action.equals(TorServiceConstants.LOCAL_ACTION_PORTS)) { - Log.d(TAG, "setting VPN ports"); + stopVPN(); + } else if (action.equals(TorServiceConstants.LOCAL_ACTION_PORTS)) { + Log.d(TAG, "setting VPN ports");
- int torSocks = intent.getIntExtra(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1); - int torDns = intent.getIntExtra(OrbotService.EXTRA_DNS_PORT, -1); + int torSocks = intent.getIntExtra(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1); + int torDns = intent.getIntExtra(OrbotService.EXTRA_DNS_PORT, -1);
- //if running, we need to restart - if ((torSocks != mTorSocks || torDns != mTorDns)) { + //if running, we need to restart + if ((torSocks != mTorSocks || torDns != mTorDns)) {
- mTorSocks = torSocks; - mTorDns = torDns; + mTorSocks = torSocks; + mTorDns = torDns;
- if (!mIsLollipop) { - stopSocksBypass(); - startSocksBypass(); - } + if (!mIsLollipop) { + stopSocksBypass(); + startSocksBypass(); + } + + setupTun2Socks(builder); + } + } + } + + }
- setupTun2Socks(builder); - } - } - }
- } - - return Service.START_STICKY; } - + private void startSocksBypass() { - new Thread () { - public void run () { - - //generate the proxy port that the - if (sSocksProxyServerPort == -1) - { - try { - - sSocksProxyLocalhost = "127.0.0.1";// InetAddress.getLocalHost().getHostAddress(); - sSocksProxyServerPort = (int)((Math.random()*1000)+10000); - - } catch (Exception e) { - Log.e(TAG,"Unable to access localhost",e); - throw new RuntimeException("Unable to access localhost: " + e); - - } - + new Thread() { + public void run() { + + //generate the proxy port that the + if (sSocksProxyServerPort == -1) { + try { + + sSocksProxyLocalhost = "127.0.0.1";// InetAddress.getLocalHost().getHostAddress(); + sSocksProxyServerPort = (int) ((Math.random() * 1000) + 10000); + + } catch (Exception e) { + Log.e(TAG, "Unable to access localhost", e); + throw new RuntimeException("Unable to access localhost: " + e); + + } + } - - - if (mSocksProxyServer != null) - { - stopSocksBypass (); - } - - try - { - mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null)); - ProxyServer.setVpnService(mService); - mSocksProxyServer.start(sSocksProxyServerPort, 5, InetAddress.getLocalHost()); - - } - catch (Exception e) - { - Log.e(TAG,"error getting host",e); - } - } - }.start(); + + + if (mSocksProxyServer != null) { + stopSocksBypass(); + } + + try { + mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null)); + ProxyServer.setVpnService(mService); + mSocksProxyServer.start(sSocksProxyServerPort, 5, InetAddress.getLocalHost()); + + } catch (Exception e) { + Log.e(TAG, "error getting host", e); + } + } + }.start(); }
- private synchronized void stopSocksBypass () { + private synchronized void stopSocksBypass() { if (mSocksProxyServer != null) { mSocksProxyServer.stop(); mSocksProxyServer = null; } }
- private void stopVPN () { - if (mIsLollipop) - stopSocksBypass (); + private void stopVPN() { + if (mIsLollipop) + stopSocksBypass();
- Tun2Socks.Stop(); + Tun2Socks.Stop();
- if (mInterface != null){ - try - { - Log.d(TAG,"closing interface, destroying VPN interface"); - - mInterface.close(); - mInterface = null; - - } - catch (Exception e) - { - Log.d(TAG,"error stopping tun2socks",e); + if (mInterface != null) { + try { + Log.d(TAG, "closing interface, destroying VPN interface"); + + mInterface.close(); + mInterface = null; + + } catch (Exception e) { + Log.d(TAG, "error stopping tun2socks", e); + } catch (Error e) { + Log.d(TAG, "error stopping tun2socks", e); } - catch (Error e) - { - Log.d(TAG,"error stopping tun2socks",e); - } } stopDns(); mThreadVPN = null; @@ -234,195 +242,161 @@ public class OrbotVpnManager implements Handler.Callback { return true; }
- - private synchronized void setupTun2Socks(final VpnService.Builder builder) { + private synchronized void setupTun2Socks(final VpnService.Builder builder) { if (mInterface != null) //stop tun2socks now to give it time to clean up { - isRestart = true; - Tun2Socks.Stop(); + isRestart = true; + Tun2Socks.Stop();
- stopDns(); + stopDns();
}
- mThreadVPN = new Thread () - { - - public void run () { - try { - - if (isRestart) { - Log.d(TAG,"is a restart... let's wait for a few seconds"); - Thread.sleep(3000); - } - - final String vpnName = "OrbotVPN"; - final String localhost = "127.0.0.1"; - - final String virtualGateway = "192.168.200.1"; - final String virtualIP = "192.168.200.2"; - final String virtualNetMask = "255.255.255.0"; - final String dummyDNS = "1.1.1.1"; //this is intercepted by the tun2socks library, but we must put in a valid DNS to start - final String defaultRoute = "0.0.0.0"; - - final String localSocks = localhost + ':' + mTorSocks; - - builder.setMtu(VPN_MTU); - builder.addAddress(virtualGateway,32); - - 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); - - //handle ipv6 - //builder.addAddress("fdfe:dcba:9876::1", 126); - //builder.addRoute("::", 0); - - if (mIsLollipop) - doLollipopAppRouting(builder); - - // Create a new interface using the builder and save the parameters. - ParcelFileDescriptor newInterface = builder.setSession(mSessionName) - .setConfigureIntent(null) // previously this was set to a null member variable - .establish(); - - if (mInterface != null) - { - Log.d(TAG,"Stopping existing VPN interface"); - mInterface.close(); - mInterface = null; - } - - mInterface = newInterface; - - isRestart = false; - - //start PDNSD daemon pointing to actual DNS - if (filePdnsd != null) { - - pdnsdPort++; - 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) - { - Log.d(TAG,"tun2Socks has stopped",e); - } - } - - }; - - mThreadVPN.start(); - + mThreadVPN = new Thread() { + + public void run() { + try { + + if (isRestart) { + Log.d(TAG, "is a restart... let's wait for a few seconds"); + Thread.sleep(3000); + } + + final String vpnName = "OrbotVPN"; + final String localhost = "127.0.0.1"; + + final String virtualGateway = "192.168.200.1"; + final String virtualIP = "192.168.200.2"; + final String virtualNetMask = "255.255.255.0"; + final String dummyDNS = "1.1.1.1"; //this is intercepted by the tun2socks library, but we must put in a valid DNS to start + final String defaultRoute = "0.0.0.0"; + + final String localSocks = localhost + ':' + mTorSocks; + + builder.setMtu(VPN_MTU); + builder.addAddress(virtualGateway, 32); + + 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); + + //handle ipv6 + //builder.addAddress("fdfe:dcba:9876::1", 126); + //builder.addRoute("::", 0); + + if (mIsLollipop) + doLollipopAppRouting(builder); + + // Create a new interface using the builder and save the parameters. + ParcelFileDescriptor newInterface = builder.setSession(mSessionName) + .setConfigureIntent(null) // previously this was set to a null member variable + .establish(); + + if (mInterface != null) { + Log.d(TAG, "Stopping existing VPN interface"); + mInterface.close(); + mInterface = null; + } + + mInterface = newInterface; + + isRestart = false; + + //start PDNSD daemon pointing to actual DNS + if (filePdnsd != null) { + + pdnsdPort++; + 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) { + Log.d(TAG, "tun2Socks has stopped", e); + } + } + + }; + + mThreadVPN.start(); + } - - + @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void doLollipopAppRouting (VpnService.Builder builder) throws NameNotFoundException { - SharedPreferences prefs = Prefs.getSharedPrefs(mService.getApplicationContext()); + private void doLollipopAppRouting(VpnService.Builder builder) throws NameNotFoundException { + SharedPreferences prefs = Prefs.getSharedPrefs(mService.getApplicationContext()); ArrayList<TorifiedApp> apps = TorifiedApp.getApps(mService, prefs);
- boolean perAppEnabled = false; - - for (TorifiedApp app : apps) - { - if (app.isTorified() && (!app.getPackageName().equals(mService.getPackageName()))) - { - if (prefs.getBoolean(app.getPackageName() + OrbotConstants.APP_TOR_KEY,true)) { + boolean perAppEnabled = false;
- builder.addAllowedApplication(app.getPackageName()); + for (TorifiedApp app : apps) { + if (app.isTorified() && (!app.getPackageName().equals(mService.getPackageName()))) { + if (prefs.getBoolean(app.getPackageName() + OrbotConstants.APP_TOR_KEY, true)) {
- } + builder.addAllowedApplication(app.getPackageName());
- perAppEnabled = true; + } + + perAppEnabled = true;
- } + } } - + if (!perAppEnabled) - builder.addDisallowedApplication(mService.getPackageName()); - + builder.addDisallowedApplication(mService.getPackageName()); + } - - private void startDNS (String pdnsPath, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws IOException, TimeoutException {
- File fileConf = makePdnsdConf(mService, mService.getFilesDir(), torDnsHost, torDnsPort, pdnsdHost, pdnsdPort); + private void startDNS(String pdnsPath, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws IOException, TimeoutException { + + File fileConf = makePdnsdConf(mService, mService.getFilesDir(), torDnsHost, torDnsPort, pdnsdHost, pdnsdPort);
- String[] cmdString = {pdnsPath,"-c",fileConf.toString(),"-g","-v2"}; + String[] cmdString = {pdnsPath, "-c", fileConf.toString(), "-g", "-v2"}; ProcessBuilder pb = new ProcessBuilder(cmdString); pb.redirectErrorStream(true); - Process proc = pb.start(); - try { proc.waitFor();} catch (Exception e){} + Process proc = pb.start(); + try { + proc.waitFor(); + } catch (Exception e) { + }
- Log.i(TAG,"PDNSD: " + proc.exitValue()); + Log.i(TAG, "PDNSD: " + proc.exitValue());
- if (proc.exitValue() != 0) - { + 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); + while ((line = br.readLine()) != null) { + Log.d(TAG, "pdnsd: " + line); } }
- - } - - File filePdnsPid; - - private boolean stopDns () { - if (filePdnsPid != null && filePdnsPid.exists()) { - List<String> lines = null; - try { - lines = IOUtils.readLines(new FileReader(filePdnsPid)); - String dnsPid = lines.get(0); - VpnUtils.killProcess(dnsPid, ""); - filePdnsPid.delete(); - filePdnsPid = null; - } catch (Exception e) { - Log.e("OrbotVPN", "error killing dns process", e); - } - } - return false; - } - - 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 fPid = new File(fileDir,pdnsdPort + "pdnsd.conf");
- if (fPid.exists()) { - fPid.delete(); - } - - FileOutputStream fos = new FileOutputStream(fPid, false); - PrintStream ps = new PrintStream(fos); - ps.print(conf); - ps.close(); - - File cache = new File(fileDir,"pdnsd.cache"); + }
- if (!cache.exists()) { - try { - cache.createNewFile(); - } catch (Exception e) { } + private boolean stopDns() { + if (filePdnsPid != null && filePdnsPid.exists()) { + List<String> lines = null; + try { + lines = IOUtils.readLines(new FileReader(filePdnsPid)); + String dnsPid = lines.get(0); + VpnUtils.killProcess(dnsPid, ""); + filePdnsPid.delete(); + filePdnsPid = null; + } catch (Exception e) { + Log.e("OrbotVPN", "error killing dns process", e); + } } - return fPid; - } + return false; + }
- public boolean isStarted () { - return isStarted; - } + public boolean isStarted() { + return isStarted; + } } diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorifiedApp.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorifiedApp.java index db25fd00..11171831 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorifiedApp.java +++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorifiedApp.java @@ -19,243 +19,242 @@ import static org.torproject.android.service.vpn.VpnPrefs.PREFS_KEY_TORIFIED;
public class TorifiedApp implements Comparable {
- private boolean enabled; - private int uid; - private String username; - private String procname; - private String name; - private Drawable icon; - private String packageName; - - private boolean torified = false; - private boolean usesInternet = false; - - public boolean usesInternet() { - return usesInternet; - } - public void setUsesInternet(boolean usesInternet) { - this.usesInternet = usesInternet; - } - /** - * @return the torified - */ - public boolean isTorified() { - return torified; - } - /** - * @param torified the torified to set - */ - public void setTorified(boolean torified) { - this.torified = torified; - } - private int[] enabledPorts; - - /** - * @return the enabledPorts - */ - public int[] getEnabledPorts() { - return enabledPorts; - } - /** - * @param enabledPorts the enabledPorts to set - */ - public void setEnabledPorts(int[] enabledPorts) { - this.enabledPorts = enabledPorts; - } - /** - * @return the enabled - */ - public boolean isEnabled() { - return enabled; - } - /** - * @param enabled the enabled to set - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - /** - * @return the uid - */ - public int getUid() { - return uid; - } - /** - * @param uid the uid to set - */ - public void setUid(int uid) { - this.uid = uid; - } - /** - * @return the username - */ - public String getUsername() { - return username; - } - /** - * @param username the username to set - */ - public void setUsername(String username) { - this.username = username; - } - /** - * @return the procname - */ - public String getProcname() { - return procname; - } - /** - * @param procname the procname to set - */ - public void setProcname(String procname) { - this.procname = procname; - } - /** - * @return the name - */ - public String getName() { - return name; - } - /** - * @param name the name to set - */ - public void setName(String name) { - this.name = name; - } - - - public Drawable getIcon() { - return icon; - } - - public void setIcon(Drawable icon) { - this.icon = icon; - } - - @Override - public int compareTo(Object another) { - return this.toString().compareToIgnoreCase(another.toString()); - } - - @Override - public String toString () - { - return getName(); - } - - - public String getPackageName() { - return packageName; - } - public void setPackageName(String packageName) { - this.packageName = packageName; - } - - public static ArrayList<TorifiedApp> getApps (Context context, SharedPreferences prefs) - { - - String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, ""); - String[] tordApps; - - StringTokenizer st = new StringTokenizer(tordAppString,"|"); - tordApps = new String[st.countTokens()]; - int tordIdx = 0; - while (st.hasMoreTokens()) - { - tordApps[tordIdx++] = st.nextToken(); - } - - Arrays.sort(tordApps); - - //else load the apps up - PackageManager pMgr = context.getPackageManager(); - - List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0); - - Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator(); - - ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>(); - - ApplicationInfo aInfo = null; - - int appIdx = 0; - TorifiedApp app = null; - - while (itAppInfo.hasNext()) - { - aInfo = itAppInfo.next(); - - app = new TorifiedApp(); - - try { - PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS); - - if (pInfo != null && pInfo.requestedPermissions != null) - { - for (String permInfo:pInfo.requestedPermissions) - { - if (permInfo.equals(Manifest.permission.INTERNET)) - { - app.setUsesInternet(true); - - } - } - - } - - - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) - { - //System app - app.setUsesInternet(true); - } - - - if (!app.usesInternet()) - continue; - else - { - apps.add(app); - } - - - app.setEnabled(aInfo.enabled); - app.setUid(aInfo.uid); - app.setUsername(pMgr.getNameForUid(app.getUid())); - app.setProcname(aInfo.processName); - app.setPackageName(aInfo.packageName); - - try - { - app.setName(pMgr.getApplicationLabel(aInfo).toString()); - } - catch (Exception e) - { - app.setName(aInfo.packageName); - } + private boolean enabled; + private int uid; + private String username; + private String procname; + private String name; + private Drawable icon; + private String packageName;
+ private boolean torified = false; + private boolean usesInternet = false; + private int[] enabledPorts;
- //app.setIcon(pMgr.getApplicationIcon(aInfo)); + public static ArrayList<TorifiedApp> getApps(Context context, SharedPreferences prefs) {
- // check if this application is allowed - if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) { - app.setTorified(true); - } - else - { - app.setTorified(false); - } + String tordAppString = prefs.getString(PREFS_KEY_TORIFIED, ""); + String[] tordApps;
- appIdx++; - } + StringTokenizer st = new StringTokenizer(tordAppString, "|"); + tordApps = new String[st.countTokens()]; + int tordIdx = 0; + while (st.hasMoreTokens()) { + tordApps[tordIdx++] = st.nextToken(); + }
- Collections.sort(apps); + Arrays.sort(tordApps);
- return apps; - } + //else load the apps up + PackageManager pMgr = context.getPackageManager(); + + List<ApplicationInfo> lAppInfo = pMgr.getInstalledApplications(0); + + Iterator<ApplicationInfo> itAppInfo = lAppInfo.iterator(); + + ArrayList<TorifiedApp> apps = new ArrayList<TorifiedApp>(); + + ApplicationInfo aInfo = null; + + int appIdx = 0; + TorifiedApp app = null; + + while (itAppInfo.hasNext()) { + aInfo = itAppInfo.next(); + + app = new TorifiedApp(); + + try { + PackageInfo pInfo = pMgr.getPackageInfo(aInfo.packageName, PackageManager.GET_PERMISSIONS); + + if (pInfo != null && pInfo.requestedPermissions != null) { + for (String permInfo : pInfo.requestedPermissions) { + if (permInfo.equals(Manifest.permission.INTERNET)) { + app.setUsesInternet(true); + + } + } + + } + + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) { + //System app + app.setUsesInternet(true); + } + + + if (!app.usesInternet()) + continue; + else { + apps.add(app); + } + + + app.setEnabled(aInfo.enabled); + app.setUid(aInfo.uid); + app.setUsername(pMgr.getNameForUid(app.getUid())); + app.setProcname(aInfo.processName); + app.setPackageName(aInfo.packageName); + + try { + app.setName(pMgr.getApplicationLabel(aInfo).toString()); + } catch (Exception e) { + app.setName(aInfo.packageName); + } + + + //app.setIcon(pMgr.getApplicationIcon(aInfo)); + + // check if this application is allowed + if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) { + app.setTorified(true); + } else { + app.setTorified(false); + } + + appIdx++; + } + + Collections.sort(apps); + + return apps; + } + + public boolean usesInternet() { + return usesInternet; + } + + public void setUsesInternet(boolean usesInternet) { + this.usesInternet = usesInternet; + } + + /** + * @return the torified + */ + public boolean isTorified() { + return torified; + } + + /** + * @param torified the torified to set + */ + public void setTorified(boolean torified) { + this.torified = torified; + } + + /** + * @return the enabledPorts + */ + public int[] getEnabledPorts() { + return enabledPorts; + } + + /** + * @param enabledPorts the enabledPorts to set + */ + public void setEnabledPorts(int[] enabledPorts) { + this.enabledPorts = enabledPorts; + } + + /** + * @return the enabled + */ + public boolean isEnabled() { + return enabled; + } + + /** + * @param enabled the enabled to set + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + /** + * @return the uid + */ + public int getUid() { + return uid; + } + + /** + * @param uid the uid to set + */ + public void setUid(int uid) { + this.uid = uid; + } + + /** + * @return the username + */ + public String getUsername() { + return username; + } + + /** + * @param username the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the procname + */ + public String getProcname() { + return procname; + } + + /** + * @param procname the procname to set + */ + public void setProcname(String procname) { + this.procname = procname; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + public Drawable getIcon() { + return icon; + } + + public void setIcon(Drawable icon) { + this.icon = icon; + } + + @Override + public int compareTo(Object another) { + return this.toString().compareToIgnoreCase(another.toString()); + } + + @Override + public String toString() { + return getName(); + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } } diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java index 11c6203e..d6910138 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java +++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/Tun2Socks.java @@ -8,12 +8,12 @@ package org.torproject.android.service.vpn; * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * @@ -25,6 +25,7 @@ import android.net.ConnectivityManager; import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.Log; + import org.torproject.android.service.util.TCPSourceApp;
import java.net.DatagramSocket; @@ -34,22 +35,12 @@ import java.util.HashMap;
import static android.content.Context.CONNECTIVITY_SERVICE;
-public class Tun2Socks -{ - - static{ - System.loadLibrary("tun2socks"); - } - - public static interface IProtectSocket - { - boolean doVpnProtect(Socket socket); - boolean doVpnProtect(DatagramSocket socket); - }; +public class Tun2Socks {
private static final String TAG = Tun2Socks.class.getSimpleName(); private static final boolean LOGD = true;
+ ; private static Thread mThread; private static ParcelFileDescriptor mVpnInterfaceFileDescriptor; private static int mVpnInterfaceMTU; @@ -58,15 +49,19 @@ public class Tun2Socks private static String mSocksServerAddress; private static String mUdpgwServerAddress; private static boolean mUdpgwTransparentDNS; - - private static HashMap<Integer,String> mAppUidBlacklist = new HashMap<>(); + private static HashMap<Integer, String> mAppUidBlacklist = new HashMap<>(); private static Context mContext; + + static { + System.loadLibrary("tun2socks"); + } + + public static void init() { + } // Note: this class isn't a singleton, but you can't run more // than one instance due to the use of global state (the lwip // module, etc.) in the native code.
- public static void init () {} - public static void Start( Context context, ParcelFileDescriptor vpnInterfaceFileDescriptor, @@ -75,8 +70,7 @@ public class Tun2Socks String vpnNetMask, String socksServerAddress, String udpgwServerAddress, - boolean udpgwTransparentDNS) - { + boolean udpgwTransparentDNS) { mContext = context;
mVpnInterfaceFileDescriptor = vpnInterfaceFileDescriptor; @@ -97,26 +91,21 @@ public class Tun2Socks mUdpgwServerAddress, mUdpgwTransparentDNS ? 1 : 0); } - - public static void Stop() - { - + + public static void Stop() { + terminateTun2Socks(); - + }
public static void logTun2Socks( String level, String channel, - String msg) - { + String msg) { String logMsg = level + "(" + channel + "): " + msg; - if (0 == level.compareTo("ERROR")) - { + if (0 == level.compareTo("ERROR")) { Log.e(TAG, logMsg); - } - else - { + } else { if (LOGD) Log.d(TAG, logMsg); } } @@ -132,30 +121,27 @@ public class Tun2Socks
private native static void terminateTun2Socks();
- public static boolean checkIsAllowed (int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) { + public static boolean checkIsAllowed(int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) - { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { return isAllowedQ(protocol, sourceAddr, sourcePort, destAddr, destPort); - } - else + } else return isAllowed(protocol, sourceAddr, sourcePort, destAddr, destPort); }
- public static boolean isAllowed (int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) { + public static boolean isAllowed(int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) {
TCPSourceApp.AppDescriptor aInfo = TCPSourceApp.getApplicationInfo(mContext, sourceAddr, sourcePort, destAddr, destPort);
if (aInfo != null) { int uid = aInfo.getUid(); return mAppUidBlacklist.containsKey(uid); - } - else + } else return true; }
@TargetApi(Build.VERSION_CODES.Q) - public static boolean isAllowedQ (int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) { + public static boolean isAllowedQ(int protocol, String sourceAddr, int sourcePort, String destAddr, int destPort) { ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(CONNECTIVITY_SERVICE); if (cm == null) return false; @@ -167,24 +153,26 @@ public class Tun2Socks return mAppUidBlacklist.containsKey(uid); }
- public static void setBlacklist(HashMap<Integer,String> appUidBlacklist) - { + public static void setBlacklist(HashMap<Integer, String> appUidBlacklist) { mAppUidBlacklist = appUidBlacklist; }
- public static void clearBlacklist() - { + public static void clearBlacklist() { mAppUidBlacklist.clear(); }
- public static void addToBlacklist (int uid, String pkgId) - { - mAppUidBlacklist.put(uid,pkgId); + public static void addToBlacklist(int uid, String pkgId) { + mAppUidBlacklist.put(uid, pkgId); }
- public static void removeFromBlacklist (int uid) - { + public static void removeFromBlacklist(int uid) { mAppUidBlacklist.remove(uid); }
+ public static interface IProtectSocket { + boolean doVpnProtect(Socket socket); + + boolean doVpnProtect(DatagramSocket socket); + } + } \ No newline at end of file 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 e1cdd375..604b1c44 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 @@ -16,9 +16,9 @@ public class VpnUtils {
public static int findProcessId(String command) throws IOException {
- String[] cmds = {"ps -ef","ps -A","toolbox ps"}; + String[] cmds = {"ps -ef", "ps -A", "toolbox ps"};
- for (int i = 0; i < cmds.length;i++) { + for (int i = 0; i < cmds.length; i++) { Process procPs = getRuntime().exec(cmds[i]);
BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream())); @@ -92,7 +92,7 @@ public class VpnUtils { // ignored }
- } + }
if (killAttempts > 4) throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath()); @@ -103,34 +103,31 @@ public class VpnUtils {
public static boolean killProcess(String pidString, String signal) throws Exception {
- String[] cmds = {"","toolbox ","busybox "}; + String[] cmds = {"", "toolbox ", "busybox "};
- for (int i = 0; i < cmds.length;i++) { + for (int i = 0; i < cmds.length; i++) { try { Process proc = getRuntime().exec(cmds[i] + "kill " + signal + " " + pidString); int exitVal = proc.waitFor(); List<String> lineErrors = IOUtils.readLines(proc.getErrorStream()); List<String> lineInputs = IOUtils.readLines(proc.getInputStream());
- if (exitVal != 0) - { - Log.d("Orbot.killProcess","exit=" + exitVal); - for (String line: lineErrors) - Log.d("Orbot.killProcess",line); + if (exitVal != 0) { + Log.d("Orbot.killProcess", "exit=" + exitVal); + for (String line : lineErrors) + Log.d("Orbot.killProcess", line);
- for (String line: lineInputs) - Log.d("Orbot.killProcess",line); + for (String line : lineInputs) + Log.d("Orbot.killProcess", line);
- } - else - { + } else { //it worked, let's exit return true; }
} catch (IOException ioe) { - Log.e("Orbot.killprcess","error killing process: " + pidString,ioe); + Log.e("Orbot.killprcess", "error killing process: " + pidString, ioe); } }
tor-commits@lists.torproject.org