tor: add service key result check
This commit is contained in:
parent
eec434ecaa
commit
c4fa0f7ec6
1 changed files with 180 additions and 156 deletions
166
src/tor/tor.rs
166
src/tor/tor.rs
|
@ -97,19 +97,18 @@ impl Tor {
|
|||
/// Create Tor client configuration.
|
||||
fn build_config() -> TorClientConfig {
|
||||
// Create Tor client config.
|
||||
let mut builder =
|
||||
TorClientConfigBuilder::from_directories(TorConfig::state_path(),
|
||||
TorConfig::cache_path());
|
||||
let mut builder = TorClientConfigBuilder::from_directories(
|
||||
TorConfig::state_path(),
|
||||
TorConfig::cache_path(),
|
||||
);
|
||||
// Setup bridges.
|
||||
let bridge = TorConfig::get_bridge();
|
||||
if let Some(b) = bridge {
|
||||
match b {
|
||||
super::TorBridge::Snowflake(path, conn) => {
|
||||
Self::build_snowflake(&mut builder, path, conn)
|
||||
},
|
||||
super::TorBridge::Obfs4(path, conn) => {
|
||||
Self::build_obfs4(&mut builder, path, conn)
|
||||
},
|
||||
}
|
||||
super::TorBridge::Obfs4(path, conn) => Self::build_obfs4(&mut builder, path, conn),
|
||||
}
|
||||
}
|
||||
// Setup address filter.
|
||||
|
@ -123,7 +122,10 @@ impl Tor {
|
|||
pub fn rebuild_client() {
|
||||
let config = Self::build_config();
|
||||
let r_client = TOR_SERVER_STATE.client_config.read();
|
||||
r_client.0.reconfigure(&config, tor_config::Reconfigure::AllOrNothing).unwrap();
|
||||
r_client
|
||||
.0
|
||||
.reconfigure(&config, tor_config::Reconfigure::AllOrNothing)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Send post request using Tor.
|
||||
|
@ -144,15 +146,11 @@ impl Tor {
|
|||
// Send request.
|
||||
let mut resp = None;
|
||||
match http.request(req).await {
|
||||
Ok(r) => {
|
||||
match hyper::body::to_bytes(r).await {
|
||||
Ok(raw) => {
|
||||
resp = Some(String::from_utf8_lossy(&raw).to_string())
|
||||
Ok(r) => match hyper::body::to_bytes(r).await {
|
||||
Ok(raw) => resp = Some(String::from_utf8_lossy(&raw).to_string()),
|
||||
Err(_) => {}
|
||||
},
|
||||
Err(_) => {},
|
||||
}
|
||||
},
|
||||
Err(_) => {},
|
||||
Err(_) => {}
|
||||
}
|
||||
resp
|
||||
}
|
||||
|
@ -218,12 +216,28 @@ impl Tor {
|
|||
|
||||
let service_id = id.clone();
|
||||
thread::spawn(move || {
|
||||
let on_error = |service_id: String| {
|
||||
// Remove service from starting.
|
||||
let mut w_services = TOR_SERVER_STATE.starting_services.write();
|
||||
w_services.remove(&service_id);
|
||||
// Save failed service.
|
||||
let mut w_services = TOR_SERVER_STATE.failed_services.write();
|
||||
w_services.insert(service_id);
|
||||
};
|
||||
|
||||
let (client, config) = Self::client_config();
|
||||
let client_thread = client.clone();
|
||||
client.runtime().spawn(async move {
|
||||
client
|
||||
.runtime()
|
||||
.spawn(async move {
|
||||
// Add service key to keystore.
|
||||
let hs_nickname = HsNickname::new(service_id.clone()).unwrap();
|
||||
Self::add_service_key(config.fs_mistrust(), &key, &hs_nickname);
|
||||
if let Err(_) = Self::add_service_key(config.fs_mistrust(),
|
||||
&key,
|
||||
&hs_nickname) {
|
||||
on_error(service_id);
|
||||
return;
|
||||
}
|
||||
// Bootstrap client.
|
||||
client_thread.bootstrap().await.unwrap();
|
||||
// Launch Onion service.
|
||||
|
@ -231,23 +245,30 @@ impl Tor {
|
|||
.nickname(hs_nickname.clone())
|
||||
.build()
|
||||
.unwrap();
|
||||
if let Ok((service, request)) = client_thread.launch_onion_service(service_config) {
|
||||
if let Ok((service, request)) =
|
||||
client_thread.launch_onion_service(service_config)
|
||||
{
|
||||
// Launch service proxy.
|
||||
let addr = SocketAddr::new(IpAddr::from(Ipv4Addr::LOCALHOST), port);
|
||||
tokio::spawn(
|
||||
Self::run_service_proxy(addr,
|
||||
tokio::spawn(Self::run_service_proxy(
|
||||
addr,
|
||||
client_thread.clone(),
|
||||
service.clone(),
|
||||
request,
|
||||
hs_nickname.clone())
|
||||
).await.unwrap();
|
||||
hs_nickname.clone(),
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Check service availability if not checking.
|
||||
if Self::is_service_checking(&service_id) {
|
||||
return;
|
||||
}
|
||||
let client_check = client_thread.clone();
|
||||
let url = format!("http://{}/v2/foreign", service.onion_name().unwrap().to_string());
|
||||
let url = format!(
|
||||
"http://{}/v2/foreign",
|
||||
service.onion_name().unwrap().to_string()
|
||||
);
|
||||
thread::spawn(move || {
|
||||
// Wait 1 second to start.
|
||||
thread::sleep(Duration::from_millis(1000));
|
||||
|
@ -264,7 +285,8 @@ impl Tor {
|
|||
loop {
|
||||
if !Self::is_service_running(&service_id) {
|
||||
// Remove service from checking.
|
||||
let mut w_services = TOR_SERVER_STATE.checking_services.write();
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.checking_services.write();
|
||||
w_services.remove(&service_id);
|
||||
break;
|
||||
}
|
||||
|
@ -273,13 +295,19 @@ impl Tor {
|
|||
"jsonrpc": "2.0",
|
||||
"method": "check_version",
|
||||
"params": []
|
||||
}).to_string();
|
||||
})
|
||||
.to_string();
|
||||
// Bootstrap client.
|
||||
client_check.bootstrap().await.unwrap();
|
||||
// Create http tor-powered client to post data.
|
||||
let tls_connector = TlsConnector::builder().unwrap().build().unwrap();
|
||||
let tor_connector = ArtiHttpConnector::new(client_check.clone(), tls_connector);
|
||||
let http = hyper::Client::builder().build::<_, Body>(tor_connector);
|
||||
let tls_connector =
|
||||
TlsConnector::builder().unwrap().build().unwrap();
|
||||
let tor_connector = ArtiHttpConnector::new(
|
||||
client_check.clone(),
|
||||
tls_connector,
|
||||
);
|
||||
let http = hyper::Client::builder()
|
||||
.build::<_, Body>(tor_connector);
|
||||
// Create request.
|
||||
let req = hyper::Request::builder()
|
||||
.method(hyper::Method::POST)
|
||||
|
@ -290,11 +318,12 @@ impl Tor {
|
|||
let duration = match http.request(req).await {
|
||||
Ok(_) => {
|
||||
// Remove service from starting.
|
||||
let mut w_services = TOR_SERVER_STATE.starting_services.write();
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.starting_services.write();
|
||||
w_services.remove(&service_id);
|
||||
// Check again after 15 seconds.
|
||||
Duration::from_millis(15000)
|
||||
},
|
||||
}
|
||||
Err(_) => {
|
||||
// Restart service on 3rd error.
|
||||
errors_count += 1;
|
||||
|
@ -303,26 +332,27 @@ impl Tor {
|
|||
let key = key.clone();
|
||||
let service_id = service_id.clone();
|
||||
thread::spawn(move || {
|
||||
Self::restart_service(port, key, &service_id);
|
||||
Self::restart_service(
|
||||
port,
|
||||
key,
|
||||
&service_id,
|
||||
);
|
||||
});
|
||||
}
|
||||
Duration::from_millis(5000)
|
||||
},
|
||||
}
|
||||
};
|
||||
// Wait to check service again.
|
||||
sleep(duration).await;
|
||||
}
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
} else {
|
||||
// Remove service from starting.
|
||||
let mut w_services = TOR_SERVER_STATE.starting_services.write();
|
||||
w_services.remove(&service_id);
|
||||
// Save failed service.
|
||||
let mut w_services = TOR_SERVER_STATE.failed_services.write();
|
||||
w_services.insert(service_id);
|
||||
return;
|
||||
}
|
||||
|
||||
}).unwrap();
|
||||
on_error(service_id);
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -332,9 +362,8 @@ impl Tor {
|
|||
client: TorClient<R>,
|
||||
service: Arc<RunningOnionService>,
|
||||
request: S,
|
||||
nickname: HsNickname
|
||||
)
|
||||
where
|
||||
nickname: HsNickname,
|
||||
) where
|
||||
R: Runtime,
|
||||
S: futures::Stream<Item = tor_hsservice::RendRequest> + Unpin + Send + 'static,
|
||||
{
|
||||
|
@ -360,65 +389,60 @@ impl Tor {
|
|||
.spawn(async move {
|
||||
match proxy
|
||||
.handle_requests(runtime, nickname.clone(), request)
|
||||
.await {
|
||||
.await
|
||||
{
|
||||
Ok(()) => {
|
||||
// Remove service from running.
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.running_services.write();
|
||||
let mut w_services = TOR_SERVER_STATE.running_services.write();
|
||||
w_services.remove(&id);
|
||||
}
|
||||
Err(_) => {
|
||||
// Remove service from running.
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.running_services.write();
|
||||
let mut w_services = TOR_SERVER_STATE.running_services.write();
|
||||
w_services.remove(&id);
|
||||
// Save failed service.
|
||||
let mut w_services =
|
||||
TOR_SERVER_STATE.failed_services.write();
|
||||
let mut w_services = TOR_SERVER_STATE.failed_services.write();
|
||||
w_services.insert(id);
|
||||
}
|
||||
}
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Save Onion service key to keystore.
|
||||
fn add_service_key(mistrust: &Mistrust, key: &SecretKey, hs_nickname: &HsNickname) {
|
||||
fn add_service_key(
|
||||
mistrust: &Mistrust,
|
||||
key: &SecretKey,
|
||||
hs_nickname: &HsNickname,
|
||||
) -> tor_keymgr::Result<()> {
|
||||
let arti_store =
|
||||
ArtiNativeKeystore::from_path_and_mistrust(TorConfig::keystore_path(), &mistrust)
|
||||
.unwrap();
|
||||
ArtiNativeKeystore::from_path_and_mistrust(TorConfig::keystore_path(), &mistrust)?;
|
||||
|
||||
let key_manager = KeyMgrBuilder::default()
|
||||
.default_store(Box::new(arti_store))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let expanded_sk = ExpandedSecretKey::from_bytes(
|
||||
Sha512::default()
|
||||
.chain_update(key)
|
||||
.finalize()
|
||||
.as_ref(),
|
||||
);
|
||||
let expanded_sk =
|
||||
ExpandedSecretKey::from_bytes(Sha512::default().chain_update(key).finalize().as_ref());
|
||||
|
||||
let mut sk_bytes = [0_u8; 64];
|
||||
sk_bytes[0..32].copy_from_slice(&expanded_sk.scalar.to_bytes());
|
||||
sk_bytes[32..64].copy_from_slice(&expanded_sk.hash_prefix);
|
||||
let expanded_kp = ExpandedKeypair::from_secret_key_bytes(sk_bytes).unwrap();
|
||||
|
||||
key_manager
|
||||
.insert(
|
||||
key_manager.insert(
|
||||
HsIdKey::from(expanded_kp.public().clone()),
|
||||
&HsIdPublicKeySpecifier::new(hs_nickname.clone()),
|
||||
KeystoreSelector::Default,
|
||||
)
|
||||
.unwrap();
|
||||
)?;
|
||||
|
||||
key_manager
|
||||
.insert(
|
||||
key_manager.insert(
|
||||
HsIdKeypair::from(expanded_kp),
|
||||
&HsIdKeypairSpecifier::new(hs_nickname.clone()),
|
||||
KeystoreSelector::Default,
|
||||
)
|
||||
.unwrap();
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_snowflake(builder: &mut TorClientConfigBuilder, bin_path: String, conn_line: String) {
|
||||
|
|
Loading…
Reference in a new issue