TOR bridge + TOR Proxy + migration config_file_version (#617)

* tor bridge config and args

* migration `config_file_version=2`

* small fixes typo, comment etc..

* support: snowflake, meek_lite, obsf4 and tor proxy

* remove useless serde

* improve migrate function

* few fixes

* add bridge flags to pay and receive + few fixes

* some improvements
This commit is contained in:
deevope
2022-02-03 16:33:41 +01:00
committed by GitHub
parent f5dbed2014
commit c424a0ed10
18 changed files with 1338 additions and 41 deletions
+56 -11
View File
@@ -25,6 +25,7 @@ use crate::util::secp::key::SecretKey;
use crate::util::{from_hex, static_secp_instance, to_base64, Mutex};
use failure::ResultExt;
use grin_wallet_api::JsonId;
use grin_wallet_config::types::{TorBridgeConfig, TorProxyConfig};
use grin_wallet_util::OnionV3Address;
use hyper::body;
use hyper::header::HeaderValue;
@@ -38,6 +39,7 @@ use std::sync::Arc;
use crate::impls::tor::config as tor_config;
use crate::impls::tor::process as tor_process;
use crate::impls::tor::{bridge as tor_bridge, proxy as tor_proxy};
use crate::apiwallet::{
EncryptedRequest, EncryptedResponse, EncryptionErrorResponse, Foreign,
@@ -83,6 +85,8 @@ fn init_tor_listener<L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K> + 'static>>>,
keychain_mask: Arc<Mutex<Option<SecretKey>>>,
addr: &str,
bridge: TorBridgeConfig,
tor_proxy: TorProxyConfig,
) -> Result<(tor_process::TorProcess, SlatepackAddress), Error>
where
L: WalletLCProvider<'static, C, K> + 'static,
@@ -103,17 +107,44 @@ where
let onion_address = OnionV3Address::from_private(&sec_key.0)
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
let sp_address = SlatepackAddress::try_from(onion_address.clone())?;
let mut hm_tor_bridge: HashMap<String, String> = HashMap::new();
let mut tor_timeout = 20;
if bridge.bridge_line.is_some() {
tor_timeout = 40;
let bridge_config = tor_bridge::TorBridge::try_from(bridge)
.map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?;
hm_tor_bridge = bridge_config
.to_hashmap()
.map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?;
}
let mut hm_tor_poxy: HashMap<String, String> = HashMap::new();
if tor_proxy.transport.is_some() || tor_proxy.allowed_port.is_some() {
let proxy_config = tor_proxy::TorProxy::try_from(tor_proxy)
.map_err(|e| ErrorKind::TorConfig(format!("{}", e).into()))?;
hm_tor_poxy = proxy_config
.to_hashmap()
.map_err(|e| ErrorKind::TorConfig(format!("{}", e.kind()).into()))?;
}
warn!(
"Starting Tor Hidden Service for API listener at address {}, binding to {}",
onion_address, addr
);
tor_config::output_tor_listener_config(&tor_dir, addr, &vec![sec_key])
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
tor_config::output_tor_listener_config(
&tor_dir,
addr,
&vec![sec_key],
hm_tor_bridge,
hm_tor_poxy,
)
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
// Start TOR process
process
.torrc_path(&format!("{}/torrc", tor_dir))
.working_dir(&tor_dir)
.timeout(20)
.timeout(tor_timeout)
.completion_percent(100)
.launch()
.map_err(|e| ErrorKind::TorProcess(format!("{:?}", e).into()))?;
@@ -266,17 +297,31 @@ where
let lc = w_lock.lc_provider()?;
let _ = lc.wallet_inst()?;
}
let (tor_bridge, tor_proxy) = match tor_config.clone() {
Some(s) => (s.bridge, s.proxy),
None => (TorBridgeConfig::default(), TorProxyConfig::default()),
};
// need to keep in scope while the main listener is running
let (_tor_process, address) = match use_tor {
true => match init_tor_listener(wallet.clone(), keychain_mask.clone(), addr) {
Ok((tp, addr)) => (Some(tp), Some(addr)),
Err(e) => {
warn!("Unable to start TOR listener; Check that TOR executable is installed and on your path");
warn!("Tor Error: {}", e);
warn!("Listener will be available via HTTP only");
(None, None)
true => {
match init_tor_listener(
wallet.clone(),
keychain_mask.clone(),
addr,
tor_bridge,
tor_proxy,
) {
Ok((tp, addr)) => (Some(tp), Some(addr)),
Err(e) => {
warn!("Unable to start TOR listener; Check that TOR executable is installed and on your path");
error!("Tor Error: {}", e);
warn!("Listener will be available via HTTP only");
(None, None)
}
}
},
}
false => (None, None),
};