230 lines
6.3 KiB
Rust
230 lines
6.3 KiB
Rust
// Copyright 2024 The Grim Developers
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use serde_derive::{Deserialize, Serialize};
|
|
use std::path::PathBuf;
|
|
|
|
use crate::Settings;
|
|
use crate::tor::{TorBridge, TorProxy};
|
|
|
|
const TOR_CONFIG_VERSION: i32 = 1;
|
|
|
|
/// Tor configuration.
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
pub struct TorConfig {
|
|
/// Proxy for tor connections.
|
|
proxy: Option<TorProxy>,
|
|
/// SOCKS5 proxy type.
|
|
proxy_socks5: TorProxy,
|
|
/// HTTP proxy type.
|
|
proxy_http: TorProxy,
|
|
|
|
/// Selected bridge type.
|
|
bridge: Option<TorBridge>,
|
|
/// Webtunnel bridge type.
|
|
webtunnel: TorBridge,
|
|
/// Obfs4 bridge type.
|
|
obfs4: TorBridge,
|
|
/// Snowflake bridge type.
|
|
snowflake: TorBridge,
|
|
|
|
/// Config version.
|
|
ver: Option<i32>,
|
|
}
|
|
|
|
impl Default for TorConfig {
|
|
fn default() -> Self {
|
|
let webtunnel = Self::default_webtunnel_bridge();
|
|
Self {
|
|
proxy: None,
|
|
proxy_socks5: TorProxy::HTTP(TorProxy::DEFAULT_SOCKS5_URL.to_string()),
|
|
proxy_http: TorProxy::HTTP(TorProxy::DEFAULT_HTTP_URL.to_string()),
|
|
bridge: Some(webtunnel.clone()),
|
|
webtunnel,
|
|
obfs4: TorBridge::Obfs4(
|
|
TorBridge::DEFAULT_OBFS4_BIN_PATH.to_string(),
|
|
TorBridge::DEFAULT_OBFS4_CONN_LINE.to_string(),
|
|
),
|
|
snowflake: TorBridge::Snowflake(
|
|
TorBridge::DEFAULT_SNOWFLAKE_BIN_PATH.to_string(),
|
|
TorBridge::DEFAULT_SNOWFLAKE_CONN_LINE.to_string(),
|
|
),
|
|
ver: Some(TOR_CONFIG_VERSION),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TorConfig {
|
|
/// Tor configuration file name.
|
|
pub const FILE_NAME: &'static str = "tor.toml";
|
|
|
|
/// Directory for Tor data files.
|
|
const DIR_NAME: &'static str = "tor";
|
|
|
|
/// Subdirectory name for Tor state.
|
|
const STATE_SUB_DIR: &'static str = "state";
|
|
/// Subdirectory name for Tor cache.
|
|
const CACHE_SUB_DIR: &'static str = "cache";
|
|
/// Subdirectory name for Tor keystore.
|
|
const KEYSTORE_DIR: &'static str = "keystore";
|
|
|
|
/// Webtunnel binary name.
|
|
pub const WEBTUNNEL_BIN: &'static str = "webtunnel";
|
|
/// Webtunnel Android binary name.
|
|
pub const WEBTUNNEL_ANDROID_BIN: &'static str = "libwebtunnel.so";
|
|
|
|
/// Save application configuration to the file.
|
|
pub fn save(&self) {
|
|
Settings::write_to_file(self, Settings::config_path(Self::FILE_NAME, None));
|
|
}
|
|
|
|
/// Get base Tor directory path.
|
|
fn base_path() -> PathBuf {
|
|
Settings::base_path(Some(Self::DIR_NAME.to_string()))
|
|
}
|
|
|
|
/// Get path from subdirectory name.
|
|
fn sub_dir_path(name: &str) -> String {
|
|
let mut base = Self::base_path();
|
|
base.push(name);
|
|
base.to_str().unwrap().to_string()
|
|
}
|
|
|
|
/// Get Tor state directory path.
|
|
pub fn state_path() -> String {
|
|
Self::sub_dir_path(Self::STATE_SUB_DIR)
|
|
}
|
|
|
|
/// Get Tor cache directory path.
|
|
pub fn cache_path() -> String {
|
|
Self::sub_dir_path(Self::CACHE_SUB_DIR)
|
|
}
|
|
|
|
/// Get Tor keystore directory path.
|
|
pub fn keystore_path() -> String {
|
|
let mut base = PathBuf::from(Self::state_path());
|
|
base.push(Self::KEYSTORE_DIR);
|
|
base.to_str().unwrap().to_string()
|
|
}
|
|
|
|
/// Get default webtunnel bridge.
|
|
pub fn default_webtunnel_bridge() -> TorBridge {
|
|
TorBridge::Webtunnel(
|
|
if egui::os::OperatingSystem::from_target_os() == egui::os::OperatingSystem::Android {
|
|
"".to_string()
|
|
} else {
|
|
TorConfig::webtunnel_path()
|
|
},
|
|
serde_json::to_string(&TorBridge::DEFAULT_WEBTUNNEL_CONN_LINES)
|
|
.unwrap_or(TorBridge::DEFAULT_WEBTUNNEL_CONN_LINE.to_string()),
|
|
)
|
|
}
|
|
|
|
/// Webtunnel binary path.
|
|
pub fn webtunnel_path() -> String {
|
|
let os = egui::os::OperatingSystem::from_target_os();
|
|
if os == egui::os::OperatingSystem::Android {
|
|
let base = std::env::var("NATIVE_LIBS_DIR").unwrap_or_default();
|
|
format!("{}/{}", base, Self::WEBTUNNEL_ANDROID_BIN)
|
|
} else {
|
|
let mut base = Self::base_path();
|
|
base.push(Self::WEBTUNNEL_BIN);
|
|
base.to_str().unwrap().to_string()
|
|
}
|
|
}
|
|
|
|
/// Save Tor bridge.
|
|
pub fn save_bridge(bridge: Option<TorBridge>) {
|
|
let mut w_tor_config = Settings::tor_config_to_update();
|
|
w_tor_config.bridge = bridge.clone();
|
|
if bridge.is_some() {
|
|
let bridge = bridge.unwrap();
|
|
match &bridge {
|
|
TorBridge::Webtunnel(_, _) => w_tor_config.webtunnel = bridge,
|
|
TorBridge::Obfs4(_, _) => w_tor_config.obfs4 = bridge,
|
|
TorBridge::Snowflake(_, _) => w_tor_config.snowflake = bridge,
|
|
}
|
|
}
|
|
w_tor_config.save();
|
|
}
|
|
|
|
/// Get current Tor bridge if enabled.
|
|
pub fn get_bridge() -> Option<TorBridge> {
|
|
let r_config = Settings::tor_config_to_read();
|
|
r_config.bridge.clone()
|
|
}
|
|
|
|
/// Get saved Webtunnel bridge.
|
|
pub fn get_webtunnel() -> TorBridge {
|
|
let r_config = Settings::tor_config_to_read();
|
|
r_config.webtunnel.clone()
|
|
}
|
|
|
|
/// Get saved Obfs4 bridge.
|
|
pub fn get_obfs4() -> TorBridge {
|
|
let r_config = Settings::tor_config_to_read();
|
|
r_config.obfs4.clone()
|
|
}
|
|
|
|
/// Get saved Snowflake bridge.
|
|
pub fn get_snowflake() -> TorBridge {
|
|
let r_config = Settings::tor_config_to_read();
|
|
r_config.snowflake.clone()
|
|
}
|
|
|
|
/// Save proxy for Tor connections.
|
|
pub fn save_proxy(proxy: Option<TorProxy>) {
|
|
let mut w_config = Settings::tor_config_to_update();
|
|
w_config.proxy = proxy.clone();
|
|
if let Some(p) = proxy {
|
|
match p {
|
|
TorProxy::SOCKS5(_) => w_config.proxy_socks5 = p,
|
|
TorProxy::HTTP(_) => w_config.proxy_http = p,
|
|
}
|
|
}
|
|
w_config.save();
|
|
}
|
|
|
|
/// Get used proxy for Tor connections.
|
|
pub fn get_proxy() -> Option<TorProxy> {
|
|
let r_config = Settings::tor_config_to_read();
|
|
r_config.proxy.clone()
|
|
}
|
|
|
|
/// Get saved SOCKS5 proxy.
|
|
pub fn get_socks5_proxy() -> TorProxy {
|
|
let r_config = Settings::tor_config_to_read();
|
|
r_config.proxy_socks5.clone()
|
|
}
|
|
|
|
/// Get saved HTTP proxy.
|
|
pub fn get_http_proxy() -> TorProxy {
|
|
let r_config = Settings::tor_config_to_read();
|
|
r_config.proxy_http.clone()
|
|
}
|
|
|
|
/// Check config version to migrate if needed.
|
|
pub fn migrate(&mut self) {
|
|
match self.ver {
|
|
None => {
|
|
// Migrate to 1st version.
|
|
self.bridge = Some(TorConfig::default_webtunnel_bridge());
|
|
self.ver = Some(1);
|
|
}
|
|
Some(_) => {}
|
|
}
|
|
self.save();
|
|
}
|
|
}
|