mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-12-22 16:11:38 +03:00
reorganized register code to create keyfile on boot route
This commit is contained in:
parent
165746204a
commit
2784260c53
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4826,6 +4826,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"base64 0.13.1",
|
||||||
"bincode",
|
"bincode",
|
||||||
"blake3",
|
"blake3",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -16,6 +16,7 @@ aes-gcm = "0.10.2"
|
|||||||
anyhow = "1.0.71"
|
anyhow = "1.0.71"
|
||||||
async-recursion = "1.0.4"
|
async-recursion = "1.0.4"
|
||||||
async-trait = "0.1.71"
|
async-trait = "0.1.71"
|
||||||
|
base64 = "0.13.0"
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
blake3 = "1.4.1"
|
blake3 = "1.4.1"
|
||||||
bytes = "1.4.0"
|
bytes = "1.4.0"
|
||||||
|
@ -27,7 +27,6 @@ pub fn encode_keyfile(
|
|||||||
jwt: Vec<u8>,
|
jwt: Vec<u8>,
|
||||||
file_key: Vec<u8>,
|
file_key: Vec<u8>,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
println!("generating disk encryption keys...");
|
|
||||||
let mut disk_key: DiskKey = [0u8; CREDENTIAL_LEN];
|
let mut disk_key: DiskKey = [0u8; CREDENTIAL_LEN];
|
||||||
|
|
||||||
let rng = SystemRandom::new();
|
let rng = SystemRandom::new();
|
||||||
|
217
src/main.rs
217
src/main.rs
@ -169,9 +169,7 @@ async fn main() {
|
|||||||
{
|
{
|
||||||
ip
|
ip
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!( "\x1b[38;5;196mfailed to find public IPv4 address: booting as a routed node\x1b[0m");
|
||||||
"\x1b[38;5;196mfailed to find public IPv4 address: booting as a routed node\x1b[0m"
|
|
||||||
);
|
|
||||||
std::net::Ipv4Addr::LOCALHOST
|
std::net::Ipv4Addr::LOCALHOST
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -189,200 +187,35 @@ async fn main() {
|
|||||||
// that updates their PKI info on-chain.
|
// that updates their PKI info on-chain.
|
||||||
let http_server_port = http_server::find_open_port(8080).await.unwrap();
|
let http_server_port = http_server::find_open_port(8080).await.unwrap();
|
||||||
let (kill_tx, kill_rx) = oneshot::channel::<bool>();
|
let (kill_tx, kill_rx) = oneshot::channel::<bool>();
|
||||||
let keyfile = fs::read(format!("{}/.keys", home_directory_path)).await;
|
|
||||||
|
|
||||||
let (our, networking_keypair, jwt_secret_bytes, file_key): (
|
let disk_keyfile = match fs::read(format!("{}/.keys", home_directory_path)).await {
|
||||||
Identity,
|
Ok(keyfile) => keyfile,
|
||||||
signature::Ed25519KeyPair,
|
Err(_) => Vec::new(),
|
||||||
Vec<u8>,
|
|
||||||
Vec<u8>,
|
|
||||||
) = if keyfile.is_ok() {
|
|
||||||
// LOGIN flow
|
|
||||||
println!(
|
|
||||||
"\u{1b}]8;;{}\u{1b}\\{}\u{1b}]8;;\u{1b}\\",
|
|
||||||
format!("http://localhost:{}/login", http_server_port),
|
|
||||||
"Click here to log in to your node.",
|
|
||||||
);
|
|
||||||
println!("(http://localhost:{}/login)", http_server_port);
|
|
||||||
if our_ip != std::net::Ipv4Addr::LOCALHOST {
|
|
||||||
println!(
|
|
||||||
"(if on a remote machine: http://{}:{}/login)",
|
|
||||||
our_ip, http_server_port
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::channel::<(
|
|
||||||
String,
|
|
||||||
Vec<String>,
|
|
||||||
signature::Ed25519KeyPair,
|
|
||||||
Vec<u8>,
|
|
||||||
Vec<u8>,
|
|
||||||
)>(1);
|
|
||||||
let (username, routers, networking_keypair, jwt_secret_bytes, file_key) = tokio::select! {
|
|
||||||
_ = register::login(
|
|
||||||
tx,
|
|
||||||
kill_rx,
|
|
||||||
keyfile.unwrap(),
|
|
||||||
http_server_port,
|
|
||||||
) => panic!("login failed"),
|
|
||||||
(username, routers, networking_keypair, jwt_secret_bytes, file_key) = async {
|
|
||||||
while let Some(fin) = rx.recv().await {
|
|
||||||
return fin
|
|
||||||
}
|
|
||||||
panic!("login failed")
|
|
||||||
} => (username, routers, networking_keypair, jwt_secret_bytes, file_key),
|
|
||||||
};
|
|
||||||
|
|
||||||
// check if Identity for this username has correct networking keys,
|
|
||||||
// if not, prompt user to reset them.
|
|
||||||
let Ok(Ok(ws_rpc)) = timeout(
|
|
||||||
tokio::time::Duration::from_secs(10),
|
|
||||||
Provider::<Ws>::connect(rpc_url.clone()),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
else {
|
|
||||||
panic!("rpc: couldn't connect to blockchain wss endpoint. you MUST set an endpoint with --rpc flag, go to alchemy.com and get a free API key, then use the wss endpoint that looks like this: wss://eth-sepolia.g.alchemy.com/v2/<your-api-key>");
|
|
||||||
};
|
|
||||||
let Ok(Ok(_)) = timeout(
|
|
||||||
tokio::time::Duration::from_secs(10),
|
|
||||||
ws_rpc.get_block_number(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
else {
|
|
||||||
panic!("error: RPC endpoint not responding, try setting one with --rpc flag");
|
|
||||||
};
|
|
||||||
let qns_address: EthAddress = QNS_SEPOLIA_ADDRESS.parse().unwrap();
|
|
||||||
let contract = QNSRegistry::new(qns_address, ws_rpc.into());
|
|
||||||
let node_id: U256 = namehash(&username).as_bytes().into();
|
|
||||||
let Ok(onchain_id) = contract.ws(node_id).call().await else {
|
|
||||||
panic!("error: RPC endpoint failed to fetch our node_id");
|
|
||||||
};
|
|
||||||
print_sender
|
|
||||||
.send(Printout {
|
|
||||||
verbosity: 0,
|
|
||||||
content: "established connection to Sepolia RPC".to_string(),
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
// double check that routers match on-chain information
|
|
||||||
let namehashed_routers: Vec<[u8; 32]> = routers
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.map(|name| {
|
|
||||||
let hash = namehash(&name);
|
|
||||||
let mut result = [0u8; 32];
|
|
||||||
result.copy_from_slice(hash.as_bytes());
|
|
||||||
result
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// double check that keys match on-chain information
|
|
||||||
if onchain_id.routers != namehashed_routers
|
|
||||||
|| onchain_id.public_key != networking_keypair.public_key().as_ref()
|
|
||||||
|| (onchain_id.ip != 0
|
|
||||||
&& onchain_id.ip != <std::net::Ipv4Addr as Into<u32>>::into(our_ip))
|
|
||||||
{
|
|
||||||
panic!("CRITICAL: your routing information does not match on-chain records");
|
|
||||||
}
|
|
||||||
|
|
||||||
let our_identity = Identity {
|
|
||||||
name: username.clone(),
|
|
||||||
networking_key: format!(
|
|
||||||
"0x{}",
|
|
||||||
hex::encode(networking_keypair.public_key().as_ref())
|
|
||||||
),
|
|
||||||
ws_routing: if onchain_id.ip > 0 && onchain_id.port > 0 {
|
|
||||||
let ip = format!(
|
|
||||||
"{}.{}.{}.{}",
|
|
||||||
(onchain_id.ip >> 24) & 0xFF,
|
|
||||||
(onchain_id.ip >> 16) & 0xFF,
|
|
||||||
(onchain_id.ip >> 8) & 0xFF,
|
|
||||||
onchain_id.ip & 0xFF
|
|
||||||
);
|
|
||||||
Some((ip, onchain_id.port))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
allowed_routers: routers,
|
|
||||||
};
|
|
||||||
|
|
||||||
(
|
|
||||||
our_identity.clone(),
|
|
||||||
networking_keypair,
|
|
||||||
jwt_secret_bytes,
|
|
||||||
file_key,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// REGISTER flow
|
|
||||||
println!(
|
|
||||||
"\u{1b}]8;;{}\u{1b}\\{}\u{1b}]8;;\u{1b}\\",
|
|
||||||
format!("http://localhost:{}", http_server_port),
|
|
||||||
"Click here to register your node.",
|
|
||||||
);
|
|
||||||
println!("(http://localhost:{})", http_server_port);
|
|
||||||
if our_ip != std::net::Ipv4Addr::LOCALHOST {
|
|
||||||
println!(
|
|
||||||
"(if on a remote machine: http://{}:{})",
|
|
||||||
our_ip, http_server_port
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::channel::<(Identity, String, Document, Vec<u8>)>(1);
|
|
||||||
let (mut our, password, serialized_networking_keypair, jwt_secret_bytes) = tokio::select! {
|
|
||||||
_ = register::register(tx, kill_rx, our_ip.to_string(), http_server_port, http_server_port)
|
|
||||||
=> panic!("registration failed"),
|
|
||||||
(our, password, serialized_networking_keypair, jwt_secret_bytes) = async {
|
|
||||||
while let Some(fin) = rx.recv().await {
|
|
||||||
return fin
|
|
||||||
}
|
|
||||||
panic!("registration failed")
|
|
||||||
} => (our, password, serialized_networking_keypair, jwt_secret_bytes),
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"saving encrypted networking keys to {}/.keys",
|
|
||||||
home_directory_path
|
|
||||||
);
|
|
||||||
|
|
||||||
let networking_keypair =
|
|
||||||
signature::Ed25519KeyPair::from_pkcs8(serialized_networking_keypair.as_ref()).unwrap();
|
|
||||||
|
|
||||||
// TODO fix register frontend so this isn't necessary
|
|
||||||
our.networking_key = format!("0x{}", our.networking_key);
|
|
||||||
|
|
||||||
let file_key = keygen::generate_file_key();
|
|
||||||
|
|
||||||
fs::write(
|
|
||||||
format!("{}/.keys", home_directory_path),
|
|
||||||
keygen::encode_keyfile(
|
|
||||||
password,
|
|
||||||
our.name.clone(),
|
|
||||||
our.allowed_routers.clone(),
|
|
||||||
serialized_networking_keypair,
|
|
||||||
jwt_secret_bytes.clone(),
|
|
||||||
file_key.clone(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
println!("registration complete!");
|
|
||||||
(
|
|
||||||
our,
|
|
||||||
networking_keypair,
|
|
||||||
jwt_secret_bytes.to_vec(),
|
|
||||||
file_key.to_vec(),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1);
|
||||||
|
let (mut our, decoded_keyfile, encoded_keyfile) = tokio::select! {
|
||||||
|
_ = register::register(tx, kill_rx, our_ip.to_string(), http_server_port, disk_keyfile)
|
||||||
|
=> panic!("registration failed"),
|
||||||
|
(our, decoded_keyfile, encoded_keyfile) = async {
|
||||||
|
while let Some(fin) = rx.recv().await { return fin }
|
||||||
|
panic!("registration failed")
|
||||||
|
} => (our, decoded_keyfile, encoded_keyfile),
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("saving encrypted networking keys to {}/.keys", home_directory_path);
|
||||||
|
|
||||||
|
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile)
|
||||||
|
.await.unwrap();
|
||||||
|
|
||||||
|
println!("registration complete!");
|
||||||
|
|
||||||
let (kernel_process_map, manifest, vfs_messages) = filesystem::load_fs(
|
let (kernel_process_map, manifest, vfs_messages) = filesystem::load_fs(
|
||||||
our.name.clone(),
|
our.name.clone(),
|
||||||
home_directory_path.clone(),
|
home_directory_path.clone(),
|
||||||
file_key,
|
decoded_keyfile.file_key,
|
||||||
fs_config,
|
fs_config,
|
||||||
)
|
).await.expect("fs load failed!");
|
||||||
.await
|
|
||||||
.expect("fs load failed!");
|
|
||||||
|
|
||||||
let _ = kill_tx.send(true);
|
let _ = kill_tx.send(true);
|
||||||
let _ = print_sender
|
let _ = print_sender
|
||||||
@ -398,7 +231,7 @@ async fn main() {
|
|||||||
*
|
*
|
||||||
* if any of these modules fail, the program exits with an error.
|
* if any of these modules fail, the program exits with an error.
|
||||||
*/
|
*/
|
||||||
let networking_keypair_arc = Arc::new(networking_keypair);
|
let networking_keypair_arc = Arc::new(decoded_keyfile.networking_keypair);
|
||||||
|
|
||||||
let mut tasks = tokio::task::JoinSet::<Result<()>>::new();
|
let mut tasks = tokio::task::JoinSet::<Result<()>>::new();
|
||||||
tasks.spawn(kernel::kernel(
|
tasks.spawn(kernel::kernel(
|
||||||
@ -443,7 +276,7 @@ async fn main() {
|
|||||||
tasks.spawn(http_server::http_server(
|
tasks.spawn(http_server::http_server(
|
||||||
our.name.clone(),
|
our.name.clone(),
|
||||||
http_server_port,
|
http_server_port,
|
||||||
jwt_secret_bytes.clone(),
|
decoded_keyfile.jwt_secret_bytes.clone(),
|
||||||
http_server_receiver,
|
http_server_receiver,
|
||||||
kernel_message_sender.clone(),
|
kernel_message_sender.clone(),
|
||||||
print_sender.clone(),
|
print_sender.clone(),
|
||||||
|
196
src/register.rs
196
src/register.rs
@ -1,4 +1,5 @@
|
|||||||
use aes_gcm::aead::KeyInit;
|
use aes_gcm::aead::KeyInit;
|
||||||
|
use base64;
|
||||||
use hmac::Hmac;
|
use hmac::Hmac;
|
||||||
use jwt::SignWithKey;
|
use jwt::SignWithKey;
|
||||||
use ring::pkcs8::Document;
|
use ring::pkcs8::Document;
|
||||||
@ -8,15 +9,15 @@ use sha2::Sha256;
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
use warp::{
|
use warp::{
|
||||||
http::header::{HeaderValue, SET_COOKIE},
|
http::{ StatusCode, header::{HeaderValue, SET_COOKIE}, },
|
||||||
Filter, Rejection, Reply,
|
Filter, Rejection, Reply,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::http_server;
|
use crate::http_server;
|
||||||
use crate::keygen;
|
use crate::keygen;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
type RegistrationSender = mpsc::Sender<(Identity, String, Document, Vec<u8>)>;
|
type RegistrationSender = mpsc::Sender<(Identity, Keyfile, Vec<u8>)>;
|
||||||
|
|
||||||
pub fn generate_jwt(jwt_secret_bytes: &[u8], username: String) -> Option<String> {
|
pub fn generate_jwt(jwt_secret_bytes: &[u8], username: String) -> Option<String> {
|
||||||
let jwt_secret: Hmac<Sha256> = match Hmac::new_from_slice(&jwt_secret_bytes) {
|
let jwt_secret: Hmac<Sha256> = match Hmac::new_from_slice(&jwt_secret_bytes) {
|
||||||
@ -41,36 +42,47 @@ pub async fn register(
|
|||||||
kill_rx: oneshot::Receiver<bool>,
|
kill_rx: oneshot::Receiver<bool>,
|
||||||
ip: String,
|
ip: String,
|
||||||
port: u16,
|
port: u16,
|
||||||
redir_port: u16,
|
keyfile: Vec<u8>
|
||||||
) {
|
) {
|
||||||
let our = Arc::new(Mutex::new(None));
|
|
||||||
let networking_keypair = Arc::new(Mutex::new(None));
|
|
||||||
|
|
||||||
let our_get = our.clone();
|
let our_arc = Arc::new(Mutex::new(None));
|
||||||
let networking_keypair_post = networking_keypair.clone();
|
let our_ws_info = our_arc.clone();
|
||||||
|
|
||||||
|
let net_keypair_arc = Arc::new(Mutex::new(None));
|
||||||
|
let net_keypair_ws_info = net_keypair_arc.clone();
|
||||||
|
|
||||||
|
let keyfile_arc = Arc::new(Mutex::new(Some(keyfile)));
|
||||||
|
let keyfile_has = keyfile_arc.clone();
|
||||||
|
|
||||||
let static_files = warp::path("static").and(warp::fs::dir("./src/register/build/static/"));
|
let static_files = warp::path("static").and(warp::fs::dir("./src/register/build/static/"));
|
||||||
let react_app = warp::path::end()
|
let react_app = warp::path::end()
|
||||||
.and(warp::get())
|
.and(warp::get())
|
||||||
.and(warp::fs::file("./src/register/build/index.html"));
|
.and(warp::fs::file("./src/register/build/index.html"));
|
||||||
|
|
||||||
let api = warp::path("get-ws-info").and(
|
let api = warp::path("has-keyfile")
|
||||||
// 1. Get uqname (already on chain) and return networking information
|
.and(warp::get()
|
||||||
warp::get()
|
.and(warp::any().map(move || keyfile_has.clone()))
|
||||||
.and(warp::any().map(move || ip.clone()))
|
.and_then(handle_has_keyfile))
|
||||||
.and(warp::any().map(move || our_get.clone()))
|
.or(warp::path("info")
|
||||||
.and(warp::any().map(move || networking_keypair_post.clone()))
|
.and(warp::get()
|
||||||
.and_then(handle_get)
|
.and(warp::any().map(move || ip.clone()))
|
||||||
// 2. trigger for finalizing registration once on-chain actions are done
|
.and(warp::any().map(move || our_ws_info.clone()))
|
||||||
.or(warp::post()
|
.and(warp::any().map(move || net_keypair_ws_info.clone()))
|
||||||
.and(warp::body::content_length_limit(1024 * 16))
|
.and_then(handle_info)))
|
||||||
|
.or(warp::path("vet-keyfile")
|
||||||
|
.and(warp::post()
|
||||||
|
.and(warp::body::content_length_limit(1024 * 16))
|
||||||
|
.and(warp::body::json())
|
||||||
|
.and_then(handle_keyfile_check)))
|
||||||
|
.or(warp::path("boot")
|
||||||
|
.and(warp::put()
|
||||||
|
.and(warp::body::content_length_limit(1024 * 16))
|
||||||
.and(warp::body::json())
|
.and(warp::body::json())
|
||||||
.and(warp::any().map(move || tx.clone()))
|
.and(warp::any().map(move || tx.clone()))
|
||||||
.and(warp::any().map(move || our.lock().unwrap().take().unwrap()))
|
.and(warp::any().map(move || our_arc.lock().unwrap().take().unwrap()))
|
||||||
.and(warp::any().map(move || networking_keypair.lock().unwrap().take().unwrap()))
|
.and(warp::any().map(move || net_keypair_arc.lock().unwrap().take().unwrap()))
|
||||||
.and(warp::any().map(move || redir_port))
|
.and(warp::any().map(move || keyfile_arc.lock().unwrap().take().unwrap()))
|
||||||
.and_then(handle_post)),
|
.and_then(handle_boot)));
|
||||||
);
|
|
||||||
|
|
||||||
let routes = static_files.or(react_app).or(api);
|
let routes = static_files.or(react_app).or(api);
|
||||||
|
|
||||||
@ -83,14 +95,130 @@ pub async fn register(
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_get(
|
async fn handle_has_keyfile(
|
||||||
|
keyfile: Arc<Mutex<Option<Vec<u8>>>>,
|
||||||
|
) -> Result<impl Reply, Rejection> {
|
||||||
|
|
||||||
|
Ok(warp::reply::json(&keyfile.lock().unwrap().is_some()))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_keyfile_check(
|
||||||
|
payload: KeyfileCheck
|
||||||
|
) -> Result<impl Reply, Rejection> {
|
||||||
|
|
||||||
|
let keyfile = base64::decode(payload.keyfile).unwrap();
|
||||||
|
|
||||||
|
match keygen::decode_keyfile(keyfile, &payload.password) {
|
||||||
|
Ok(_) => Ok(warp::reply::with_status(warp::reply(), StatusCode::OK)),
|
||||||
|
Err(_) => Err(warp::reject()),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_keyfile_gen(
|
||||||
|
payload: Registration,
|
||||||
|
our: Arc<Mutex<Option<Identity>>>,
|
||||||
|
networking_keypair: Arc<Mutex<Option<Document>>>,
|
||||||
|
jwt_secret: Arc<Mutex<Option<Vec<u8>>>>,
|
||||||
|
) -> Result<impl Reply, Rejection> {
|
||||||
|
|
||||||
|
Ok(warp::reply::with_status(warp::reply(), StatusCode::OK))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_boot(
|
||||||
|
info: BootInfo,
|
||||||
|
sender: RegistrationSender,
|
||||||
|
mut our: Identity,
|
||||||
|
networking_keypair: Document,
|
||||||
|
mut encoded_keyfile: Vec<u8>,
|
||||||
|
) -> Result<impl Reply, Rejection> {
|
||||||
|
|
||||||
|
println!("hello");
|
||||||
|
|
||||||
|
if info.direct {
|
||||||
|
our.allowed_routers = vec![];
|
||||||
|
} else {
|
||||||
|
our.ws_routing = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("~~~~~");
|
||||||
|
|
||||||
|
if encoded_keyfile.is_empty() && !info.keyfile.is_empty() {
|
||||||
|
match base64::decode(info.keyfile) {
|
||||||
|
Ok(k) => encoded_keyfile = k,
|
||||||
|
Err(_) => return Err(warp::reject()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("_____");
|
||||||
|
|
||||||
|
let decoded_keyfile = if !encoded_keyfile.is_empty() {
|
||||||
|
match keygen::decode_keyfile(encoded_keyfile.clone(), &info.password) {
|
||||||
|
Ok(k) => k,
|
||||||
|
Err(_) => return Err(warp::reject()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let seed = SystemRandom::new();
|
||||||
|
let mut jwt_secret = [0u8, 32];
|
||||||
|
ring::rand::SecureRandom::fill(&seed, &mut jwt_secret).unwrap();
|
||||||
|
|
||||||
|
let networking_pair = signature::Ed25519KeyPair::from_pkcs8(networking_keypair.as_ref()).unwrap();
|
||||||
|
|
||||||
|
Keyfile {
|
||||||
|
username: our.name.clone(),
|
||||||
|
routers: our.allowed_routers.clone(),
|
||||||
|
networking_keypair: signature::Ed25519KeyPair
|
||||||
|
::from_pkcs8(networking_keypair.as_ref()).unwrap(),
|
||||||
|
jwt_secret_bytes: jwt_secret.to_vec(),
|
||||||
|
file_key: keygen::generate_file_key(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(">>>>>");
|
||||||
|
|
||||||
|
if encoded_keyfile.is_empty() {
|
||||||
|
encoded_keyfile = keygen::encode_keyfile(
|
||||||
|
info.password,
|
||||||
|
decoded_keyfile.username.clone(),
|
||||||
|
decoded_keyfile.routers.clone(),
|
||||||
|
networking_keypair,
|
||||||
|
decoded_keyfile.jwt_secret_bytes.clone(),
|
||||||
|
decoded_keyfile.file_key.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("<<<<<");
|
||||||
|
|
||||||
|
let token = match generate_jwt(&decoded_keyfile.jwt_secret_bytes, our.name.clone()) {
|
||||||
|
Some(token) => token,
|
||||||
|
None => return Err(warp::reject()),
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.send((our.clone(), decoded_keyfile, encoded_keyfile.clone())).await.unwrap();
|
||||||
|
|
||||||
|
let mut response = warp::reply::html("Success".to_string()).into_response();
|
||||||
|
|
||||||
|
println!("ioioioio");
|
||||||
|
|
||||||
|
let headers = response.headers_mut();
|
||||||
|
headers.append(SET_COOKIE, HeaderValue::from_str(
|
||||||
|
&format!("uqbar-auth_{}={};", &our.name, &token)).unwrap());
|
||||||
|
headers.append(SET_COOKIE, HeaderValue::from_str(
|
||||||
|
&format!("uqbar-ws-auth_{}={};", &our.name, &token)).unwrap());
|
||||||
|
|
||||||
|
Ok(warp::reply::with_status(warp::reply(), StatusCode::OK))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_info(
|
||||||
ip: String,
|
ip: String,
|
||||||
our_get: Arc<Mutex<Option<Identity>>>,
|
our_arc: Arc<Mutex<Option<Identity>>>,
|
||||||
networking_keypair_post: Arc<Mutex<Option<Document>>>,
|
networking_keypair_arc: Arc<Mutex<Option<Document>>>,
|
||||||
) -> Result<impl Reply, Rejection> {
|
) -> Result<impl Reply, Rejection> {
|
||||||
// 1. Generate networking keys
|
// 1. Generate networking keys
|
||||||
let (public_key, serialized_networking_keypair) = keygen::generate_networking_key();
|
let (public_key, serialized_networking_keypair) = keygen::generate_networking_key();
|
||||||
*networking_keypair_post.lock().unwrap() = Some(serialized_networking_keypair);
|
*networking_keypair_arc.lock().unwrap() = Some(serialized_networking_keypair);
|
||||||
|
|
||||||
// 2. set our...
|
// 2. set our...
|
||||||
// TODO: if IP is localhost, assign a router...
|
// TODO: if IP is localhost, assign a router...
|
||||||
@ -107,10 +235,10 @@ async fn handle_get(
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
*our_get.lock().unwrap() = Some(our.clone());
|
*our_arc.lock().unwrap() = Some(our.clone());
|
||||||
|
|
||||||
// return response containing networking information
|
|
||||||
Ok(warp::reply::json(&our))
|
Ok(warp::reply::json(&our))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_post(
|
async fn handle_post(
|
||||||
@ -118,7 +246,7 @@ async fn handle_post(
|
|||||||
sender: RegistrationSender,
|
sender: RegistrationSender,
|
||||||
mut our: Identity,
|
mut our: Identity,
|
||||||
networking_keypair: Document,
|
networking_keypair: Document,
|
||||||
_redir_port: u16,
|
keyfile: Vec<u8>,
|
||||||
) -> Result<impl Reply, Rejection> {
|
) -> Result<impl Reply, Rejection> {
|
||||||
if info.direct {
|
if info.direct {
|
||||||
our.allowed_routers = vec![];
|
our.allowed_routers = vec![];
|
||||||
@ -139,10 +267,10 @@ async fn handle_post(
|
|||||||
let cookie_value = format!("uqbar-auth_{}={};", &our.name, &token);
|
let cookie_value = format!("uqbar-auth_{}={};", &our.name, &token);
|
||||||
let ws_cookie_value = format!("uqbar-ws-auth_{}={};", &our.name, &token);
|
let ws_cookie_value = format!("uqbar-ws-auth_{}={};", &our.name, &token);
|
||||||
|
|
||||||
sender
|
// sender
|
||||||
.send((our, info.password, networking_keypair, jwt_secret.to_vec()))
|
// .send((our, info.password, networking_keypair, jwt_secret.to_vec(), keyfile))
|
||||||
.await
|
// .await
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
let mut response = warp::reply::html("Success".to_string()).into_response();
|
let mut response = warp::reply::html("Success".to_string()).into_response();
|
||||||
|
|
||||||
|
14
src/types.rs
14
src/types.rs
@ -53,6 +53,20 @@ pub struct Registration {
|
|||||||
pub direct: bool,
|
pub direct: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct KeyfileCheck {
|
||||||
|
pub password: String,
|
||||||
|
pub keyfile: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct BootInfo {
|
||||||
|
pub password: String,
|
||||||
|
pub keyfile: String,
|
||||||
|
pub username: String,
|
||||||
|
pub direct: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Identity {
|
pub struct Identity {
|
||||||
pub name: NodeId,
|
pub name: NodeId,
|
||||||
|
Loading…
Reference in New Issue
Block a user