orbot
orbot copied to clipboard
[Feature Request] Add support for Meek-Azure
Is your feature request related to a problem? Please describe.
Orbot used to support MeekLite bridges, but support was lost when IPtProxy was recently upgraded. The function bridgesEnabled() checks if the locale is Farsi and automatically sets MeekLite as the default bridge, even though it is undefined now. Tor Browser has support for Meek-Azure, so lets add support for it as well. The bridge line used in Tor Browser is:
meek_lite 192.0.2.20:80 url=https://1314488750.rsc.cdn77.org front=www.phpmyadmin.net utls=HelloRandomizedALPN
Describe the Solution You'd Like Add support for Meek-Azure bridge
Describe the Alternatives You've Considered A clear and concise description of any alternative solutions or features you've considered.
Additional Context Add any other context or screenshots about the feature request here.
@bitmold I looked at the code and I'm not sure what the best way is to implement this. IMHO, Meek-Azure should just be an option when setting up a custom bridge, same as snowflake bridges. There is only one known working meek-azure bridge, the same one that Tor Browser uses. So, the Meek-Azure bridge is not a bridge that users would manually enter in as a custom bridge.
Since Tor Browser lets users manually select Meek-Azure as a bridge, I dont think this should be an issue if it was also added to Orbot.
In CustomBridgeBottomSheet.kt, regex should also support meek bridges. Currently, it is only checking for obfs4 and webtunnel.
https://github.com/guardianproject/orbot-android/blob/f26ee8e7c31eccf46abd2e43b485ad0e9e4c31a8/app/src/main/java/org/torproject/android/CustomBridgeBottomSheet.kt#L18
@meenbeese When you added the regex check in CustomBridgeBottomSheet.kt, we only tested obfs4 and webtunnel. Could you also look at meek support using the bridge line from the first post here?
I will take care of this next week and streamline with our Apple implementations.
FWIW bridgesEnabled is actually an unused function
Related: #1196, #1102
@meenbeese When you added the regex check in CustomBridgeBottomSheet.kt, we only tested obfs4 and webtunnel. Could you also look at meek support using the bridge line from the first post here?
A regex like this should work for meek bridges. I'm not really sure if we should also update bridgeStatement regex like I did here, but feel free to push this to your PR and test if it works.
diff --git a/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt b/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt
index 1ef3938ec..d72ed326a 100644
--- a/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt
+++ b/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt
@@ -16,14 +16,19 @@ class CustomBridgeBottomSheet(private val callbacks: ConnectionHelperCallbacks)
OrbotBottomSheetDialogFragment() {
companion object {
const val TAG = "CustomBridgeBottomSheet"
- private val bridgeStatement = Regex("(obfs4|meek|webtunnel)")
+ private val bridgeStatement = Regex("(obfs4|meek|webtunnel|meek_lite)")
private val obfs4Regex = Regex("""^obfs4\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-fA-F:]+]):\d+\s+[A-F0-9]{40}(\s+cert=[a-zA-Z0-9+/=]+)?(\s+iat-mode=\d+)?$""")
private val webtunnelRegex = Regex("""^webtunnel\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-fA-F:]+]):\d+\s+[A-F0-9]{40}(\s+url=https?://\S+)?(\s+ver=\d+\.\d+\.\d+)?$""")
+ private val meekLiteRegex = Regex("""^meek_lite\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-fA-F:]+]):\d+\s+url=https?://\S+\s+front=\S+\s+utls=\S+$""")
fun isValidBridge(input: String): Boolean {
return input.lines()
.filter { it.isNotEmpty() && it.isNotBlank() }
- .all { it.matches(obfs4Regex) || it.matches(webtunnelRegex) }
+ .all {
+ it.matches(obfs4Regex) ||
+ it.matches(webtunnelRegex) ||
+ it.matches(meekLiteRegex)
+ }
}
}
Thanks @meenbeese. I think bridgeStatement does not need to have meek_lite added, since the code uses contains when checking the value. So, just meek should be enough to set bridges = "".
https://github.com/guardianproject/orbot-android/blob/0b9e0c97392c2eb7ce92d72012954aed56583311/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt#L50
Great, thanks for confirming. There is also a nice UX enhancement we can make where if the bridge is invalid, the connect button is grayed out. We were already disabling this button internally so pressing it wouldn't work, but an indication to the user was missing.
diff --git a/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt b/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt
index d72ed326a..033a56105 100644
--- a/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt
+++ b/app/src/main/java/org/torproject/android/ui/connect/CustomBridgeBottomSheet.kt
@@ -1,5 +1,7 @@
package org.torproject.android.ui.connect
+import android.content.res.ColorStateList
+import android.graphics.Color
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
@@ -8,6 +10,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
+
import org.torproject.android.R
import org.torproject.android.service.util.Prefs
import org.torproject.android.ui.OrbotBottomSheetDialogFragment
@@ -69,7 +72,16 @@ class CustomBridgeBottomSheet(private val callbacks: ConnectionHelperCallbacks)
private fun updateUi() {
val inputText = etBridges.text.toString()
- btnAction.isEnabled = inputText.isNotEmpty() && isValidBridge(inputText)
+ val isValid = inputText.isNotEmpty() && isValidBridge(inputText)
+
+ btnAction.isEnabled = isValid
+ btnAction.backgroundTintList = ColorStateList.valueOf(
+ if (isValid) {
+ requireContext().getColor(R.color.orbot_btn_enabled_purple)
+ } else {
+ Color.DKGRAY
+ }
+ )
if (!isValidBridge(inputText)) {
etBridges.error = requireContext().getString(R.string.invalid_bridge_format)
FWIW
bridgesEnabledis actually an unused function
Ah yeah, I still have the Tor Relay support added on my branch which uses that function.
Great, thanks for confirming. There is also a nice UX enhancement we can make where if the bridge is invalid, the connect button is grayed out. We were already disabling this button internally so pressing it wouldn't work, but an indication to the user was missing.
I really like that idea. You should add that as a separate PR. I don't want to take credit for your good idea. ;)
Great, thanks for confirming. There is also a nice UX enhancement we can make where if the bridge is invalid, the connect button is grayed out. We were already disabling this button internally so pressing it wouldn't work, but an indication to the user was missing.
I really like that idea. You should add that as a separate PR. I don't want to take credit for your good idea. ;)
Right, I'll add it after your PR is merged then to avoid merge conflicts.
Right, I'll add it after your PR is merged then to avoid merge conflicts.
It does not look like it will conflict with anything I'm doing.
Working on this here: https://github.com/tladesignz/orbot/tree/bridge_refurbish
Note that it's sometimes useful to have a custom Snowflake bridge line, such as for changing domain fronts, or rendezvous method.
Implemented with #1360