commit 0c77144ee3fd423e043b732499766ab37c6e1309 Author: b dsnake@protonmail.com Date: Wed Dec 15 18:09:58 2021 -0500
add support for snowflake with amp rendezvous --- .../ui/onboarding/BridgeWizardActivity.java | 10 +++++++ .../ui/onboarding/CustomBridgesActivity.java | 2 +- app/src/main/res/layout/content_bridge_wizard.xml | 18 ++++++------ app/src/main/res/values/strings.xml | 3 +- orbotservice/src/main/assets/fronts | 1 - .../torproject/android/service/OrbotService.java | 32 ++++++++++++++++------ 6 files changed, 46 insertions(+), 20 deletions(-)
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 19e998d0..5dc4e770 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 @@ -25,6 +25,7 @@ public class BridgeWizardActivity extends AppCompatActivity { private RadioButton mBtObfs4; private RadioButton mBtCustom; private RadioButton mBtSnowflake; + private RadioButton mBtnSnowflakeAmp; private View mBtnConfgiureCustomBridges;
private static boolean noBridgesSet() { @@ -68,6 +69,13 @@ public class BridgeWizardActivity extends AppCompatActivity { Prefs.putBridgesEnabled(true); });
+ mBtnSnowflakeAmp = findViewById(R.id.btnSnowflakeAmp); + mBtnSnowflakeAmp.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (!isChecked) return; + Prefs.setBridgesList("snowflake-amp"); + Prefs.putBridgesEnabled(true); + }); + mBtCustom = findViewById(R.id.btnCustomBridges); mBtCustom.setOnCheckedChangeListener((buttonView, isChecked) -> mBtnConfgiureCustomBridges.setVisibility(isChecked ? View.VISIBLE : View.GONE)); @@ -125,6 +133,8 @@ public class BridgeWizardActivity extends AppCompatActivity { mBtObfs4.setChecked(true); } else if (Prefs.getBridgesList().equals("snowflake")) { mBtSnowflake.setChecked(true); + } else if (Prefs.getBridgesList().equals("snowflake-amp")) { + mBtnSnowflakeAmp.setChecked(true); } else { mBtCustom.setChecked(true); } 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 91f50235..3a0babb8 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 @@ -204,6 +204,6 @@ public class CustomBridgesActivity extends AppCompatActivity implements TextWatc
private static boolean userHasSetPreconfiguredBridge(String bridges) { if (bridges == null) return false; - return bridges.equals("obfs4") || bridges.equals("meek") || bridges.equals("snowflake"); + return bridges.equals("obfs4") || bridges.equals("meek") || bridges.equals("snowflake") || bridges.equals("snowflake-amp"); } } diff --git a/app/src/main/res/layout/content_bridge_wizard.xml b/app/src/main/res/layout/content_bridge_wizard.xml index 6dbca868..65364846 100644 --- a/app/src/main/res/layout/content_bridge_wizard.xml +++ b/app/src/main/res/layout/content_bridge_wizard.xml @@ -67,6 +67,14 @@ android:layout_margin="12dp" android:text="@string/bridge_snowflake" />
+ + <RadioButton + android:id="@+id/btnSnowflakeAmp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="12dp" + android:text="@string/bridge_snowflake_amp"/> + <RadioButton android:id="@+id/btnCustomBridges" android:layout_width="wrap_content" @@ -74,6 +82,7 @@ android:layout_margin="12dp" android:text="@string/custom_bridges" />
+ </RadioGroup>
<Button @@ -84,14 +93,5 @@ android:text="@string/configure_custom_bridges" android:visibility="gone" />
- <TextView - android:id="@+id/lbl_bridge_test_status" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_margin="12dp" - android:gravity="center" - android:textColor="@color/bright_green" - android:textSize="16sp" - android:textStyle="bold" /> </LinearLayout> </ScrollView> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3b54a1d7..3a4987d0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -249,7 +249,8 @@ <string name="paste_bridges">Paste Bridges</string> <string name="use_qr_code">Use QR Code</string> <string name="snowflake_proxy_pref_category">Snowflake Proxy (Experimental)</string> - <string name="bridge_snowflake">Connect through other Tor peers (experimental)</string> + <string name="bridge_snowflake">Connect through peers via the snowflake proxy (using domain fronting)</string> + <string name="bridge_snowflake_amp">Connect through peers via the snowflake proxy (using AMP cache rendezvous)</string> <string name="be_a_snowflake_title">Run Snowflake Proxy</string> <string name="be_a_snowflake_desc">Allow other Tor users to connect to Tor through your device. (This can't be used if you connect alongside bridges)</string>
diff --git a/orbotservice/src/main/assets/fronts b/orbotservice/src/main/assets/fronts index 3900c33a..6cafa57b 100644 --- a/orbotservice/src/main/assets/fronts +++ b/orbotservice/src/main/assets/fronts @@ -1,7 +1,6 @@ snowflake-target https://snowflake-broker.torproject.net.global.prod.fastly.net/ snowflake-front cdn.sstatic.net snowflake-stun stun:stun.stunprotocol.org:3478 -snowflake-ampcache https://cdn.ampproject.org/ moat-cdn https://d50gd378qj74g.cloudfront.net/ moat-url https://moat.torproject.org.global.prod.fastly.net/ moat-front cdn.sstatic.net \ No newline at end of file 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 8fef4543..777e641d 100644 --- a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java +++ b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java @@ -139,6 +139,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb 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", ""); + Log.d("bim", "bridgeList=" + bridgeList); return bridgeList.split("\n"); }
@@ -286,7 +287,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb if (Prefs.bridgesEnabled()) { if (useIPtObfsMeekProxy()) IPtProxy.stopObfs4Proxy(); - else if (useIPtSnowflakeProxy()) + else if (useIPtSnowflakeProxyDomainFronting()) IPtProxy.stopSnowflake(); } else if (Prefs.beSnowflakeProxy()) @@ -318,9 +319,14 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb return bridgeList.contains("obfs") || bridgeList.contains("meek"); }
- private static boolean useIPtSnowflakeProxy() { + private static boolean useIPtSnowflakeProxyDomainFronting() { String bridgeList = Prefs.getBridgesList(); - return bridgeList.contains("snowflake"); + return bridgeList.equals("snowflake"); + } + + private static boolean useIPtSnowflakeProxyAMPRendezvous() { + String bridgeList = Prefs.getBridgesList(); + return bridgeList.equals("snowflake-amp"); }
private static HashMap<String,String> mFronts; @@ -350,17 +356,25 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb }
- private void startSnowflakeClient() { + private void startSnowflakeClientDomainFronting() { //this is using the current, default Tor snowflake infrastructure String target = getCdnFront("snowflake-target"); String front = getCdnFront("snowflake-front"); String stunServer = getCdnFront("snowflake-stun"); - String ampCache = null; // getCdnFront("snowflake-ampcache"); + String ampCache = null;
IPtProxy.startSnowflake(stunServer, target, front, ampCache, null, true, false, false, 1); }
+ private void startSnowflakeClientAmpRendezvous() { + String stunServers ="stun:stun.l.google.com:19302,stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478"; + String target = "https://snowflake-broker.torproject.net/"; + String front = "www.google.com"; + String ampCache ="https://cdn.ampproject.org/"; + IPtProxy.startSnowflake(stunServers, target, front, ampCache, null, true, false, false, 1); + } + /* This is to host a snowflake entrance node / bridge */ @@ -1072,7 +1086,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb builtInBridgeType = "meek_lite"; }
- if (bridgeList.equals("snowflake")) { + if (bridgeList.equals("snowflake") || bridgeList.equals("snowflake-amp")) { extraLines.append("ClientTransportPlugin snowflake socks5 127.0.0.1:" + IPtProxy.snowflakePort()).append('\n'); builtInBridgeType = "snowflake"; } @@ -1417,8 +1431,10 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb if (Prefs.bridgesEnabled()) { if (useIPtObfsMeekProxy()) IPtProxy.startObfs4Proxy("DEBUG", false, false, null); - else if (useIPtSnowflakeProxy()) - startSnowflakeClient(); + else if (useIPtSnowflakeProxyDomainFronting()) + startSnowflakeClientDomainFronting(); + else if (useIPtSnowflakeProxyAMPRendezvous()) + startSnowflakeClientAmpRendezvous(); } else if (Prefs.beSnowflakeProxy()) { // if (Prefs.limitSnowflakeProxying()) { enableSnowflakeProxy();
tor-commits@lists.torproject.org