Skip to content

Commit 404f84e

Browse files
authored
[feature] update camouflage-tls (#310)
1 parent b8471c6 commit 404f84e

11 files changed

Lines changed: 111 additions & 47 deletions

File tree

app/src/main/cpp/libs/fptn

Submodule fptn updated from a99db50 to b170630

app/src/main/cpp/src/https_client.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,30 +117,44 @@ Java_org_fptn_vpn_services_websocket_NativeHttpsClientImpl_nativeCreate(
117117
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityMode;
118118
}
119119
/* Chrome */
120-
else if (censorship_strategy_name == "SNI-REALITY-CHROME-147") {
120+
else if (censorship_strategy_name == "SNI-REALITY-CHROME-149") {
121+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome149;
122+
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-148") {
123+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome148;
124+
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-147") {
121125
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome147;
122126
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-146") {
123127
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome146;
124128
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-145") {
125129
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome145;
126130
}
127131
/* Firefox */
128-
else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-149") {
132+
else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-151") {
133+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeFirefox151;
134+
} else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-150") {
135+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeFirefox150;
136+
} else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-149") {
129137
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeFirefox149;
130138
}
131139
/* Yandex */
132-
else if (censorship_strategy_name == "SNI-REALITY-YANDEX-26") {
133-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex26;
140+
else if (censorship_strategy_name == "SNI-REALITY-YANDEX-26-4") {
141+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex26_4;
142+
} else if (censorship_strategy_name == "SNI-REALITY-YANDEX-26-3") {
143+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex26_3;
134144
} else if (censorship_strategy_name == "SNI-REALITY-YANDEX-25") {
135145
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex25;
136146
} else if (censorship_strategy_name == "SNI-REALITY-YANDEX-24") {
137147
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex24;
138148
}
139149
/* Safari */
140-
else if (censorship_strategy_name == "SNI-REALITY-SAFARI-26") {
141-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeSafari26;
150+
else if (censorship_strategy_name == "SNI-REALITY-SAFARI-26-5") {
151+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeSafari26_5;
152+
} else if (censorship_strategy_name == "SNI-REALITY-SAFARI-26-4") {
153+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeSafari26_4;
142154
}
143155

156+
SPDLOG_INFO("HTTPS client censorship strategy: {}", censorship_strategy_name);
157+
144158
auto* https_client = new WrapperHttpsClient(env, global_object_ref,
145159
std::move(host), port, std::move(sni), std::move(md5_fingerprint), censorship_strategy);
146160
return reinterpret_cast<jlong>(https_client);

app/src/main/cpp/src/websocket_client.cpp

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,37 +88,51 @@ Java_org_fptn_vpn_services_websocket_NativeWebSocketClientImpl_nativeCreate(
8888
fptn::protocol::https::CensorshipStrategy censorship_strategy =
8989
fptn::protocol::https::CensorshipStrategy::kSni;
9090
if (censorship_strategy_name == "SNI") {
91-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSni;
91+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSni;
9292
} else if (censorship_strategy_name == "OBFUSCATION") {
9393
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kTlsObfuscator;
9494
} else if (censorship_strategy_name == "SNI-REALITY") { // deprecated
95-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityMode;
95+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityMode;
9696
}
9797
/* Chrome */
98-
else if (censorship_strategy_name == "SNI-REALITY-CHROME-147") {
99-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome147;
98+
else if (censorship_strategy_name == "SNI-REALITY-CHROME-149") {
99+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome149;
100+
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-148") {
101+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome148;
102+
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-147") {
103+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome147;
100104
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-146") {
101-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome146;
105+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome146;
102106
} else if (censorship_strategy_name == "SNI-REALITY-CHROME-145") {
103107
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeChrome145;
104108
}
105109
/* Firefox */
106-
else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-149") {
110+
else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-151") {
111+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeFirefox151;
112+
} else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-150") {
113+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeFirefox150;
114+
} else if (censorship_strategy_name == "SNI-REALITY-FIREFOX-149") {
107115
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeFirefox149;
108116
}
109117
/* Yandex */
110-
else if (censorship_strategy_name == "SNI-REALITY-YANDEX-26") {
111-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex26;
118+
else if (censorship_strategy_name == "SNI-REALITY-YANDEX-26-4") {
119+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex26_4;
120+
} else if (censorship_strategy_name == "SNI-REALITY-YANDEX-26-3") {
121+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex26_3;
112122
} else if (censorship_strategy_name == "SNI-REALITY-YANDEX-25") {
113123
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex25;
114124
} else if (censorship_strategy_name == "SNI-REALITY-YANDEX-24") {
115-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex24;
125+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeYandex24;
116126
}
117127
/* Safari */
118-
else if (censorship_strategy_name == "SNI-REALITY-SAFARI-26") {
119-
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeSafari26;
128+
else if (censorship_strategy_name == "SNI-REALITY-SAFARI-26-5") {
129+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeSafari26_5;
130+
} else if (censorship_strategy_name == "SNI-REALITY-SAFARI-26-4") {
131+
censorship_strategy = fptn::protocol::https::CensorshipStrategy::kSniRealityModeSafari26_4;
120132
}
121133

134+
SPDLOG_INFO("Censorship strategy selected: {}", censorship_strategy_name);
135+
122136
jobject global_object_ref = env->NewWeakGlobalRef(thiz);
123137
auto* websocket_client = new WrapperWebsocketClient(
124138
global_object_ref,

app/src/main/java/org/fptn/vpn/enums/SniSpoofingMode.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22

33
public enum SniSpoofingMode {
44
SNI,
5-
/* Chrome */
6-
SNI_REALITY_CHROME_147,
7-
SNI_REALITY_CHROME_146,
8-
SNI_REALITY_CHROME_145,
9-
/* Firefox */
10-
SNI_REALITY_FIREFOX_149,
115
/* Yandex Browser */
12-
SNI_REALITY_YANDEX_26,
6+
SNI_REALITY_YANDEX_26_4,
7+
SNI_REALITY_YANDEX_26_3,
138
SNI_REALITY_YANDEX_25,
149
SNI_REALITY_YANDEX_24,
10+
/* Firefox */
11+
SNI_REALITY_FIREFOX_151,
12+
SNI_REALITY_FIREFOX_150,
13+
SNI_REALITY_FIREFOX_149,
1514
/* Safari */
16-
SNI_REALITY_SAFARI_26
15+
SNI_REALITY_SAFARI_26_5,
16+
SNI_REALITY_SAFARI_26_4,
17+
/* Chrome */
18+
SNI_REALITY_CHROME_149,
19+
SNI_REALITY_CHROME_148,
20+
SNI_REALITY_CHROME_147,
21+
SNI_REALITY_CHROME_146,
22+
SNI_REALITY_CHROME_145,
1723
}

app/src/main/java/org/fptn/vpn/services/speedtest/SpeedTestUtils.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ public static ServerEntity findFastestServer(List<ServerEntity> serverEntityList
5454
} finally {
5555
executor.shutdownNow();
5656
}
57-
} else {
57+
} /* else {
5858
// Must never happen
59-
throw new PVNClientException(ErrorCode.SERVER_LIST_NULL_OR_EMPTY);
60-
}
59+
// throw new PVNClientException(ErrorCode.SERVER_LIST_NULL_OR_EMPTY);
60+
} */
6161
return null;
6262
}
6363

@@ -92,7 +92,8 @@ public static SpeedTestResult findServerByLogin(List<ServerEntity> serverEntityL
9292
executor.shutdownNow();
9393
}
9494
}
95-
throw new PVNClientException(ErrorCode.SERVER_LIST_NULL_OR_EMPTY);
95+
return null;
96+
//throw new PVNClientException(ErrorCode.SERVER_LIST_NULL_OR_EMPTY);
9697
}
9798

9899
private static List<ServerEntity> selectServersForTesting(List<ServerEntity> servers) {

app/src/main/java/org/fptn/vpn/services/vpn/FptnService.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,6 @@ private void connect(ServerEntity serverEntity, String sniHostname, String preFe
479479
}
480480
int maxReconnectCount = SharedPrefUtils.getReconnectAttemptsCount(this);
481481
int delayBetweenAttempts = SharedPrefUtils.getDelayBetweenReconnect(this);
482-
XLog.tag(TAG).i("Connection params [bypass=%s, maxRetries=%d, retryDelay=%ds, watchIP=%b, watchNetwork=%b]",
483-
SharedPrefUtils.getBypassCensorshipMethod(this),
484-
maxReconnectCount, delayBetweenAttempts,
485-
reconnectOnChangeIPEnabled, reconnectOnChangeNetworkTypeEnabled);
486482

487483
FptnConnection connection;
488484

@@ -492,6 +488,11 @@ private void connect(ServerEntity serverEntity, String sniHostname, String preFe
492488
if (bypassCensorshipMethod == BypassCensorshipMethod.SNI_REALITY) {
493489
sniSpoofingMode = SharedPrefUtils.getSniSpoofingMode(this);
494490
}
491+
XLog.tag(TAG).i("Connection params [bypass=%s, spoofingMode=%s, maxRetries=%d, retryDelay=%ds, watchIP=%b, watchNetwork=%b]",
492+
bypassCensorshipMethod,
493+
sniSpoofingMode,
494+
maxReconnectCount, delayBetweenAttempts,
495+
reconnectOnChangeIPEnabled, reconnectOnChangeNetworkTypeEnabled);
495496

496497
PerAppVpnMode perAppVpnMode = SharedPrefUtils.getPerAppVPNMode(this);
497498
List<AppInfo> appInfos = new ArrayList<>();

app/src/main/java/org/fptn/vpn/utils/token/TokenUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public List<ServerEntity> parseToken(String token) throws PVNClientException {
7676

7777
if (serverDtoList.isEmpty()) {
7878
XLog.tag(TAG).e("Token parsed but no servers found — token may be invalid or expired");
79-
throw new PVNClientException(ErrorCode.SERVER_LIST_NULL_OR_EMPTY);
79+
// throw new PVNClientException(ErrorCode.SERVER_LIST_NULL_OR_EMPTY);
8080
}
8181

8282
return serverDtoList;

app/src/main/java/org/fptn/vpn/views/bypassmethod/BypassMethodsActivity.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -442,22 +442,34 @@ public void onEditSNIServer(View view) {
442442
private String getSniSpoofingModeFriendlyName(SniSpoofingMode mode) {
443443
return switch (mode) {
444444
case SNI -> getString(R.string.sni);
445+
case SNI_REALITY_CHROME_149 ->
446+
getString(R.string.sni_reality_radio_button_label_chrome_149);
447+
case SNI_REALITY_CHROME_148 ->
448+
getString(R.string.sni_reality_radio_button_label_chrome_148);
445449
case SNI_REALITY_CHROME_147 ->
446450
getString(R.string.sni_reality_radio_button_label_chrome_147);
447451
case SNI_REALITY_CHROME_146 ->
448452
getString(R.string.sni_reality_radio_button_label_chrome_146);
449453
case SNI_REALITY_CHROME_145 ->
450454
getString(R.string.sni_reality_radio_button_label_chrome_145);
455+
case SNI_REALITY_FIREFOX_151 ->
456+
getString(R.string.sni_reality_radio_button_label_firefox_151);
457+
case SNI_REALITY_FIREFOX_150 ->
458+
getString(R.string.sni_reality_radio_button_label_firefox_150);
451459
case SNI_REALITY_FIREFOX_149 ->
452460
getString(R.string.sni_reality_radio_button_label_firefox_149);
453-
case SNI_REALITY_YANDEX_26 ->
454-
getString(R.string.sni_reality_radio_button_label_yandex_26);
461+
case SNI_REALITY_YANDEX_26_4 ->
462+
getString(R.string.sni_reality_radio_button_label_yandex_26_4);
463+
case SNI_REALITY_YANDEX_26_3 ->
464+
getString(R.string.sni_reality_radio_button_label_yandex_26_3);
455465
case SNI_REALITY_YANDEX_25 ->
456466
getString(R.string.sni_reality_radio_button_label_yandex_25);
457467
case SNI_REALITY_YANDEX_24 ->
458468
getString(R.string.sni_reality_radio_button_label_yandex_24);
459-
case SNI_REALITY_SAFARI_26 ->
460-
getString(R.string.sni_reality_radio_button_label_safari_26);
469+
case SNI_REALITY_SAFARI_26_5 ->
470+
getString(R.string.sni_reality_radio_button_label_safari_26_5);
471+
case SNI_REALITY_SAFARI_26_4 ->
472+
getString(R.string.sni_reality_radio_button_label_safari_26_4);
461473
default -> mode.toString();
462474
};
463475
}

app/src/main/res/values-fa-rIR/strings.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,23 @@ https://play.google.com/store/apps/details?id=org.fptn.vpn
163163
<string name="tls_handshake_obfuscation_radio_button_label">مخفی‌سازی ترافیک (Obfuscation)</string>
164164
<string name="sni_reality_radio_button_label">جعل پیشرفتهٔ دامنه (SNI + REALITY)</string>
165165

166+
<string name="sni_reality_radio_button_label_chrome_149">(Chrome 149) جعل پیشرفتهٔ دامنه</string>
167+
<string name="sni_reality_radio_button_label_chrome_148">(Chrome 148) جعل پیشرفتهٔ دامنه</string>
166168
<string name="sni_reality_radio_button_label_chrome_147">(Chrome 147) جعل پیشرفتهٔ دامنه</string>
167169
<string name="sni_reality_radio_button_label_chrome_146">(Chrome 146) جعل پیشرفتهٔ دامنه</string>
168170
<string name="sni_reality_radio_button_label_chrome_145">(Chrome 145) جعل پیشرفتهٔ دامنه</string>
169171

172+
<string name="sni_reality_radio_button_label_firefox_151">(Firefox 151) جعل پیشرفتهٔ دامنه</string>
173+
<string name="sni_reality_radio_button_label_firefox_150">(Firefox 150) جعل پیشرفتهٔ دامنه</string>
170174
<string name="sni_reality_radio_button_label_firefox_149">(Firefox 149) جعل پیشرفتهٔ دامنه</string>
171175

172-
<string name="sni_reality_radio_button_label_yandex_26">(Yandex 26) جعل پیشرفتهٔ دامنه</string>
176+
<string name="sni_reality_radio_button_label_yandex_26_4">(Yandex 26.4) جعل پیشرفتهٔ دامنه</string>
177+
<string name="sni_reality_radio_button_label_yandex_26_3">(Yandex 26.3) جعل پیشرفتهٔ دامنه</string>
173178
<string name="sni_reality_radio_button_label_yandex_25">Yandex 25) جعل پیشرفتهٔ دامنه</string>
174179
<string name="sni_reality_radio_button_label_yandex_24">Yandex 24) جعل پیشرفتهٔ دامنه</string>
175180

176-
<string name="sni_reality_radio_button_label_safari_26">(Safari 26) جعل پیشرفتهٔ دامنه</string>
181+
<string name="sni_reality_radio_button_label_safari_26_5">(Safari 26.5) جعل پیشرفتهٔ دامنه</string>
182+
<string name="sni_reality_radio_button_label_safari_26_4">(Safari 26.4) جعل پیشرفتهٔ دامنه</string>
177183

178184
<string name="sni_reality_radio_button_label_additional_info">نیازمند یک دامنهٔ واقعی و فعال است (در غیر این صورت ممکن است خطا رخ دهد)</string>
179185

app/src/main/res/values-ru-rRU/strings.xml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,23 @@ https://play.google.com/store/apps/details?id=org.fptn.vpn
160160
<string name="sni_radio_button_label">Подмена домена</string>
161161
<string name="tls_handshake_obfuscation_radio_button_label">Маскировка трафика (обфускация)</string>
162162
<string name="sni_reality_radio_button_label">Подмена домена (SNI + REALITY)</string>
163-
163+
<string name="sni_reality_radio_button_label_chrome_149">Подмена домена (Chrome 149)</string>
164+
<string name="sni_reality_radio_button_label_chrome_148">Подмена домена (Chrome 148)</string>
164165
<string name="sni_reality_radio_button_label_chrome_147">Подмена домена (Chrome 147)</string>
165166
<string name="sni_reality_radio_button_label_chrome_146">Подмена домена (Chrome 146)</string>
166167
<string name="sni_reality_radio_button_label_chrome_145">Подмена домена (Chrome 145)</string>
167168

169+
<string name="sni_reality_radio_button_label_firefox_151">Подмена домена (Firefox 151)</string>
170+
<string name="sni_reality_radio_button_label_firefox_150">Подмена домена (Firefox 150)</string>
168171
<string name="sni_reality_radio_button_label_firefox_149">Подмена домена (Firefox 149)</string>
169172

170-
<string name="sni_reality_radio_button_label_yandex_26">Подмена домена (Yandex 26)</string>
173+
<string name="sni_reality_radio_button_label_yandex_26_4">Подмена домена (Yandex 26.4)</string>
174+
<string name="sni_reality_radio_button_label_yandex_26_3">Подмена домена (Yandex 26.3)</string>
171175
<string name="sni_reality_radio_button_label_yandex_25">Подмена домена (Yandex 25)</string>
172176
<string name="sni_reality_radio_button_label_yandex_24">Подмена домена (Yandex 24)</string>
173177

174-
<string name="sni_reality_radio_button_label_safari_26">Подмена домена (Safari 26)</string>
178+
<string name="sni_reality_radio_button_label_safari_26_5">Подмена домена (Safari 26.5)</string>
179+
<string name="sni_reality_radio_button_label_safari_26_4">Подмена домена (Safari 26.4)</string>
175180

176181
<string name="sni_reality_radio_button_label_additional_info">Требуется реальный существующий домен (иначе возможны ошибки)</string>
177182

0 commit comments

Comments
 (0)