Add key handling implementation

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/1/head
trivernis 4 years ago
parent cc8d18d288
commit ba005fc7bf
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

12
Cargo.lock generated

@ -21,6 +21,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bitflags"
version = "1.2.1"
@ -492,6 +498,8 @@ checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
name = "snekcloud-node"
version = "0.1.0"
dependencies = [
"base64",
"rand",
"rusqlite",
"vented",
]
@ -555,9 +563,9 @@ checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
[[package]]
name = "vented"
version = "0.1.0"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1b9a45811ac7741c477738e79759119950cc09f1afc2d53673b83560c35e53d"
checksum = "b92984cc8ed261509126ebc9b043c814e98f3d8da9dbf2e1d21e072c6906c8a7"
dependencies = [
"byteorder",
"crossbeam-utils",

@ -7,5 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
vented = "0.1.0"
vented = "0.1.2"
rusqlite = "0.24.1"
rand = "0.7.3"
base64 = "0.13.0"

@ -1,4 +1,5 @@
mod utils;
pub(crate) mod utils;
pub(crate) mod server;
fn main() {
unimplemented!()

@ -0,0 +1,37 @@
use vented::server::VentedServer;
use crate::utils::result::SnekcloudResult;
use vented::crypto::SecretKey;
use std::path::PathBuf;
use vented::server::data::Node;
use vented::WaitGroup;
pub struct SnekcloudServer {
inner: VentedServer,
listen_addresses: Vec<String>,
listeners: Vec<WaitGroup>,
}
impl SnekcloudServer {
/// Creates a new snekcloud server with the provided keys and number of threads
pub fn new(id: String, private_key: SecretKey, keys: Vec<Node>, num_threads: usize) -> Self {
Self {
inner: VentedServer::new(id, private_key, keys, num_threads),
listen_addresses: Vec::new(),
listeners: Vec::new(),
}
}
/// Adds an address the server should listen on
pub fn add_listen_address(&mut self, address: String) {
self.listen_addresses.push(address);
}
/// Starts listening on all addresses
pub fn run(&mut self) -> SnekcloudResult<()> {
for address in &self.listen_addresses {
self.listeners.push(self.inner.listen(address.clone()))
}
Ok(())
}
}

@ -0,0 +1,67 @@
use std::path::PathBuf;
use vented::crypto::{SecretKey, PublicKey};
use std::fs;
use crate::utils::result::{SnekcloudResult, SnekcloudError};
use vented::server::data::Node;
const PRIVATE_KEY_HEADER_LINE: &str = "---BEGIN-SNEKCLOUD-PRIVATE-KEY---\n";
const PRIVATE_KEY_FOOTER_LINE: &str = "\n---END-SNEKCLOUD-PRIVATE-KEY---";
const PUBLIC_KEY_HEADER_LINE: &str = "---BEGIN-SNEKCLOUD-PUBLIC-KEY---\n";
const PUBLIC_KEY_FOOTER_LINE: &str = "\n---END-SNEKCLOUD-PUBLIC-KEY---";
/// Reads a folder of node public keys
pub fn read_node_keys(path: &PathBuf) -> SnekcloudResult<Vec<Node>> {
let dir_content = path.read_dir()?;
let content = dir_content
.filter_map(|entry| {
let entry = entry.ok()?;
Some((entry.metadata().ok()?, entry))
})
.filter(|(meta, _)|meta.is_file())
.filter_map(|(_, entry)|{
let key = read_public_key(&entry.path()).ok()?;
let file_name = entry.file_name();
let file_name = file_name.to_string_lossy();
let node_id = file_name.trim_end_matches(".pub");
Some(Node {public_key: key, address: None, id: node_id.to_string()})
}).collect();
Ok(content)
}
/// Reads the private key from a file
pub fn read_private_key(filename: &PathBuf) -> SnekcloudResult<SecretKey> {
let content = fs::read_to_string(filename)?;
let bytes = extract_key(content, PUBLIC_KEY_HEADER_LINE, PUBLIC_KEY_FOOTER_LINE)?;
Ok(SecretKey::from(bytes))
}
/// Reads the public key from a file
pub fn read_public_key(filename: &PathBuf) -> SnekcloudResult<PublicKey> {
let content = fs::read_to_string(filename)?;
let bytes = extract_key(content, PUBLIC_KEY_HEADER_LINE, PUBLIC_KEY_FOOTER_LINE)?;
Ok(PublicKey::from(bytes))
}
/// Extracts a base64 encoded key between the prefix and suffix
fn extract_key(content: String, prefix: &str, suffix: &str) -> SnekcloudResult<[u8; 32]> {
let mut content = content.strip_prefix(prefix).ok_or(SnekcloudError::InvalidKey)?;
content = content.strip_suffix(suffix).ok_or(SnekcloudError::InvalidKey)?;
let key = base64::decode(content)?;
if key.len() != 32 {
return Err(SnekcloudError::InvalidKey);
}
let mut key_bytes = [0u8; 32];
key_bytes.copy_from_slice(&key[..]);
Ok(key_bytes)
}

@ -1 +1,2 @@
pub mod result;
pub mod keys;

@ -1,18 +1,26 @@
use vented::result::VentedError;
use std::fmt;
use std::io;
use std::error::Error;
pub type SnekcloudResult<T> = Result<T, SnekcloudError>;
#[derive(Debug)]
pub enum SnekcloudError {
Vented(VentedError),
IoError(io::Error),
Base64DecodeError(base64::DecodeError),
InvalidKey,
}
impl fmt::Display for SnekcloudError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Vented(v) => write!(f, "Vented Error: {}", v)
Self::Vented(v) => write!(f, "Vented Error: {}", v),
Self::IoError(e) => write!(f, "IO Error: {}", e),
Self::Base64DecodeError(e) => write!(f, "Base 64 Decode error: {}", e),
Self::InvalidKey => write!(f, "Invalid Key!"),
}
}
}
@ -24,3 +32,15 @@ impl From<VentedError> for SnekcloudError {
Self::Vented(error)
}
}
impl From<io::Error> for SnekcloudError {
fn from(error: io::Error) -> Self {
Self::IoError(error)
}
}
impl From<base64::DecodeError> for SnekcloudError {
fn from(error: base64::DecodeError) -> Self {
Self::Base64DecodeError(error)
}
}
Loading…
Cancel
Save