diff --git a/dnapi-rs/src/message.rs b/dnapi-rs/src/message.rs index 68172a7..e3a934f 100644 --- a/dnapi-rs/src/message.rs +++ b/dnapi-rs/src/message.rs @@ -2,7 +2,6 @@ use base64_serde::base64_serde_type; use serde::{Deserialize, Serialize}; -use serde_with::serde_as; /// The version 1 `DNClient` API endpoint pub const ENDPOINT_V1: &str = "/v1/dnclient"; @@ -201,9 +200,9 @@ pub struct APIError { pub type APIErrors = Vec; mod b64_as { - use serde::{Serialize, Deserialize}; - use serde::{Deserializer, Serializer}; use base64::Engine; + use serde::{Deserialize, Serialize}; + use serde::{Deserializer, Serializer}; pub fn serialize(v: &Vec, s: S) -> Result { let base64 = base64::engine::general_purpose::STANDARD.encode(v); @@ -212,13 +211,13 @@ mod b64_as { pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { let base64 = >::deserialize(d)?; - match base64 { - Some(v) => { - base64::engine::general_purpose::STANDARD.decode(v.as_bytes()) - .map(|v| v) - .map_err(|e| serde::de::Error::custom(e)) + base64.map_or_else( + || Ok(vec![]), + |v| { + base64::engine::general_purpose::STANDARD + .decode(v.as_bytes()) + .map_err(serde::de::Error::custom) }, - None => Ok(vec![]), - } + ) } -} \ No newline at end of file +} diff --git a/tfclient/src/daemon.rs b/tfclient/src/daemon.rs index b39aed8..72cf9f7 100644 --- a/tfclient/src/daemon.rs +++ b/tfclient/src/daemon.rs @@ -6,7 +6,7 @@ use std::thread; use crate::apiworker::{apiworker_main, APIWorkerMessage}; use crate::config::load_config; -use crate::nebulaworker::{nebulaworker_main, NebulaWorkerMessage}; +use crate::nebulaworker::NebulaWorkerMessage; use crate::socketworker::{socketworker_main, SocketWorkerMessage}; use crate::timerworker::{timer_main, TimerWorkerMessage}; use crate::util::check_server_url; @@ -28,7 +28,7 @@ pub fn daemon_main(name: String, server: String) { let (tx_api, rx_api) = mpsc::channel::(); let (tx_socket, rx_socket) = mpsc::channel::(); - let (tx_nebula, rx_nebula) = mpsc::channel::(); + let (tx_nebula, _rx_nebula) = mpsc::channel::(); let (tx_timer, rx_timer) = mpsc::channel::(); let transmitter = ThreadMessageSender { @@ -108,9 +108,9 @@ pub fn daemon_main(name: String, server: String) { }); info!("Starting Nebula thread..."); - let config_nebula = config.clone(); - let transmitter_nebula = transmitter.clone(); - let name_nebula = name.clone(); + let _config_nebula = config.clone(); + let _transmitter_nebula = transmitter.clone(); + let _name_nebula = name.clone(); //let nebula_thread = thread::spawn(move || { // nebulaworker_main(config_nebula, name_nebula, transmitter_nebula, rx_nebula); //}); diff --git a/trifid-api/src/codegen/mod.rs b/trifid-api/src/codegen/mod.rs index b8e1df9..8489316 100644 --- a/trifid-api/src/codegen/mod.rs +++ b/trifid-api/src/codegen/mod.rs @@ -6,19 +6,26 @@ use std::time::{Duration, SystemTime}; use actix_web::web::Data; -use crate::config::{NebulaConfig, NebulaConfigCipher, NebulaConfigLighthouse, NebulaConfigListen, NebulaConfigPki, NebulaConfigPunchy, NebulaConfigRelay, NebulaConfigTun, CONFIG, NebulaConfigFirewall, NebulaConfigFirewallRule}; -use crate::crypto::{decrypt_with_nonce, encrypt_with_nonce, get_cipher_from_config}; +use crate::config::{ + NebulaConfig, NebulaConfigCipher, NebulaConfigFirewall, NebulaConfigFirewallRule, + NebulaConfigLighthouse, NebulaConfigListen, NebulaConfigPki, NebulaConfigPunchy, + NebulaConfigRelay, NebulaConfigTun, CONFIG, +}; +use crate::crypto::{decrypt_with_nonce, get_cipher_from_config}; +use crate::keystore::keystore_init; use crate::AppState; use ed25519_dalek::SigningKey; use ipnet::Ipv4Net; use log::{debug, error}; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; -use trifid_api_entities::entity::{firewall_rule, host, host_config_override, host_static_address, network, organization, signing_ca}; +use trifid_api_entities::entity::{ + firewall_rule, host, host_config_override, host_static_address, network, organization, + signing_ca, +}; use trifid_pki::cert::{ deserialize_ed25519_private, deserialize_nebula_certificate_from_pem, NebulaCertificate, NebulaCertificateDetails, }; -use crate::keystore::keystore_init; pub struct CodegenRequiredInfo { pub host: host::Model, @@ -32,14 +39,17 @@ pub struct CodegenRequiredInfo { pub relay_ips: Vec, pub lighthouse_ips: Vec, pub blocked_hosts: Vec, - pub firewall_rules: Vec + pub firewall_rules: Vec, } pub async fn generate_config( - data: &Data, + _data: &Data, info: &CodegenRequiredInfo, ) -> Result<(NebulaConfig, NebulaCertificate), Box> { - debug!("chk: deserialize CA cert {:x?}", hex::decode(&info.ca.cert)?); + debug!( + "chk: deserialize CA cert {:x?}", + hex::decode(&info.ca.cert)? + ); // decode the CA data let ca_cert = deserialize_nebula_certificate_from_pem(&hex::decode(&info.ca.cert)?)?; @@ -53,9 +63,7 @@ pub async fn generate_config( ) .unwrap()], subnets: vec![], - groups: vec![ - format!("role:{}", info.host.role) - ], + groups: vec![format!("role:{}", info.host.role)], not_before: SystemTime::now(), not_after: SystemTime::now() + Duration::from_secs(CONFIG.crypto.certs_expiry_time), public_key: info.dh_pubkey.clone().try_into().unwrap(), @@ -172,18 +180,16 @@ pub async fn generate_config( firewall: Some(NebulaConfigFirewall { conntrack: None, inbound: Some(info.firewall_rules.clone()), - outbound: Some(vec![ - NebulaConfigFirewallRule { - port: Some("any".to_string()), - proto: Some("any".to_string()), - ca_name: None, - ca_sha: None, - host: Some("any".to_string()), - group: None, - groups: None, - cidr: None, - } - ]), + outbound: Some(vec![NebulaConfigFirewallRule { + port: Some("any".to_string()), + proto: Some("any".to_string()), + ca_name: None, + ca_sha: None, + host: Some("any".to_string()), + group: None, + groups: None, + cidr: None, + }]), }), routines: 0, stats: None, @@ -310,19 +316,35 @@ pub async fn collect_info<'a>( let best_ca = best_ca.unwrap(); // pull our role's firewall rules - let firewall_rules = trifid_api_entities::entity::firewall_rule::Entity::find().filter(firewall_rule::Column::Role.eq(&host.id)).all(&db.conn).await?; - let firewall_rules = firewall_rules.iter().map(|u| { - NebulaConfigFirewallRule { - port: Some(if u.port_range_from == 0 && u.port_range_to == 65535 { "any".to_string() } else { format!("{}-{}", u.port_range_from, u.port_range_to) }), + let firewall_rules = trifid_api_entities::entity::firewall_rule::Entity::find() + .filter(firewall_rule::Column::Role.eq(&host.id)) + .all(&db.conn) + .await?; + let firewall_rules = firewall_rules + .iter() + .map(|u| NebulaConfigFirewallRule { + port: Some(if u.port_range_from == 0 && u.port_range_to == 65535 { + "any".to_string() + } else { + format!("{}-{}", u.port_range_from, u.port_range_to) + }), proto: Some(u.protocol.clone()), ca_name: None, ca_sha: None, - host: if u.allowed_role_id.is_some() { None } else { Some("any".to_string()) }, - groups: if u.allowed_role_id.is_some() { Some(vec![format!("role:{}", u.allowed_role_id.clone().unwrap())])} else { None }, + host: if u.allowed_role_id.is_some() { + None + } else { + Some("any".to_string()) + }, + groups: if u.allowed_role_id.is_some() { + Some(vec![format!("role:{}", u.allowed_role_id.clone().unwrap())]) + } else { + None + }, group: None, cidr: None, - } - }).collect(); + }) + .collect(); Ok(CodegenRequiredInfo { host, @@ -336,6 +358,6 @@ pub async fn collect_info<'a>( relay_ips: relays, lighthouse_ips: lighthouses, blocked_hosts, - firewall_rules + firewall_rules, }) } diff --git a/trifid-api/src/config.rs b/trifid-api/src/config.rs index 01dd7f0..f0fddb5 100644 --- a/trifid-api/src/config.rs +++ b/trifid-api/src/config.rs @@ -24,7 +24,7 @@ use std::fs; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::path::PathBuf; use std::time::SystemTime; -use derivative::Derivative; + use trifid_pki::cert::deserialize_nebula_certificate_from_pem; pub static CONFIG: Lazy = Lazy::new(|| { @@ -194,20 +194,24 @@ pub struct NebulaConfigPki { impl PartialEq for NebulaConfigPki { fn eq(&self, other: &Self) -> bool { - if self.ca != other.ca { return false; } - if self.key != other.key { return false; } - if self.blocklist != other.blocklist { return false; } - if self.disconnect_invalid != other.disconnect_invalid { return false; } + if self.ca != other.ca { + return false; + } + if self.key != other.key { + return false; + } + if self.blocklist != other.blocklist { + return false; + } + if self.disconnect_invalid != other.disconnect_invalid { + return false; + } // cert logic // if the cert is invalid, fallback to just checking equality match is_cert_equal_ignoring_expiry(&self.cert, &other.cert) { - Ok(res) => { - res - }, - Err(_) => { - self.cert == other.cert - } + Ok(res) => res, + Err(_) => self.cert == other.cert, } } } @@ -220,18 +224,38 @@ fn is_cert_equal_ignoring_expiry(me: &str, other: &str) -> Result Result> { ks_fp.push("tfks.toml"); if !ks_fp.exists() { - return Ok(Keystore { - hosts: vec![] - }) + return Ok(Keystore { hosts: vec![] }); } let f_str = fs::read_to_string(ks_fp)?; diff --git a/trifid-api/src/main.rs b/trifid-api/src/main.rs index 6c5f8f9..51425c1 100644 --- a/trifid-api/src/main.rs +++ b/trifid-api/src/main.rs @@ -26,7 +26,7 @@ use std::time::Duration; use crate::config::CONFIG; use crate::error::{APIError, APIErrorsResponse}; -use crate::keystore::{keystore_init, Keystore}; +use crate::keystore::keystore_init; use crate::tokens::random_id_no_id; use trifid_api_migration::{Migrator, MigratorTrait}; @@ -43,7 +43,7 @@ pub mod timers; pub mod tokens; pub struct AppState { - pub conn: DatabaseConnection + pub conn: DatabaseConnection, } #[actix_web::main] @@ -52,7 +52,7 @@ async fn main() -> Result<(), Box> { info!("Creating keystore..."); - let keystore = keystore_init()?; + let _keystore = keystore_init()?; info!("Connecting to database at {}...", CONFIG.database.url); @@ -76,16 +76,20 @@ async fn main() -> Result<(), Box> { HttpServer::new(move || { App::new() .app_data(data.clone()) - .app_data(JsonConfig::default().content_type_required(false).error_handler(|err, _req| { - let api_error: APIError = (&err).into(); - actix_web::error::InternalError::from_response( - err, - HttpResponse::BadRequest().json(APIErrorsResponse { - errors: vec![api_error], + .app_data( + JsonConfig::default() + .content_type_required(false) + .error_handler(|err, _req| { + let api_error: APIError = (&err).into(); + actix_web::error::InternalError::from_response( + err, + HttpResponse::BadRequest().json(APIErrorsResponse { + errors: vec![api_error], + }), + ) + .into() }), - ) - .into() - })) + ) .wrap(RequestIdentifier::with_generator(random_id_no_id)) .service(routes::v1::auth::magic_link::magic_link_request) .service(routes::v1::signup::signup_request) diff --git a/trifid-api/src/routes/v1/dnclient.rs b/trifid-api/src/routes/v1/dnclient.rs index ea65d8b..07f9b5e 100644 --- a/trifid-api/src/routes/v1/dnclient.rs +++ b/trifid-api/src/routes/v1/dnclient.rs @@ -1,28 +1,34 @@ -use actix_web::{HttpRequest, HttpResponse, post}; -use actix_web::web::{Data, Json}; -use base64::Engine; -use dnapi_rs::message::{APIError, APIErrors, CheckForUpdateResponse, CheckForUpdateResponseWrapper, DoUpdateRequest, DoUpdateResponse, EnrollResponse, RequestV1, RequestWrapper, SignedResponse, SignedResponseWrapper}; -use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey}; -use log::{debug, error}; -use trifid_pki::x25519_dalek::PublicKey; -use crate::AppState; use crate::codegen::{collect_info, generate_config}; use crate::keystore::{keystore_flush, keystore_init, KSCert, KSClientKey, KSConfig, KSSigningKey}; -use std::clone::Clone; +use crate::AppState; +use actix_web::web::{Data, Json}; +use actix_web::{post, HttpRequest, HttpResponse}; +use base64::Engine; use dnapi_rs::credentials::ed25519_public_keys_to_pem; +use dnapi_rs::message::{ + APIError, CheckForUpdateResponse, CheckForUpdateResponseWrapper, DoUpdateRequest, + DoUpdateResponse, EnrollResponse, RequestV1, RequestWrapper, SignedResponse, + SignedResponseWrapper, +}; +use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey}; +use log::{debug, error}; use rand::rngs::OsRng; +use std::clone::Clone; use trifid_pki::cert::{deserialize_ed25519_public, deserialize_x25519_public}; +use trifid_pki::x25519_dalek::PublicKey; #[post("/v1/dnclient")] -pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data) -> HttpResponse { +pub async fn dnclient( + req: Json, + _req_info: HttpRequest, + db: Data, +) -> HttpResponse { if req.version != 1 { - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_UNSUPPORTED_VERSION".to_string(), - message: "This server does not support the requested DNClient version.".to_string(), - path: None, - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_UNSUPPORTED_VERSION".to_string(), + message: "This server does not support the requested DNClient version.".to_string(), + path: None, + }]); } // verify the signature @@ -49,44 +55,57 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data host, None => { - return HttpResponse::Unauthorized().json(vec![ - APIError { - code: "ERR_HOST_ERROR".to_string(), - message: "The host does not exist or you do not have permission to access it.".to_string(), - path: None, - } - ]) + return HttpResponse::Unauthorized().json(vec![APIError { + code: "ERR_HOST_ERROR".to_string(), + message: "The host does not exist or you do not have permission to access it." + .to_string(), + path: None, + }]) } }; - let client_keys = host_in_ks.client_keys.iter().find(|u| u.id == req.counter as u64).unwrap(); - let client_keys_2 = host_in_ks.client_keys.iter().find(|u| u.id == host_in_ks.current_client_key).unwrap(); + let client_keys = host_in_ks + .client_keys + .iter() + .find(|u| u.id == req.counter as u64) + .unwrap(); + let client_keys_2 = host_in_ks + .client_keys + .iter() + .find(|u| u.id == host_in_ks.current_client_key) + .unwrap(); let signature = match Signature::from_slice(&req.signature) { Ok(sig) => sig, Err(e) => { error!("signature load error: {}", e); // Be intentionally vague as the signature is invalid. - return HttpResponse::Unauthorized().json(vec![ - APIError { - code: "ERR_HOST_ERROR".to_string(), - message: "The host does not exist or you do not have permission to access it.".to_string(), - path: None, - } - ]) + return HttpResponse::Unauthorized().json(vec![APIError { + code: "ERR_HOST_ERROR".to_string(), + message: "The host does not exist or you do not have permission to access it." + .to_string(), + path: None, + }]); } }; - if client_keys.ed_pub.verify(req.message.as_bytes(), &signature).is_err() && client_keys_2.ed_pub.verify(req.message.as_bytes(), &signature).is_err() { + if client_keys + .ed_pub + .verify(req.message.as_bytes(), &signature) + .is_err() + && client_keys_2 + .ed_pub + .verify(req.message.as_bytes(), &signature) + .is_err() + { // Be intentionally vague as the message is invalid. debug!("! invalid signature"); - return HttpResponse::Unauthorized().json(vec![ - APIError { - code: "ERR_HOST_ERROR".to_string(), - message: "The host does not exist or you do not have permission to access it.".to_string(), - path: None, - } - ]) + return HttpResponse::Unauthorized().json(vec![APIError { + code: "ERR_HOST_ERROR".to_string(), + message: "The host does not exist or you do not have permission to access it." + .to_string(), + path: None, + }]); } // Sig OK @@ -98,13 +117,11 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data msg, Err(e) => { error!("b64 decode error: {}", e); - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_INVALID_MESSAGE".to_string(), - message: "Error while decoding message from base64.".to_string(), - path: None - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_INVALID_MESSAGE".to_string(), + message: "Error while decoding message from base64.".to_string(), + path: None, + }]); } }; @@ -116,13 +133,11 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data msg, Err(e) => { error!("msg decode error: {}", e); - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_INVALID_MESSAGE".to_string(), - message: "Error while decoding message from JSON.".to_string(), - path: None - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_INVALID_MESSAGE".to_string(), + message: "Error while decoding message from JSON.".to_string(), + path: None, + }]); } }; @@ -142,7 +157,7 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data cfg, Err(e) => { error!("error generating configuration: {}", e); @@ -156,39 +171,41 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data { // value ignored here HttpResponse::Ok().json(CheckForUpdateResponseWrapper { - data: CheckForUpdateResponse { update_available: config_update_avail }, + data: CheckForUpdateResponse { + update_available: config_update_avail, + }, }) - }, + } "DoUpdate" => { if !config_update_avail { - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_NO_UPDATE_AVAILABLE".to_string(), - message: "There is no new configuration available.".to_string(), - path: None - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_NO_UPDATE_AVAILABLE".to_string(), + message: "There is no new configuration available.".to_string(), + path: None, + }]); } let do_update_req: DoUpdateRequest = match serde_json::from_slice(&req_w.value) { Ok(req) => req, Err(e) => { error!("DoUpdate deserialization error: {}", e); - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_REQ_DESERIALIZE_ERROR".to_string(), - message: "There was an error deserializing the update request.".to_string(), - path: None - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_REQ_DESERIALIZE_ERROR".to_string(), + message: "There was an error deserializing the update request.".to_string(), + path: None, + }]); } }; @@ -196,13 +213,11 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data pk, Err(e) => { error!("PEM decode error: {}", e); - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_BAD_PK".to_string(), - message: "There was an error deserializing the DHPK.".to_string(), - path: None - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_BAD_PK".to_string(), + message: "There was an error deserializing the DHPK.".to_string(), + path: None, + }]); } }; @@ -227,7 +242,8 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data, req_info: HttpRequest, db: Data r, Err(e) => { error!("DH pubkey deserialize error: {}", e); - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_DH_INVALID".to_string(), - message: "There was an error deserializing the DH pubkey.".to_string(), - path: None - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_DH_INVALID".to_string(), + message: "There was an error deserializing the DH pubkey.".to_string(), + path: None, + }]); } }; @@ -272,17 +286,15 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data r, Err(e) => { error!("ED pubkey deserialize error: {}", e); - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_ED_INVALID".to_string(), - message: "There was an error deserializing the ED pubkey.".to_string(), - path: None - } - ]) + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_ED_INVALID".to_string(), + message: "There was an error deserializing the ED pubkey.".to_string(), + path: None, + }]); } }; - let dh_pubkey_typed: [u8; 32] = dh_pubkey.clone().try_into().unwrap(); + let dh_pubkey_typed: [u8; 32] = dh_pubkey.try_into().unwrap(); ks.client_keys.push(KSClientKey { id: ks.current_client_key + 1, @@ -297,32 +309,33 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data (), Err(e) => { error!("keystore save error: {}", e); - return HttpResponse::InternalServerError().json(vec![ - APIError { - code: "ERR_SAVE_ERR".to_string(), - message: "There was an error saving the keystore.".to_string(), - path: None - } - ]) + return HttpResponse::InternalServerError().json(vec![APIError { + code: "ERR_SAVE_ERR".to_string(), + message: "There was an error saving the keystore.".to_string(), + path: None, + }]); } } // get the signing key that the client last trusted based on its current config version // this is their current counter - let signing_key = host_in_ks.signing_keys.iter().find(|u| u.id == (req.counter as u64) - 1).unwrap(); + let signing_key = host_in_ks + .signing_keys + .iter() + .find(|u| u.id == (req.counter as u64) - 1) + .unwrap(); let msg = DoUpdateResponse { config: match serde_yaml::to_string(&cfg) { Ok(c_str) => c_str.as_bytes().to_vec(), Err(e) => { error!("config serialization error: {}", e); - return HttpResponse::InternalServerError().json(vec![ - APIError { - code: "ERR_CFG_SERIALIZATION".to_string(), - message: "There was an error serializing the new configuration.".to_string(), - path: None - } - ]) + return HttpResponse::InternalServerError().json(vec![APIError { + code: "ERR_CFG_SERIALIZATION".to_string(), + message: "There was an error serializing the new configuration." + .to_string(), + path: None, + }]); } }, counter: host_in_ks.current_config as u32, @@ -334,13 +347,12 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data b, Err(e) => { error!("response serialization error: {}", e); - return HttpResponse::InternalServerError().json(vec![ - APIError { - code: "ERR_CFG_SERIALIZATION".to_string(), - message: "There was an error serializing the new configuration.".to_string(), - path: None - } - ]) + return HttpResponse::InternalServerError().json(vec![APIError { + code: "ERR_CFG_SERIALIZATION".to_string(), + message: "There was an error serializing the new configuration." + .to_string(), + path: None, + }]); } }; @@ -350,20 +362,14 @@ pub async fn dnclient(req: Json, req_info: HttpRequest, db: Data { - HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_UNSUPPORTED_METHOD".to_string(), - message: "This server does not support that method yet.".to_string(), - path: None - } - ]) } - } -} \ No newline at end of file + _ => HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_UNSUPPORTED_METHOD".to_string(), + message: "This server does not support that method yet.".to_string(), + path: None, + }]), + }; +} diff --git a/trifid-api/src/routes/v1/mod.rs b/trifid-api/src/routes/v1/mod.rs index 35fc9c5..7e8f5a9 100644 --- a/trifid-api/src/routes/v1/mod.rs +++ b/trifid-api/src/routes/v1/mod.rs @@ -1,4 +1,5 @@ pub mod auth; +pub mod dnclient; pub mod hosts; pub mod networks; pub mod organization; @@ -7,4 +8,3 @@ pub mod signup; pub mod totp_authenticators; pub mod trifid; pub mod verify_totp_authenticators; -pub mod dnclient; \ No newline at end of file diff --git a/trifid-api/src/routes/v1/organization.rs b/trifid-api/src/routes/v1/organization.rs index e4c51ec..af60899 100644 --- a/trifid-api/src/routes/v1/organization.rs +++ b/trifid-api/src/routes/v1/organization.rs @@ -33,7 +33,7 @@ use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, Query use serde::{Deserialize, Serialize}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use trifid_api_entities::entity::{network, organization, signing_ca}; -use trifid_pki::cert::{serialize_x25519_private, NebulaCertificate, NebulaCertificateDetails, serialize_ed25519_private}; +use trifid_pki::cert::{serialize_ed25519_private, NebulaCertificate, NebulaCertificateDetails}; use trifid_pki::ed25519_dalek::SigningKey; use trifid_pki::rand_core::OsRng; diff --git a/trifid-api/src/routes/v2/enroll.rs b/trifid-api/src/routes/v2/enroll.rs index 4df4c87..b9b845e 100644 --- a/trifid-api/src/routes/v2/enroll.rs +++ b/trifid-api/src/routes/v2/enroll.rs @@ -4,12 +4,15 @@ use dnapi_rs::message::{ APIError, EnrollRequest, EnrollResponse, EnrollResponseData, EnrollResponseDataOrg, }; use ed25519_dalek::{SigningKey, VerifyingKey}; -use log::{debug, error, trace}; +use log::{debug, error}; use rand::rngs::OsRng; use sea_orm::{ColumnTrait, EntityTrait, ModelTrait, QueryFilter}; use crate::codegen::{collect_info, generate_config}; -use crate::keystore::{KSCert, KSClientKey, KSConfig, KSSigningKey, KeystoreHostInformation, keystore_flush, keystore_init}; +use crate::keystore::{ + keystore_flush, keystore_init, KSCert, KSClientKey, KSConfig, KSSigningKey, + KeystoreHostInformation, +}; use crate::AppState; use trifid_api_entities::entity::host_enrollment_code; use trifid_pki::cert::{ @@ -40,8 +43,8 @@ pub async fn enroll( errors: vec![APIError { code: "ERR_DB_ERROR".to_string(), message: - "There was an error with the database request. Please try again later." - .to_string(), + "There was an error with the database request. Please try again later." + .to_string(), path: None, }], }); @@ -109,8 +112,8 @@ pub async fn enroll( errors: vec![APIError { code: "ERR_DB_ERROR".to_string(), message: - "There was an error with the database request. Please try again later." - .to_string(), + "There was an error with the database request. Please try again later." + .to_string(), path: None, }], }); @@ -198,13 +201,11 @@ pub async fn enroll( Ok(_) => (), Err(e) => { error!("keystore save error: {}", e); - return HttpResponse::InternalServerError().json(vec![ - APIError { - code: "ERR_SAVE_ERR".to_string(), - message: "There was an error saving the keystore.".to_string(), - path: None, - } - ]); + return HttpResponse::InternalServerError().json(vec![APIError { + code: "ERR_SAVE_ERR".to_string(), + message: "There was an error saving the keystore.".to_string(), + path: None, + }]); } } @@ -214,19 +215,30 @@ pub async fn enroll( Ok(cfg) => cfg.as_bytes().to_vec(), Err(e) => { error!("serialization error: {}", e); - return HttpResponse::BadRequest().json(vec![ - APIError { - code: "ERR_ED_INVALID".to_string(), - message: "There was an error deserializing the ED pubkey.".to_string(), - path: None, - } - ]); + return HttpResponse::BadRequest().json(vec![APIError { + code: "ERR_ED_INVALID".to_string(), + message: "There was an error deserializing the ED pubkey.".to_string(), + path: None, + }]); } }, host_id: enroll_info.host.clone(), counter: host.current_config as u32, - trusted_keys: serialize_ed25519_public(host.signing_keys.iter().find(|u| u.id == host.current_signing_key).unwrap().key.verifying_key().as_bytes().as_slice()).to_vec(), - organization: EnrollResponseDataOrg { id: info.organization.id.clone(), name: info.organization.name.clone() }, + trusted_keys: serialize_ed25519_public( + host.signing_keys + .iter() + .find(|u| u.id == host.current_signing_key) + .unwrap() + .key + .verifying_key() + .as_bytes() + .as_slice(), + ) + .to_vec(), + organization: EnrollResponseDataOrg { + id: info.organization.id.clone(), + name: info.organization.name.clone(), + }, }, }) } diff --git a/trifid-pki/src/ca.rs b/trifid-pki/src/ca.rs index da7903a..d4441d6 100644 --- a/trifid-pki/src/ca.rs +++ b/trifid-pki/src/ca.rs @@ -43,7 +43,7 @@ impl NebulaCAPool { match pool.add_ca_certificate(pem::encode(&cert).as_bytes()) { Ok(did_expire) => { if did_expire { - pool.expired = true + pool.expired = true; } } Err(e) => return Err(e), @@ -71,7 +71,7 @@ impl NebulaCAPool { let expired = cert.expired(SystemTime::now()); if expired { - self.expired = true + self.expired = true; } self.cas.insert(fingerprint, cert);