diff options
Diffstat (limited to 'ipscrambling')
-rw-r--r-- | ipscrambling/README.md | 2 | ||||
-rw-r--r-- | ipscrambling/build.gradle | 4 | ||||
-rw-r--r-- | ipscrambling/dependencies.gradle | 61 | ||||
-rw-r--r-- | ipscrambling/exportdependencies/publish.gradle | 6 | ||||
-rw-r--r-- | ipscrambling/exportdependencies/update_dependencies.md | 4 | ||||
-rw-r--r-- | ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt | 2 | ||||
-rw-r--r-- | ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt (renamed from ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/IpScramblerModule.kt) | 132 |
7 files changed, 107 insertions, 104 deletions
diff --git a/ipscrambling/README.md b/ipscrambling/README.md index 777b6a1..be51828 100644 --- a/ipscrambling/README.md +++ b/ipscrambling/README.md @@ -22,7 +22,7 @@ This will put compiled AAR and pom file exposing their dependencies in the local repository (usually in ~/.m2/repository). -To push release on gitlab +To push release on gitlab (you will need a valid gitLabPrivateToken in ~/.gradle/gradle.properties) ./gradlew --console=verbose publish diff --git a/ipscrambling/build.gradle b/ipscrambling/build.gradle index 39efce7..29fed4f 100644 --- a/ipscrambling/build.gradle +++ b/ipscrambling/build.gradle @@ -50,7 +50,9 @@ dependencies { libs.bundles.koin, libs.bundles.kotlin.android.coroutines, libs.androidx.localbroadcast, + libs.pcap4j, + libs.timber ) implementation libs.e.orbotservice - //implementation project(':ipscrambling:orbotservice') + implementation project(':core') } diff --git a/ipscrambling/dependencies.gradle b/ipscrambling/dependencies.gradle index 412bf9a..31b6b78 100644 --- a/ipscrambling/dependencies.gradle +++ b/ipscrambling/dependencies.gradle @@ -1,5 +1,5 @@ ext { - versions = [ + orbotversions = [ android_material : "1.4.0", android_shell : "1.0.0", android_snowfall : "1.2.1", @@ -26,36 +26,37 @@ ext { tor_android : "0.4.7.10", pcap_core : "1.8.2", pcap_factory : "1.8.2", - orbot_service : libs.versions.orbotservice, + orbot_service : "orbot-16.6.3-2", //libs.versions.orbotservice, + orbot_service_dependencies : "orbot-16.6.3-1", ] - libs = [ - android_material : "com.google.android.material:material:$versions.android_material", - android_shell : "com.jaredrummler:android-shell:$versions.android_shell", - android_snowfall : "com.github.jetradarmobile:android-snowfall:$versions.android_snowfall", - android_volley : "com.android.volley:volley:$versions.android_volley", - androidx_appcompat : "androidx.appcompat:appcompat:$versions.androidx_appcompat", - androidx_constraint : "androidx.constraintlayout:constraintlayout:$versions.androidx_constraint", - androidx_coordinator : "androidx.coordinatorlayout:coordinatorlayout:$versions.androidx_coordinator", - androidx_core : "androidx.core:core:$versions.androidx_core", - androidx_leanback_core : "androidx.leanback:leanback:$versions.androidx_leanback", - androidx_leanback_paging : "androidx.leanback:leanback-paging:$versions.androidx_leanback_paging", - androidx_leanback_preferences : "androidx.leanback:leanback-preference:$versions.androidx_leanback", - androidx_leanback_tab : "androidx.leanback:leanback-tab:$versions.androidx_leanback_tab", - androidx_localbroadcast : "androidx.localbroadcastmanager:localbroadcastmanager:$versions.androidx_localbroadcast", - androidx_multidex : "androidx.multidex:multidex:$versions.androidx_multidex", - androidx_palette : "androidx.palette:palette:$versions.androidx_palette", - androidx_recyclerview : "androidx.recyclerview:recyclerview:$versions.androidx_recyclerview", - apl_appintro : "com.github.apl-devs:appintro:$versions.apl_appintro", - bclogic_pulsator : "pl.bclogic:pulsator4droid:$versions.bclogic_pulsator", - fastlane_screengrab : "tools.fastlane:screengrab:$versions.fastlane_screengrab", - guardian_geoip : "foundation.e:geoip:$versions.orbot_service", - guardian_jsocks : "com.gitlab.guardianproject:jsocksandroid:$versions.guardian_jsocks", - guardian_jtorctl : "info.guardianproject:jtorctl:$versions.guardian_jtorctl", - ipt_proxy : "foundation.e:OrbotIPtProxy:$versions.orbot_service", - portmapper : "com.offbynull.portmapper:portmapper:$versions.portmapper", - tor_android : "foundation.e:tor-android:$versions.orbot_service", - pcap_core : "org.pcap4j:pcap4j-core:$versions.pcap_core", - pcap_factory : "org.pcap4j:pcap4j-packetfactory-static:$versions.pcap_factory" + orbotlibs = [ + android_material : "com.google.android.material:material:$orbotversions.android_material", + android_shell : "com.jaredrummler:android-shell:$orbotversions.android_shell", + android_snowfall : "com.github.jetradarmobile:android-snowfall:$orbotversions.android_snowfall", + android_volley : "com.android.volley:volley:$orbotversions.android_volley", + androidx_appcompat : "androidx.appcompat:appcompat:$orbotversions.androidx_appcompat", + androidx_constraint : "androidx.constraintlayout:constraintlayout:$orbotversions.androidx_constraint", + androidx_coordinator : "androidx.coordinatorlayout:coordinatorlayout:$orbotversions.androidx_coordinator", + androidx_core : "androidx.core:core:$orbotversions.androidx_core", + androidx_leanback_core : "androidx.leanback:leanback:$orbotversions.androidx_leanback", + androidx_leanback_paging : "androidx.leanback:leanback-paging:$orbotversions.androidx_leanback_paging", + androidx_leanback_preferences : "androidx.leanback:leanback-preference:$orbotversions.androidx_leanback", + androidx_leanback_tab : "androidx.leanback:leanback-tab:$orbotversions.androidx_leanback_tab", + androidx_localbroadcast : "androidx.localbroadcastmanager:localbroadcastmanager:$orbotversions.androidx_localbroadcast", + androidx_multidex : "androidx.multidex:multidex:$orbotversions.androidx_multidex", + androidx_palette : "androidx.palette:palette:$orbotversions.androidx_palette", + androidx_recyclerview : "androidx.recyclerview:recyclerview:$orbotversions.androidx_recyclerview", + apl_appintro : "com.github.apl-devs:appintro:$orbotversions.apl_appintro", + bclogic_pulsator : "pl.bclogic:pulsator4droid:$orbotversions.bclogic_pulsator", + fastlane_screengrab : "tools.fastlane:screengrab:$orbotversions.fastlane_screengrab", + guardian_geoip : "foundation.e:geoip:$orbotversions.orbot_service_dependencies", + guardian_jsocks : "com.gitlab.guardianproject:jsocksandroid:$orbotversions.guardian_jsocks", + guardian_jtorctl : "info.guardianproject:jtorctl:$orbotversions.guardian_jtorctl", + ipt_proxy : "foundation.e:OrbotIPtProxy:$orbotversions.orbot_service_dependencies", + portmapper : "com.offbynull.portmapper:portmapper:$orbotversions.portmapper", + tor_android : "foundation.e:tor-android:$orbotversions.orbot_service_dependencies", + pcap_core : "org.pcap4j:pcap4j-core:$orbotversions.pcap_core", + pcap_factory : "org.pcap4j:pcap4j-packetfactory-static:$orbotversions.pcap_factory" ] } diff --git a/ipscrambling/exportdependencies/publish.gradle b/ipscrambling/exportdependencies/publish.gradle index 657ce22..3ff0f91 100644 --- a/ipscrambling/exportdependencies/publish.gradle +++ b/ipscrambling/exportdependencies/publish.gradle @@ -5,7 +5,7 @@ publishing { maven(MavenPublication) { groupId 'foundation.e' artifactId 'orbotservice' - version versions.orbot_service + version orbotversions.orbot_service artifact "$buildDir/outputs/aar/orbotservice-release.aar" pom.withXml { @@ -25,7 +25,7 @@ publishing { def ciApiV4Url = System.getenv("CI_API_V4_URL") if (ciJobToken != null) { maven { - url "${ciApiV4Url}/projects/1063/packages/maven" + url "${ciApiV4Url}/projects/900/packages/maven" credentials(HttpHeaderCredentials) { name = 'Job-Token' value = ciJobToken @@ -36,7 +36,7 @@ publishing { } } else { maven { - url "https://gitlab.e.foundation/api/v4/projects/1063/packages/maven" + url "https://gitlab.e.foundation/api/v4/projects/900/packages/maven" credentials(HttpHeaderCredentials) { name = "Private-Token" value = gitLabPrivateToken diff --git a/ipscrambling/exportdependencies/update_dependencies.md b/ipscrambling/exportdependencies/update_dependencies.md index 32ef58d..faf11f3 100644 --- a/ipscrambling/exportdependencies/update_dependencies.md +++ b/ipscrambling/exportdependencies/update_dependencies.md @@ -17,7 +17,7 @@ mvn install:install-file \ mvn deploy:deploy-file \ -DrepositoryId=gitlab-e-maven \ --Durl=https://gitlab.e.foundation/api/v4/projects/1063/packages/maven \ +-Durl=https://gitlab.e.foundation/api/v4/projects/900/packages/maven \ -DartifactId=[ARTIFACTID] \ -Dpackaging=aar \ -Dfile=[PATH] @@ -37,7 +37,7 @@ step 4 : mvn deploy:deploy-file \ -DrepositoryId=gitlab-e-maven \ --Durl=https://gitlab.e.foundation/api/v4/projects/1063/packages/maven \ +-Durl=https://gitlab.e.foundation/api/v4/projects/900/packages/maven \ -DartifactId=tor-android \ -Dpackaging=aar \ -Dfile="../../orbot/libs/tor-android-binary-release.aar diff --git a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt index bfb9b32..79aeb05 100644 --- a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt +++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt @@ -21,5 +21,5 @@ import org.koin.core.module.dsl.singleOf import org.koin.dsl.module val ipScramblerModule = module { - singleOf(::IpScramblerModule) + singleOf(::OrbotServiceSupervisor) } diff --git a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/IpScramblerModule.kt b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt index d1f01a0..8813948 100644 --- a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/IpScramblerModule.kt +++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt @@ -1,4 +1,5 @@ /* + * Copyright (C) 2023 MURENA SAS * Copyright (C) 2021 E FOUNDATION * * This program is free software: you can redistribute it and/or modify @@ -27,28 +28,37 @@ 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.advancedprivacy.domain.entities.FeatureServiceState +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.pcap4j.packet.DnsPacket 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 timber.log.Timber import java.security.InvalidParameterException +import java.util.function.Function @SuppressLint("CommitPrefEdits") -class IpScramblerModule(private val context: Context) { - interface Listener { - fun onStatusChanged(newStatus: Status) - fun log(message: String) - fun onTrafficUpdate(upload: Long, download: Long, read: Long, write: Long) - } +class OrbotServiceSupervisor( + private val context: Context, + private val coroutineScope: CoroutineScope, +) { + private val _state = MutableStateFlow(FeatureServiceState.OFF) + val state: StateFlow<FeatureServiceState> = _state enum class Status { OFF, ON, STARTING, STOPPING, START_DISABLED } 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. @@ -58,7 +68,6 @@ class IpScramblerModule(private val context: Context) { } private var currentStatus: Status? = null - private val listeners = mutableSetOf<Listener>() private val localBroadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -70,7 +79,7 @@ class IpScramblerModule(private val context: Context) { currentStatus = newStatus } } catch (e: Exception) { - Log.e(TAG, "Can't parse Orbot service status.") + Timber.e("Can't parse Orbot service status.") } return } @@ -87,18 +96,6 @@ class IpScramblerModule(private val context: Context) { 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) @@ -110,9 +107,11 @@ class IpScramblerModule(private val context: Context) { val newStatus = Status.valueOf(it) updateStatus(newStatus, force = true) } catch (e: Exception) { - Log.e(TAG, "Can't parse Orbot service status.") + Timber.e("Can't parse Orbot service status.") } } + OrbotConstants.LOCAL_ACTION_LOG, + OrbotConstants.LOCAL_ACTION_BANDWIDTH -> {} // Unused in Advanced Privacy } super.handleMessage(msg) } @@ -150,9 +149,24 @@ class IpScramblerModule(private val context: Context) { private fun updateStatus(status: Status, force: Boolean = false) { if (force || status != currentStatus) { - currentStatus = status - listeners.forEach { - it.onStatusChanged(status) + val newState = when (status) { + Status.OFF -> FeatureServiceState.OFF + Status.ON -> FeatureServiceState.ON + Status.STARTING -> FeatureServiceState.STARTING + Status.STOPPING, + Status.START_DISABLED -> FeatureServiceState.STOPPING + } + + coroutineScope.launch(Dispatchers.IO) { + _state.update { currentState -> + if (newState == FeatureServiceState.OFF && + currentState == FeatureServiceState.STOPPING + ) { + // Wait for orbot to relax before allowing user to reactivate it. + delay(1000) + } + newState + } } } } @@ -165,14 +179,6 @@ class IpScramblerModule(private val context: Context) { 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 @@ -203,27 +209,29 @@ class IpScramblerModule(private val context: Context) { } @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 { ", " } }" - ) - } + suspend fun setExitCountryCode(countryCode: String) { + withContext(Dispatchers.IO) { + 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() + 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 { + fun getExitCountryCode(): String { val raw = Prefs.getExitNodes() return if (raw.isEmpty()) raw else raw.slice(1..2) } @@ -232,6 +240,10 @@ class IpScramblerModule(private val context: Context) { return VpnService.prepare(context) } + fun setDNSFilter(shouldBlock: Function<DnsPacket?, DnsPacket?>?) { + OrbotService.shouldBlock = shouldBlock + } + fun start(enableNotification: Boolean) { Prefs.enableNotification(enableNotification) Prefs.putUseVpn(true) @@ -242,6 +254,8 @@ class IpScramblerModule(private val context: Context) { } fun stop() { + if (!isServiceRunning()) return + updateStatus(Status.STOPPING) Prefs.putUseVpn(false) @@ -280,10 +294,6 @@ class IpScramblerModule(private val context: Context) { get() = getTorifiedApps() set(value) = saveTorifiedApps(value) - var exitCountry: String - get() = getExitCountryCode() - set(value) = setExitCountryCode(value) - fun getAvailablesLocations(): Set<String> = EXIT_COUNTRY_CODES var httpProxyPort: Int = -1 @@ -292,16 +302,6 @@ class IpScramblerModule(private val context: Context) { var socksProxyPort: Int = -1 private set - fun addListener(listener: Listener) { - listeners.add(listener) - } - fun removeListener(listener: Listener) { - listeners.remove(listener) - } - fun clearListeners() { - listeners.clear() - } - fun onCleared() { LocalBroadcastManager.getInstance(context).unregisterReceiver(localBroadcastReceiver) } |