From 6093518e46c1d19e72a68f1154bac55d13d1dd80 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Tue, 31 Aug 2021 11:44:08 -0600 Subject: [PATCH] load os tor key from db --- appmgr/Cargo.lock | 2 +- appmgr/migrations/20210629193146_Init.sql | 6 +++-- appmgr/sqlx-data.json | 26 ++++++++++++++++---- appmgr/src/auth.rs | 4 ++-- appmgr/src/context/rpc.rs | 2 +- appmgr/src/hostname.rs | 1 + appmgr/src/net/tor.rs | 29 +++++++++++++++++++++-- 7 files changed, 58 insertions(+), 12 deletions(-) diff --git a/appmgr/Cargo.lock b/appmgr/Cargo.lock index 8cd146e3d..c3abe3ffa 100644 --- a/appmgr/Cargo.lock +++ b/appmgr/Cargo.lock @@ -3270,7 +3270,7 @@ dependencies = [ "either", "futures-util", "thiserror", - "tokio 1.9.0", + "tokio 1.10.1", ] [[package]] diff --git a/appmgr/migrations/20210629193146_Init.sql b/appmgr/migrations/20210629193146_Init.sql index 2dfe21467..9668764df 100644 --- a/appmgr/migrations/20210629193146_Init.sql +++ b/appmgr/migrations/20210629193146_Init.sql @@ -15,9 +15,11 @@ CREATE TABLE IF NOT EXISTS session user_agent TEXT, metadata TEXT NOT NULL DEFAULT 'null' ); -CREATE TABLE IF NOT EXISTS password +CREATE TABLE IF NOT EXISTS account ( - hash TEXT NOT NULL PRIMARY KEY + id INTEGER PRIMARY KEY CHECK (id = 0), + password TEXT NOT NULL, + tor_key BLOB NOT NULL ); CREATE TABLE IF NOT EXISTS ssh_keys ( diff --git a/appmgr/sqlx-data.json b/appmgr/sqlx-data.json index c88bcc693..cf1fec4b4 100644 --- a/appmgr/sqlx-data.json +++ b/appmgr/sqlx-data.json @@ -20,14 +20,14 @@ "nullable": [] } }, - "3efd0daa61f4f8bead1adbe78a8225bc31fb940406d0415b578d3adc03a5e414": { - "query": "SELECT hash FROM password", + "3502e58f2ab48fb4566d21c920c096f81acfa3ff0d02f970626a4dcd67bac71d": { + "query": "SELECT tor_key FROM account", "describe": { "columns": [ { - "name": "hash", + "name": "tor_key", "ordinal": 0, - "type_info": "Text" + "type_info": "Blob" } ], "parameters": { @@ -86,6 +86,24 @@ ] } }, + "629be61c3c341c131ddbbff0293a83dbc6afd07cae69d246987f62cf0cc35c2a": { + "query": "SELECT password FROM account", + "describe": { + "columns": [ + { + "name": "password", + "ordinal": 0, + "type_info": "Text" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false + ] + } + }, "63785dc5f193ea31e6f641a910c75857ccd288a3f6e9c4f704331531e4f0689f": { "query": "UPDATE session SET last_active = CURRENT_TIMESTAMP WHERE id = ? AND logged_out IS NULL OR logged_out > CURRENT_TIMESTAMP", "describe": { diff --git a/appmgr/src/auth.rs b/appmgr/src/auth.rs index 7f5f51455..d38ff812c 100644 --- a/appmgr/src/auth.rs +++ b/appmgr/src/auth.rs @@ -55,10 +55,10 @@ pub async fn login( ) -> Result<(), Error> { let rpc_ctx = ctx.as_rpc().unwrap(); let mut handle = rpc_ctx.secret_store.acquire().await?; - let pw_hash = sqlx::query!("SELECT hash FROM password") + let pw_hash = sqlx::query!("SELECT password FROM account") .fetch_one(&mut handle) .await? - .hash; + .password; ensure_code!( argon2::verify_encoded(&pw_hash, password.as_bytes()).map_err(|_| { Error::new( diff --git a/appmgr/src/context/rpc.rs b/appmgr/src/context/rpc.rs index 45ed91fe3..83a61fb89 100644 --- a/appmgr/src/context/rpc.rs +++ b/appmgr/src/context/rpc.rs @@ -83,7 +83,7 @@ impl RpcContext { let net_controller = Arc::new( NetController::init( ([127, 0, 0, 1], 80).into(), - todo!("Grab Key from Database, Generate if it doesn't exist"), + crate::net::tor::os_key(&mut secret_store.acquire().await?).await?, base.tor_control .unwrap_or(SocketAddr::from(([127, 0, 0, 1], 9051))), ) diff --git a/appmgr/src/hostname.rs b/appmgr/src/hostname.rs index 3e5cc7005..cde0cc0c8 100644 --- a/appmgr/src/hostname.rs +++ b/appmgr/src/hostname.rs @@ -26,6 +26,7 @@ pub async fn get_product_key() -> Result { Ok(out.trim().to_owned()) } +// cat /boot/product_key.txt | shasum -a 256 | head -c 8 | awk '{print "start9-"$1}' | xargs hostnamectl set-hostname pub async fn sync_hostname() -> Result<(), Error> { let key = get_product_key().await?; let mut hasher = sha2::Sha256::new(); diff --git a/appmgr/src/net/tor.rs b/appmgr/src/net/tor.rs index 3294679bc..b894316db 100644 --- a/appmgr/src/net/tor.rs +++ b/appmgr/src/net/tor.rs @@ -5,16 +5,41 @@ use std::time::Duration; use anyhow::anyhow; use futures::future::BoxFuture; use futures::FutureExt; +use sqlx::{Executor, Sqlite}; use tokio::net::TcpStream; use tokio::sync::Mutex; use torut::control::{AsyncEvent, AuthenticatedConn, ConnError}; -use torut::onion::{OnionAddressV3, TorSecretKey, TorSecretKeyV3}; +use torut::onion::{OnionAddressV3, TorSecretKeyV3}; use super::interface::{InterfaceId, TorConfig}; use crate::s9pk::manifest::PackageId; use crate::{Error, ErrorKind, ResultExt as _}; -fn event_handler(event: AsyncEvent<'static>) -> BoxFuture<'static, Result<(), ConnError>> { +#[test] +fn random_key() { + println!("'0x{}'", hex::encode(TorSecretKeyV3::generate().as_bytes())); +} + +pub async fn os_key(secrets: &mut Ex) -> Result +where + for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>, +{ + let key = sqlx::query!("SELECT tor_key FROM account") + .fetch_one(secrets) + .await? + .tor_key; + + let mut buf = [0; 64]; + buf.clone_from_slice(key.get(0..64).ok_or_else(|| { + Error::new( + anyhow!("Invalid Tor Key Length"), + crate::ErrorKind::Database, + ) + })?); + Ok(buf.into()) +} + +fn event_handler(_event: AsyncEvent<'static>) -> BoxFuture<'static, Result<(), ConnError>> { async move { Ok(()) }.boxed() }