-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use JSON config file instead of arg command line
- Loading branch information
Thomas Prévost
committed
Feb 6, 2024
1 parent
c9712a3
commit 8822629
Showing
7 changed files
with
289 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
{ | ||
"this_kme": { | ||
"id": 1, | ||
"sqlite_db_path": ":memory:", | ||
"https_listen_address": "127.0.0.1:3000", | ||
"https_ca_client_cert_path": "certs/CA-zone1.crt", | ||
"https_server_cert_path": "certs/kme1.crt", | ||
"https_server_key_path": "certs/kme1.key" | ||
}, | ||
"other_kmes": [ | ||
{ | ||
"id": 1, | ||
"key_directory_to_watch": "raw_keys", | ||
"ip_address": "127.0.0.1" | ||
}, | ||
{ | ||
"id": 2, | ||
"key_directory_to_watch": "raw_keys", | ||
"ip_address": "127.0.0.1" | ||
} | ||
], | ||
"saes": [ | ||
{ | ||
"id": 1, | ||
"kme_id": 1, | ||
"https_client_certificate_serial": [ | ||
112, | ||
244, | ||
79, | ||
86, | ||
12, | ||
63, | ||
39, | ||
212, | ||
178, | ||
17, | ||
164, | ||
120, | ||
19, | ||
175, | ||
208, | ||
60, | ||
3, | ||
129, | ||
59, | ||
142 | ||
] | ||
}, | ||
{ | ||
"id": 2, | ||
"kme_id": 1, | ||
"https_client_certificate_serial": [ | ||
112, | ||
244, | ||
79, | ||
86, | ||
12, | ||
63, | ||
39, | ||
212, | ||
178, | ||
17, | ||
164, | ||
120, | ||
19, | ||
175, | ||
208, | ||
60, | ||
3, | ||
129, | ||
59, | ||
146 | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
//! Configuration module, contains structs used to deserialize JSON configuration and other material extraction functions | ||
use std::io; | ||
use serde::{Deserialize, Serialize}; | ||
use crate::{io_err, KmeId, SaeClientCertSerial, SaeId}; | ||
|
||
/// Whole KME config, to be extracted from JSON | ||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct Config { | ||
/// Config for this specific KME, including its ID and paths to certificates | ||
#[serde(rename = "this_kme")] | ||
pub this_kme_config: ThisKmeConfig, | ||
/// Configs for other KMEs, including their IDs and paths to directories to watch for new keys | ||
#[serde(rename = "other_kmes")] | ||
pub(crate) other_kme_configs: Vec<OtherKmeConfig>, | ||
/// Configs for SAEs, including their IDs, KMEs they are associated with and optional client certificate serials, if SAEs belong to this KME | ||
#[serde(rename = "saes")] | ||
pub(crate) sae_configs: Vec<SaeConfig> | ||
} | ||
|
||
impl Config { | ||
/// Extract configuration from JSON file | ||
pub fn from_json_path(json_config_file_path: &str) -> Result<Self, io::Error> { | ||
let config: Self = match std::fs::read_to_string(json_config_file_path) { | ||
Ok(json) => match serde_json::from_str(&json) { | ||
Ok(config) => config, | ||
Err(_) => return Err(io_err("Error deserializing JSON")) | ||
}, | ||
Err(_) => return Err(io_err("Error reading JSON file")) | ||
}; | ||
Ok(config) | ||
} | ||
} | ||
|
||
/// Config for this specific KME, including its ID and paths to certificates | ||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct ThisKmeConfig { | ||
/// ID of this KME, in the QKD network | ||
pub(crate) id: KmeId, | ||
/// Path to SQLite database file, used to store keys, certificates and other data | ||
/// You can use `:memory:` to use in-memory database | ||
pub(crate) sqlite_db_path: String, | ||
/// Address to listen for HTTPS connections | ||
pub https_listen_address: String, | ||
/// Server certificate authority certificate path, used to authenticate client SAEs | ||
pub https_ca_client_cert_path: String, | ||
/// Server HTTPS certificate path | ||
pub https_server_cert_path: String, | ||
/// Server HTTPS private key path | ||
pub https_server_key_path: String | ||
} | ||
|
||
/// Configs for other KMEs, including their IDs and paths to directories to watch for new keys | ||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct OtherKmeConfig { | ||
/// ID of the other KME, in the QKD network | ||
pub(crate) id: KmeId, | ||
/// Path to directory to read and watch for new keys, files must have [crate::QKD_KEY_FILE_EXTENSION](crate::QKD_KEY_FILE_EXTENSION) extension | ||
pub(crate) key_directory_to_watch: String, | ||
/// IP address of the other KME, used to send keys to it using "classical channel" | ||
pub(crate) ip_address: String, | ||
} | ||
|
||
/// Config for specific SAE: its ID, KME ID and optional client certificate serial | ||
#[derive(Serialize, Deserialize, Debug)] | ||
pub struct SaeConfig { | ||
/// ID of the SAE in QKD network | ||
pub(crate) id: SaeId, | ||
/// ID of the KME this SAE belongs to | ||
pub(crate) kme_id: KmeId, | ||
/// Client certificate serial number, used to authenticate SAEs to this KME if it belongs to, None otherwise | ||
pub(crate) https_client_certificate_serial: Option<SaeClientCertSerial> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,130 +1,37 @@ | ||
use std::io::{BufReader, Read}; | ||
use std::path::Path; | ||
use std::sync::Arc; | ||
use log::error; | ||
use clap::Parser; | ||
use notify::{EventKind, RecursiveMode, Watcher}; | ||
use notify::event::{AccessKind, AccessMode}; | ||
use qkd_kme_server::qkd_manager::{PreInitQkdKeyWrapper, QkdManager}; | ||
use qkd_kme_server::qkd_manager::QkdManager; | ||
use qkd_kme_server::routes::QKDKMERoutesV1; | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
simple_logger::SimpleLogger::new().init().unwrap(); | ||
let args = Args::parse(); | ||
|
||
println!("{:?}", args); | ||
|
||
|
||
let server = qkd_kme_server::server::Server { | ||
listen_addr: "127.0.0.1:3000".to_string(), | ||
ca_client_cert_path: "certs/CA-zone1.crt".to_string(), | ||
server_cert_path: "certs/kme1.crt".to_string(), | ||
server_key_path: "certs/kme1.key".to_string(), | ||
}; | ||
|
||
let qkd_manager = Arc::new(QkdManager::new(qkd_kme_server::MEMORY_SQLITE_DB_PATH, args.this_kme_id)); | ||
if qkd_manager.add_sae(1, | ||
1, | ||
&Some([0x70, 0xf4, 0x4f, 0x56, 0x0c, 0x3f, 0x27, 0xd4, 0xb2, 0x11, 0xa4, 0x78, 0x13, 0xaf, 0xd0, 0x3c, 0x03, 0x81, 0x3b, 0x8e]) | ||
).is_err() { | ||
error!("Error adding SAE to QKD manager"); | ||
return; | ||
} | ||
if qkd_manager.add_sae(2, | ||
1, | ||
&Some([0x70, 0xf4, 0x4f, 0x56, 0x0c, 0x3f, 0x27, 0xd4, 0xb2, 0x11, 0xa4, 0x78, 0x13, 0xaf, 0xd0, 0x3c, 0x03, 0x81, 0x3b, 0x92]) | ||
).is_err() { | ||
error!("Error adding SAE to QKD manager"); | ||
if std::env::args().len() != 2 { | ||
eprintln!("Usage: {} <path to json config file>", std::env::args().nth(0).unwrap()); | ||
return; | ||
} | ||
|
||
let mut watchers: Vec<notify::RecommendedWatcher> = Vec::new(); | ||
|
||
for kme_dir in args.dirs_to_watch_other_kme_ids { | ||
extract_all_keys_from_dir(&kme_dir.dir, kme_dir.kme_id, &qkd_manager); | ||
let kme_id = kme_dir.kme_id; | ||
let qkd_manager = Arc::clone(&qkd_manager); | ||
watchers.push(match notify::recommended_watcher(move |res: Result<notify::Event, notify::Error>| { | ||
match res { | ||
Ok(event) => { | ||
if let EventKind::Access(AccessKind::Close(AccessMode::Write)) = event.kind { | ||
extract_all_keys_from_file(&event.paths[0].to_str().unwrap(), kme_id, &qkd_manager); | ||
} | ||
} | ||
Err(e) => { | ||
println!("Watch error: {:?}", e); | ||
return; | ||
} | ||
} | ||
}) { | ||
Ok(watcher) => watcher, | ||
Err(e) => { | ||
error!("Error creating watcher: {:?}", e); | ||
return; | ||
} | ||
}); | ||
if watchers.iter_mut().last().unwrap().watch(Path::new(&kme_dir.dir), RecursiveMode::NonRecursive).is_err() { | ||
error!("Error watching directory: {:?}", kme_dir.dir); | ||
let config = match qkd_kme_server::config::Config::from_json_path(&std::env::args().nth(1).unwrap()) { | ||
Ok(config) => config, | ||
Err(e) => { | ||
eprintln!("Error reading config: {:?}", e); | ||
return; | ||
} | ||
} | ||
}; | ||
|
||
let server = qkd_kme_server::server::Server { | ||
listen_addr: config.this_kme_config.https_listen_address.clone(), | ||
ca_client_cert_path: config.this_kme_config.https_ca_client_cert_path.clone(), | ||
server_cert_path: config.this_kme_config.https_server_cert_path.clone(), | ||
server_key_path: config.this_kme_config.https_server_key_path.clone(), | ||
}; | ||
|
||
let qkd_manager= QkdManager::from_config(&config); | ||
println!("{:?}", qkd_manager.is_err()); | ||
let qkd_manager = qkd_manager.unwrap(); | ||
|
||
if server.run::<QKDKMERoutesV1>(&qkd_manager).await.is_err() { | ||
error!("Error running HTTP server"); | ||
return; | ||
} | ||
} | ||
|
||
#[derive(Parser, Debug)] | ||
struct Args { | ||
#[arg(long)] | ||
this_kme_id: i64, | ||
#[arg(long("kme_id,dir_watch"))] | ||
dirs_to_watch_other_kme_ids: Vec<DirWatchOtherKmesArgs>, | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
struct DirWatchOtherKmesArgs { | ||
dir: String, | ||
kme_id: i64, | ||
} | ||
|
||
impl std::str::FromStr for DirWatchOtherKmesArgs { | ||
type Err = std::io::Error; | ||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
let kme_id_and_dir = s.split(",").collect::<Vec<&str>>(); | ||
if kme_id_and_dir.len() != 2 { | ||
return Err(std::io::Error::other("Invalid format")); | ||
} | ||
let kme_id = i64::from_str(kme_id_and_dir[0]).map_err(|_| std::io::Error::other("Invalid format"))?; | ||
Ok(Self { | ||
dir: kme_id_and_dir[1].to_string(), | ||
kme_id, | ||
}) | ||
} | ||
} | ||
|
||
// TODO: move to QKD manager struct | ||
fn extract_all_keys_from_file(file_path: &str, other_kme_id: i64, qkd_manager: &QkdManager) { | ||
let file = std::fs::File::open(file_path).unwrap(); | ||
let mut reader = BufReader::with_capacity(32, file); | ||
let mut buffer = [0; 32]; | ||
while let Ok(_) = reader.read_exact(&mut buffer) { | ||
let qkd_key = PreInitQkdKeyWrapper::new( | ||
other_kme_id, | ||
&buffer, | ||
).unwrap(); | ||
qkd_manager.add_pre_init_qkd_key(qkd_key).unwrap(); | ||
} | ||
} | ||
|
||
fn extract_all_keys_from_dir(dir_path: &str, other_kme_id: i64, qkd_manager: &QkdManager) { | ||
let paths = std::fs::read_dir(dir_path).unwrap(); | ||
for path in paths { | ||
let path = path.unwrap().path(); | ||
if path.is_file() { | ||
extract_all_keys_from_file(path.to_str().unwrap(), other_kme_id, qkd_manager); | ||
} | ||
} | ||
} |
Oops, something went wrong.