summaryrefslogtreecommitdiff
path: root/ipscrambling/src/main/java/foundation/e/privacymodules
diff options
context:
space:
mode:
Diffstat (limited to 'ipscrambling/src/main/java/foundation/e/privacymodules')
-rw-r--r--ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt54
-rw-r--r--ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt301
2 files changed, 0 insertions, 355 deletions
diff --git a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt b/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt
deleted file mode 100644
index 859319a..0000000
--- a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 E FOUNDATION
- *
- * This program is free software: you can redistribute it and/or modify
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-package foundation.e.privacymodules.ipscrambler
-
-import android.content.Intent
-
-interface IIpScramblerModule {
- fun prepareAndroidVpn(): Intent?
-
- fun start(enableNotification: Boolean = true)
-
- fun stop()
-
- fun requestStatus()
-
- var appList: Set<String>
-
- var exitCountry: String
- fun getAvailablesLocations(): Set<String>
-
- val httpProxyPort: Int
- val socksProxyPort: Int
-
- fun addListener(listener: Listener)
- fun removeListener(listener: Listener)
- fun clearListeners()
-
- fun onCleared()
-
- interface Listener {
- fun onStatusChanged(newStatus: Status)
- fun log(message: String)
- fun onTrafficUpdate(upload: Long, download: Long, read: Long, write: Long)
- }
-
- enum class Status {
- OFF, ON, STARTING, STOPPING, START_DISABLED
- }
-}
diff --git a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt b/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt
deleted file mode 100644
index 1c39330..0000000
--- a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2021 E FOUNDATION
- *
- * This program is free software: you can redistribute it and/or modify
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-package foundation.e.privacymodules.ipscrambler
-
-import android.annotation.SuppressLint
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.net.VpnService
-import android.os.Bundle
-import android.os.Handler
-import android.os.Looper
-import android.os.Message
-import android.util.Log
-import androidx.localbroadcastmanager.content.LocalBroadcastManager
-import foundation.e.privacymodules.ipscrambler.IIpScramblerModule.Listener
-import foundation.e.privacymodules.ipscrambler.IIpScramblerModule.Status
-import org.torproject.android.service.OrbotConstants
-import org.torproject.android.service.OrbotConstants.ACTION_STOP_FOREGROUND_TASK
-import org.torproject.android.service.OrbotService
-import org.torproject.android.service.util.Prefs
-import java.security.InvalidParameterException
-
-@SuppressLint("CommitPrefEdits")
-class IpScramblerModule(private val context: Context) : IIpScramblerModule {
- companion object {
- const val TAG = "IpScramblerModule"
-
- private val EXIT_COUNTRY_CODES = setOf("DE", "AT", "SE", "CH", "IS", "CA", "US", "ES", "FR", "BG", "PL", "AU", "BR", "CZ", "DK", "FI", "GB", "HU", "NL", "JP", "RO", "RU", "SG", "SK")
-
- // Key where exit country is stored by orbot service.
- private const val PREFS_KEY_EXIT_NODES = "pref_exit_nodes"
- // Copy of the package private OrbotService.NOTIFY_ID value.
- // const val ORBOT_SERVICE_NOTIFY_ID_COPY = 1
- }
-
- private var currentStatus: Status? = null
- private val listeners = mutableSetOf<Listener>()
-
- private val localBroadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val action = intent.action ?: return
- if (action == OrbotConstants.ACTION_RUNNING_SYNC) {
- try {
- intent.getStringExtra(OrbotConstants.EXTRA_STATUS)?.let {
- val newStatus = Status.valueOf(it)
- currentStatus = newStatus
- }
- } catch (e: Exception) {
- Log.e(TAG, "Can't parse Orbot service status.")
- }
- return
- }
-
- val msg = messageHandler.obtainMessage()
- msg.obj = action
- msg.data = intent.extras
- messageHandler.sendMessage(msg)
- }
- }
-
- private val messageHandler: Handler = object : Handler(Looper.getMainLooper()) {
- override fun handleMessage(msg: Message) {
- val action = msg.obj as? String ?: return
- val data = msg.data
- when (action) {
- OrbotConstants.LOCAL_ACTION_LOG ->
- data.getString(OrbotConstants.LOCAL_EXTRA_LOG)?.let { newLog(it) }
-
- OrbotConstants.LOCAL_ACTION_BANDWIDTH -> {
- trafficUpdate(
- data.getLong("up", 0),
- data.getLong("down", 0),
- data.getLong("written", 0),
- data.getLong("read", 0)
- )
- }
-
- OrbotConstants.LOCAL_ACTION_PORTS -> {
- httpProxyPort = data.getInt(OrbotService.EXTRA_HTTP_PROXY_PORT, -1)
- socksProxyPort = data.getInt(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1)
- }
-
- OrbotConstants.LOCAL_ACTION_STATUS ->
- data.getString(OrbotConstants.EXTRA_STATUS)?.let {
- try {
- val newStatus = Status.valueOf(it)
- updateStatus(newStatus, force = true)
- } catch (e: Exception) {
- Log.e(TAG, "Can't parse Orbot service status.")
- }
- }
- }
- super.handleMessage(msg)
- }
- }
-
- init {
- Prefs.setContext(context)
-
- val lbm = LocalBroadcastManager.getInstance(context)
- lbm.registerReceiver(
- localBroadcastReceiver,
- IntentFilter(OrbotConstants.LOCAL_ACTION_STATUS)
- )
- lbm.registerReceiver(
- localBroadcastReceiver,
- IntentFilter(OrbotConstants.LOCAL_ACTION_BANDWIDTH)
- )
- lbm.registerReceiver(
- localBroadcastReceiver,
- IntentFilter(OrbotConstants.LOCAL_ACTION_LOG)
- )
- lbm.registerReceiver(
- localBroadcastReceiver,
- IntentFilter(OrbotConstants.LOCAL_ACTION_PORTS)
- )
- lbm.registerReceiver(
- localBroadcastReceiver,
- IntentFilter(OrbotConstants.ACTION_RUNNING_SYNC)
- )
-
- Prefs.getSharedPrefs(context).edit()
- .putInt(OrbotConstants.PREFS_DNS_PORT, OrbotConstants.TOR_DNS_PORT_DEFAULT)
- .apply()
- }
-
- private fun updateStatus(status: Status, force: Boolean = false) {
- if (force || status != currentStatus) {
- currentStatus = status
- listeners.forEach {
- it.onStatusChanged(status)
- }
- }
- }
-
- private fun isServiceRunning(): Boolean {
- // Reset status, and then ask to refresh it synchronously.
- currentStatus = Status.OFF
- LocalBroadcastManager.getInstance(context)
- .sendBroadcastSync(Intent(OrbotConstants.ACTION_CHECK_RUNNING_SYNC))
- return currentStatus != Status.OFF
- }
-
- private fun newLog(message: String) {
- listeners.forEach { it.log(message) }
- }
-
- private fun trafficUpdate(upload: Long, download: Long, read: Long, write: Long) {
- listeners.forEach { it.onTrafficUpdate(upload, download, read, write) }
- }
-
- private fun sendIntentToService(action: String, extra: Bundle? = null) {
- val intent = Intent(context, OrbotService::class.java)
- intent.action = action
- extra?.let { intent.putExtras(it) }
- context.startService(intent)
- }
-
- @SuppressLint("ApplySharedPref")
- private fun saveTorifiedApps(packageNames: Collection<String>) {
- packageNames.joinToString("|")
- Prefs.getSharedPrefs(context).edit().putString(
- OrbotConstants.PREFS_KEY_TORIFIED, packageNames.joinToString("|")
- ).commit()
-
- if (isServiceRunning()) {
- sendIntentToService(OrbotConstants.ACTION_RESTART_VPN)
- }
- }
-
- private fun getTorifiedApps(): Set<String> {
- val list = Prefs.getSharedPrefs(context).getString(OrbotConstants.PREFS_KEY_TORIFIED, "")
- ?.split("|")
- return if (list == null || list == listOf("")) {
- emptySet()
- } else {
- list.toSet()
- }
- }
-
- @SuppressLint("ApplySharedPref")
- private fun setExitCountryCode(countryCode: String) {
- val countryParam = when {
- countryCode.isEmpty() -> ""
- countryCode in EXIT_COUNTRY_CODES -> "{$countryCode}"
- else -> throw InvalidParameterException(
- "Only these countries are available: ${EXIT_COUNTRY_CODES.joinToString { ", " } }"
- )
- }
-
- if (isServiceRunning()) {
- val extra = Bundle()
- extra.putString("exit", countryParam)
- sendIntentToService(OrbotConstants.CMD_SET_EXIT, extra)
- } else {
- Prefs.getSharedPrefs(context)
- .edit().putString(PREFS_KEY_EXIT_NODES, countryParam)
- .commit()
- }
- }
-
- private fun getExitCountryCode(): String {
- val raw = Prefs.getExitNodes()
- return if (raw.isEmpty()) raw else raw.slice(1..2)
- }
-
- override fun prepareAndroidVpn(): Intent? {
- return VpnService.prepare(context)
- }
-
- override fun start(enableNotification: Boolean) {
- Prefs.enableNotification(enableNotification)
- Prefs.putUseVpn(true)
- Prefs.putStartOnBoot(true)
-
- sendIntentToService(OrbotConstants.ACTION_START)
- sendIntentToService(OrbotConstants.ACTION_START_VPN)
- }
-
- override fun stop() {
- updateStatus(Status.STOPPING)
-
- Prefs.putUseVpn(false)
- Prefs.putStartOnBoot(false)
-
- sendIntentToService(OrbotConstants.ACTION_STOP_VPN)
- sendIntentToService(
- action = OrbotConstants.ACTION_STOP,
- extra = Bundle().apply { putBoolean(ACTION_STOP_FOREGROUND_TASK, true) }
- )
- stoppingWatchdog(5)
- }
-
- private fun stoppingWatchdog(countDown: Int) {
- Handler(Looper.getMainLooper()).postDelayed(
- {
- if (isServiceRunning() && countDown > 0) {
- stoppingWatchdog(countDown - 1)
- } else {
- updateStatus(Status.OFF, force = true)
- }
- },
- 500
- )
- }
-
- override fun requestStatus() {
- if (isServiceRunning()) {
- sendIntentToService(OrbotConstants.ACTION_STATUS)
- } else {
- updateStatus(Status.OFF, force = true)
- }
- }
-
- override var appList: Set<String>
- get() = getTorifiedApps()
- set(value) = saveTorifiedApps(value)
-
- override var exitCountry: String
- get() = getExitCountryCode()
- set(value) = setExitCountryCode(value)
-
- override fun getAvailablesLocations(): Set<String> = EXIT_COUNTRY_CODES
-
- override var httpProxyPort: Int = -1
- private set
-
- override var socksProxyPort: Int = -1
- private set
-
- override fun addListener(listener: Listener) {
- listeners.add(listener)
- }
- override fun removeListener(listener: Listener) {
- listeners.remove(listener)
- }
- override fun clearListeners() {
- listeners.clear()
- }
-
- override fun onCleared() {
- LocalBroadcastManager.getInstance(context).unregisterReceiver(localBroadcastReceiver)
- }
-}