mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-12-17 13:35:50 +00:00
mobile verify both webpki and installed CA (#13272)
Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
34
Cargo.lock
generated
34
Cargo.lock
generated
@@ -3345,6 +3345,7 @@ dependencies = [
|
|||||||
"protobuf-codegen",
|
"protobuf-codegen",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"regex",
|
"regex",
|
||||||
|
"rustls-native-certs",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-platform-verifier",
|
"rustls-platform-verifier",
|
||||||
"serde 1.0.203",
|
"serde 1.0.203",
|
||||||
@@ -3365,6 +3366,7 @@ dependencies = [
|
|||||||
"tungstenite",
|
"tungstenite",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
"webpki-roots 1.0.0",
|
||||||
"whoami",
|
"whoami",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
"zstd 0.13.1",
|
"zstd 0.13.1",
|
||||||
@@ -6697,9 +6699,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.26"
|
version = "0.23.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0"
|
checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -6719,7 +6721,7 @@ dependencies = [
|
|||||||
"openssl-probe",
|
"openssl-probe",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"schannel",
|
"schannel",
|
||||||
"security-framework 3.2.0",
|
"security-framework 3.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6742,9 +6744,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-platform-verifier"
|
name = "rustls-platform-verifier"
|
||||||
version = "0.5.1"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a5467026f437b4cb2a533865eaa73eb840019a0916f4b9ec563c6e617e086c9"
|
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation 0.10.1",
|
"core-foundation 0.10.1",
|
||||||
"core-foundation-sys 0.8.7",
|
"core-foundation-sys 0.8.7",
|
||||||
@@ -6755,7 +6757,7 @@ dependencies = [
|
|||||||
"rustls-native-certs",
|
"rustls-native-certs",
|
||||||
"rustls-platform-verifier-android",
|
"rustls-platform-verifier-android",
|
||||||
"rustls-webpki",
|
"rustls-webpki",
|
||||||
"security-framework 3.2.0",
|
"security-framework 3.5.1",
|
||||||
"security-framework-sys",
|
"security-framework-sys",
|
||||||
"webpki-root-certs",
|
"webpki-root-certs",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
@@ -6763,15 +6765,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-platform-verifier-android"
|
name = "rustls-platform-verifier-android"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84e217e7fdc8466b5b35d30f8c0a30febd29173df4a3a0c2115d306b9c4117ad"
|
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.103.1"
|
version = "0.103.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
|
checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
@@ -6901,9 +6903,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "3.2.0"
|
version = "3.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
|
checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"core-foundation 0.10.1",
|
"core-foundation 0.10.1",
|
||||||
@@ -6914,9 +6916,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework-sys"
|
name = "security-framework-sys"
|
||||||
version = "2.14.0"
|
version = "2.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
|
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys 0.8.7",
|
"core-foundation-sys 0.8.7",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -8846,9 +8848,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-root-certs"
|
name = "webpki-root-certs"
|
||||||
version = "0.26.8"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09aed61f5e8d2c18344b3faa33a4c837855fe56642757754775548fee21386c4"
|
checksum = "05d651ec480de84b762e7be71e6efa7461699c19d9e2c272c8d93455f567786e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import com.google.protobuf.gradle.*
|
import com.google.protobuf.gradle.*
|
||||||
|
import groovy.json.JsonSlurper
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "com.google.protobuf" version "0.9.4"
|
id "com.google.protobuf" version "0.9.4"
|
||||||
id "com.android.application"
|
id "com.android.application"
|
||||||
@@ -30,8 +32,37 @@ if (flutterVersionName == null) {
|
|||||||
flutterVersionName = '1.0'
|
flutterVersionName = '1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
// Add rustls-platform-verifier Android support
|
||||||
implementation 'com.google.protobuf:protobuf-javalite:3.20.1'
|
String findRustlsPlatformVerifierMavenDir() {
|
||||||
|
def dependencyText = providers.exec {
|
||||||
|
it.workingDir = new File("../..")
|
||||||
|
commandLine("cargo", "metadata", "--format-version", "1")
|
||||||
|
}.standardOutput.asText.get()
|
||||||
|
|
||||||
|
def dependencyJson = new JsonSlurper().parseText(dependencyText)
|
||||||
|
def pkg = dependencyJson.packages.find { it.name == "rustls-platform-verifier-android" }
|
||||||
|
|
||||||
|
if (pkg == null) {
|
||||||
|
throw new GradleException("rustls-platform-verifier-android package not found in cargo metadata!")
|
||||||
|
}
|
||||||
|
|
||||||
|
def manifestPath = file(pkg.manifest_path)
|
||||||
|
def mavenDir = new File(manifestPath.parentFile, "maven")
|
||||||
|
|
||||||
|
if (!mavenDir.exists()) {
|
||||||
|
throw new GradleException("Maven directory not found at: ${mavenDir.path}")
|
||||||
|
}
|
||||||
|
|
||||||
|
println("✓ Found rustls-platform-verifier maven repo at: ${mavenDir.path}")
|
||||||
|
return mavenDir.path
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = findRustlsPlatformVerifierMavenDir()
|
||||||
|
metadataSources.artifact()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protobuf {
|
protobuf {
|
||||||
@@ -67,7 +98,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "com.carriez.flutter_hbb"
|
applicationId "com.carriez.flutter_hbb"
|
||||||
minSdkVersion 21
|
minSdkVersion 22
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
@@ -97,8 +128,10 @@ flutter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation 'com.google.protobuf:protobuf-javalite:3.20.1'
|
||||||
implementation "androidx.media:media:1.6.0"
|
implementation "androidx.media:media:1.6.0"
|
||||||
implementation 'com.github.getActivity:XXPermissions:18.5'
|
implementation 'com.github.getActivity:XXPermissions:18.5'
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib") { version { strictly("1.9.10") } }
|
implementation("org.jetbrains.kotlin:kotlin-stdlib") { version { strictly("1.9.10") } }
|
||||||
implementation 'com.caverock:androidsvg-aar:1.4'
|
implementation 'com.caverock:androidsvg-aar:1.4'
|
||||||
|
implementation "rustls:rustls-platform-verifier:0.1.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
# Keep class members from protobuf generated code.
|
# Keep class members from protobuf generated code.
|
||||||
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
|
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
|
||||||
<fields>;
|
<fields>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Keep rustls-platform-verifier classes for JNI
|
||||||
|
-keep, includedescriptorclasses class org.rustls.platformverifier.** { *; }
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
</queries>
|
</queries>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".RustDeskApplication"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="RustDesk"
|
android:label="RustDesk"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.carriez.flutter_hbb
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.util.Log
|
||||||
|
import ffi.FFI
|
||||||
|
|
||||||
|
class RustDeskApplication : Application() {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "RustDeskApplication"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
Log.d(TAG, "RustDeskApplication onCreate")
|
||||||
|
FFI.onAppStart(applicationContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ object FFI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
external fun init(ctx: Context)
|
external fun init(ctx: Context)
|
||||||
|
external fun onAppStart(ctx: Context)
|
||||||
external fun setClipboardManager(clipboardManager: RdClipboardManager)
|
external fun setClipboardManager(clipboardManager: RdClipboardManager)
|
||||||
external fun startServer(app_dir: String, custom_client_config: String)
|
external fun startServer(app_dir: String, custom_client_config: String)
|
||||||
external fun startService()
|
external fun startService()
|
||||||
|
|||||||
Submodule libs/hbb_common updated: 5ed0afde08...0e38202093
@@ -22,6 +22,7 @@ use std::time::{Duration, Instant};
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref JVM: RwLock<Option<JavaVM>> = RwLock::new(None);
|
static ref JVM: RwLock<Option<JavaVM>> = RwLock::new(None);
|
||||||
static ref MAIN_SERVICE_CTX: RwLock<Option<GlobalRef>> = RwLock::new(None); // MainService -> video service / audio service / info
|
static ref MAIN_SERVICE_CTX: RwLock<Option<GlobalRef>> = RwLock::new(None); // MainService -> video service / audio service / info
|
||||||
|
static ref APPLICATION_CONTEXT: RwLock<Option<GlobalRef>> = RwLock::new(None);
|
||||||
static ref VIDEO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("video", MAX_VIDEO_FRAME_TIMEOUT));
|
static ref VIDEO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("video", MAX_VIDEO_FRAME_TIMEOUT));
|
||||||
static ref AUDIO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("audio", MAX_AUDIO_FRAME_TIMEOUT));
|
static ref AUDIO_RAW: Mutex<FrameRaw> = Mutex::new(FrameRaw::new("audio", MAX_AUDIO_FRAME_TIMEOUT));
|
||||||
static ref NDK_CONTEXT_INITED: Mutex<bool> = Default::default();
|
static ref NDK_CONTEXT_INITED: Mutex<bool> = Default::default();
|
||||||
@@ -462,6 +463,23 @@ fn init_ndk_context(java_vm: *mut c_void, context_jobject: *mut c_void) {
|
|||||||
*lock = true;
|
*lock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_init_rustls_platform_verifier(env: &mut JNIEnv, context_jobject: *mut c_void) {
|
||||||
|
use hbb_common::config::ANDROID_RUSTLS_PLATFORM_VERIFIER_INITIALIZED as INITIALIZED;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
let initialized = INITIALIZED.load(Ordering::Relaxed);
|
||||||
|
if !initialized {
|
||||||
|
let ctx_for_rustls = unsafe { JObject::from_raw(context_jobject as jni::sys::jobject) };
|
||||||
|
if let Err(e) =
|
||||||
|
hbb_common::rustls_platform_verifier::android::init_hosted(env, ctx_for_rustls)
|
||||||
|
{
|
||||||
|
log::error!("Failed to initialize rustls-platform-verifier: {:?}", e);
|
||||||
|
} else {
|
||||||
|
INITIALIZED.store(true, Ordering::Relaxed);
|
||||||
|
log::info!("rustls-platform-verifier initialized successfully");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// https://cjycode.com/flutter_rust_bridge/guides/how-to/ndk-init
|
// https://cjycode.com/flutter_rust_bridge/guides/how-to/ndk-init
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn JNI_OnLoad(vm: jni::JavaVM, res: *mut std::os::raw::c_void) -> jni::sys::jint {
|
pub extern "C" fn JNI_OnLoad(vm: jni::JavaVM, res: *mut std::os::raw::c_void) -> jni::sys::jint {
|
||||||
@@ -471,3 +489,23 @@ pub extern "C" fn JNI_OnLoad(vm: jni::JavaVM, res: *mut std::os::raw::c_void) ->
|
|||||||
}
|
}
|
||||||
jni::JNIVersion::V6.into()
|
jni::JNIVersion::V6.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_ffi_FFI_onAppStart(mut env: JNIEnv, _class: JClass, ctx: JObject) {
|
||||||
|
if ctx.is_null() {
|
||||||
|
log::error!("application context is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if APPLICATION_CONTEXT.read().unwrap().is_some() {
|
||||||
|
log::info!("application context already initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Ok(jvm) = env.get_java_vm() {
|
||||||
|
if let Ok(context) = env.new_global_ref(ctx) {
|
||||||
|
let java_vm = jvm.get_java_vm_pointer() as *mut c_void;
|
||||||
|
let context_jobject = context.as_obj().as_raw() as *mut c_void;
|
||||||
|
*APPLICATION_CONTEXT.write().unwrap() = Some(context);
|
||||||
|
try_init_rustls_platform_verifier(&mut env, context_jobject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,15 +9,30 @@ macro_rules! configure_http_client {
|
|||||||
// https://github.com/rustdesk/rustdesk/issues/11569
|
// https://github.com/rustdesk/rustdesk/issues/11569
|
||||||
// https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.no_proxy
|
// https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.no_proxy
|
||||||
let mut builder = $builder.no_proxy();
|
let mut builder = $builder.no_proxy();
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
match hbb_common::verifier::client_config() {
|
||||||
|
Ok(client_config) => {
|
||||||
|
builder = builder.use_preconfigured_tls(client_config);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
hbb_common::log::error!("Failed to get client config: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
let client = if let Some(conf) = Config::get_socks() {
|
let client = if let Some(conf) = Config::get_socks() {
|
||||||
let proxy_result = Proxy::from_conf(&conf, None);
|
let proxy_result = Proxy::from_conf(&conf, None);
|
||||||
|
|
||||||
match proxy_result {
|
match proxy_result {
|
||||||
Ok(proxy) => {
|
Ok(proxy) => {
|
||||||
let proxy_setup = match &proxy.intercept {
|
let proxy_setup = match &proxy.intercept {
|
||||||
ProxyScheme::Http { host, .. } =>{ reqwest::Proxy::all(format!("http://{}", host))},
|
ProxyScheme::Http { host, .. } => {
|
||||||
ProxyScheme::Https { host, .. } => {reqwest::Proxy::all(format!("https://{}", host))},
|
reqwest::Proxy::all(format!("http://{}", host))
|
||||||
ProxyScheme::Socks5 { addr, .. } => { reqwest::Proxy::all(&format!("socks5://{}", addr)) }
|
}
|
||||||
|
ProxyScheme::Https { host, .. } => {
|
||||||
|
reqwest::Proxy::all(format!("https://{}", host))
|
||||||
|
}
|
||||||
|
ProxyScheme::Socks5 { addr, .. } => {
|
||||||
|
reqwest::Proxy::all(&format!("socks5://{}", addr))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match proxy_setup {
|
match proxy_setup {
|
||||||
@@ -28,12 +43,9 @@ macro_rules! configure_http_client {
|
|||||||
format!("Basic {}", auth.get_basic_authorization());
|
format!("Basic {}", auth.get_basic_authorization());
|
||||||
if let Ok(auth) = basic_auth.parse() {
|
if let Ok(auth) = basic_auth.parse() {
|
||||||
builder = builder.default_headers(
|
builder = builder.default_headers(
|
||||||
vec![(
|
vec![(reqwest::header::PROXY_AUTHORIZATION, auth)]
|
||||||
reqwest::header::PROXY_AUTHORIZATION,
|
.into_iter()
|
||||||
auth,
|
.collect(),
|
||||||
)]
|
|
||||||
.into_iter()
|
|
||||||
.collect(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user