appmgr: wrap up tor

This commit is contained in:
Aiden McClelland
2021-06-24 17:10:30 -06:00
committed by Aiden McClelland
parent 351ce2495d
commit 9630c356f4
12 changed files with 156 additions and 99 deletions

114
appmgr/src/net/interface.rs Normal file
View File

@@ -0,0 +1,114 @@
use std::net::Ipv4Addr;
use std::path::Path;
use indexmap::IndexMap;
use patch_db::DbHandle;
use serde::{Deserialize, Deserializer, Serialize};
use sqlx::{Executor, Sqlite};
use torut::onion::TorSecretKeyV3;
use crate::context::RpcContext;
use crate::db::model::{InterfaceAddressMap, InterfaceAddresses, InterfaceInfo};
use crate::id::Id;
use crate::s9pk::manifest::PackageId;
use crate::Error;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct Interfaces(pub IndexMap<InterfaceId, Interface>); // TODO
impl Interfaces {
pub async fn install<Ex>(
&self,
ctx: &RpcContext,
secrets: &mut Ex,
package_id: &PackageId,
ip: Ipv4Addr,
) -> Result<InterfaceInfo, Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let mut interface_info = InterfaceInfo {
ip,
addresses: InterfaceAddressMap(IndexMap::new()),
};
for (id, iface) in &self.0 {
let mut addrs = InterfaceAddresses {
tor_address: None,
lan_address: None,
};
if iface.tor_config.is_some() {
let key = TorSecretKeyV3::generate();
let key_vec = key.as_bytes().to_vec();
sqlx::query!(
"INSERT INTO tor (package, interface, key) VALUES (?, ?, ?)",
**package_id,
**id,
key_vec,
)
.execute(&mut *secrets)
.await?;
addrs.tor_address = Some(key.public().get_onion_address().to_string());
}
interface_info.addresses.0.insert(id.clone(), addrs);
}
todo!()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct InterfaceId<S: AsRef<str> = String>(Id<S>);
impl<S: AsRef<str>> std::fmt::Display for InterfaceId<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self.0)
}
}
impl<S: AsRef<str>> std::ops::Deref for InterfaceId<S> {
type Target = S;
fn deref(&self) -> &Self::Target {
&*self.0
}
}
impl<S: AsRef<str>> AsRef<str> for InterfaceId<S> {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl<'de, S> Deserialize<'de> for InterfaceId<S>
where
S: AsRef<str>,
Id<S>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(InterfaceId(Deserialize::deserialize(deserializer)?))
}
}
impl<S: AsRef<str>> AsRef<Path> for InterfaceId<S> {
fn as_ref(&self) -> &Path {
self.0.as_ref().as_ref()
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct Interface {
pub tor_config: Option<TorConfig>,
pub lan_config: Option<IndexMap<u16, LanPortConfig>>,
pub ui: bool,
pub protocols: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct TorConfig {
pub port_mapping: IndexMap<u16, u16>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct LanPortConfig {
pub ssl: bool,
pub mapping: u16,
}

View File

@@ -10,6 +10,7 @@ use crate::s9pk::manifest::PackageId;
use crate::{Error, ResultExt};
pub mod host;
pub mod interface;
#[cfg(feature = "avahi")]
pub mod mdns;
pub mod tor;

View File

@@ -6,14 +6,13 @@ use futures::future::BoxFuture;
use futures::FutureExt;
use indexmap::IndexMap;
use patch_db::DbHandle;
use sqlx::pool::PoolConnection;
use sqlx::Sqlite;
use sqlx::{Executor, Sqlite};
use tokio::net::TcpStream;
use tokio::sync::RwLock;
use torut::control::{AsyncEvent, AuthenticatedConn, ConnError};
use torut::onion::TorSecretKeyV3;
use crate::s9pk::manifest::TorConfig;
use super::interface::TorConfig;
use crate::{Error, ResultExt as _};
fn event_handler(event: AsyncEvent<'static>) -> BoxFuture<'static, Result<(), ConnError>> {
@@ -23,21 +22,23 @@ fn event_handler(event: AsyncEvent<'static>) -> BoxFuture<'static, Result<(), Co
#[derive(Clone)]
pub struct TorController(Arc<RwLock<TorControllerInner>>);
impl TorController {
pub async fn init<Db: DbHandle>(
pub async fn init<Db: DbHandle, Ex>(
tor_cp: SocketAddr,
db: &mut Db,
secrets: &mut PoolConnection<Sqlite>,
) -> Result<Self, Error> {
secrets: &mut Ex,
) -> Result<Self, Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
Ok(TorController(Arc::new(RwLock::new(
TorControllerInner::init(tor_cp, db, secrets).await?,
))))
}
pub async fn sync<Db: DbHandle>(
&self,
db: &mut Db,
secrets: &mut PoolConnection<Sqlite>,
) -> Result<(), Error> {
pub async fn sync<Db: DbHandle, Ex>(&self, db: &mut Db, secrets: &mut Ex) -> Result<(), Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let new = TorControllerInner::get_services(db, secrets).await?;
if &new != &self.0.read().await.services {
self.0.write().await.sync(new).await?;
@@ -62,10 +63,13 @@ pub struct TorControllerInner {
services: IndexMap<[u8; 64], HiddenServiceConfig>,
}
impl TorControllerInner {
async fn get_services<Db: DbHandle>(
async fn get_services<Db: DbHandle, Ex>(
db: &mut Db,
secrets: &mut PoolConnection<Sqlite>,
) -> Result<IndexMap<[u8; 64], HiddenServiceConfig>, Error> {
secrets: &mut Ex,
) -> Result<IndexMap<[u8; 64], HiddenServiceConfig>, Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let pkg_ids = crate::db::DatabaseModel::new()
.package_data()
.keys(db)
@@ -189,11 +193,14 @@ impl TorControllerInner {
Ok(())
}
async fn init<Db: DbHandle>(
async fn init<Db: DbHandle, Ex>(
tor_cp: SocketAddr,
db: &mut Db,
secrets: &mut PoolConnection<Sqlite>,
) -> Result<Self, Error> {
secrets: &mut Ex,
) -> Result<Self, Error>
where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{
let mut conn = torut::control::UnauthenticatedConn::new(
TcpStream::connect(tor_cp).await?, // TODO
);