use crate::auth::AuthenticationRequest;
use crate::prelude::{GroupBroadcast, PeerSignal, VirtualTargetType};
use crate::proto::state_container::VirtualConnectionType;
use citadel_crypt::scramble::streaming_crypt_scrambler::ObjectSource;
use citadel_types::crypto::SecurityLevel;
use citadel_types::proto::TransferType;
use citadel_types::proto::{ConnectMode, SessionSecuritySettings, UdpMode};
use citadel_user::auth::proposed_credentials::ProposedCredentials;
use serde::{Deserialize, Serialize};
use sha3::Digest;
use std::fmt::{Debug, Formatter};
use std::net::SocketAddr;
use std::path::PathBuf;
pub struct RegisterToHypernode {
pub remote_addr: SocketAddr,
pub proposed_credentials: ProposedCredentials,
pub static_security_settings: SessionSecuritySettings,
pub session_password: PreSharedKey,
}
pub struct PeerCommand {
pub session_cid: u64,
pub command: PeerSignal,
}
pub struct DeregisterFromHypernode {
pub session_cid: u64,
pub v_conn_type: VirtualConnectionType,
}
pub struct ConnectToHypernode {
pub auth_request: AuthenticationRequest,
pub connect_mode: ConnectMode,
pub udp_mode: UdpMode,
pub keep_alive_timeout: Option<u64>,
pub session_password: PreSharedKey,
pub session_security_settings: SessionSecuritySettings,
}
pub struct ReKey {
pub v_conn_type: VirtualTargetType,
}
pub struct SendObject {
pub source: Box<dyn ObjectSource>,
pub chunk_size: Option<usize>,
pub session_cid: u64,
pub v_conn_type: VirtualTargetType,
pub transfer_type: TransferType,
}
pub struct PullObject {
pub v_conn: VirtualConnectionType,
pub virtual_dir: PathBuf,
pub delete_on_pull: bool,
pub transfer_security_level: SecurityLevel,
}
pub struct DeleteObject {
pub v_conn: VirtualConnectionType,
pub virtual_dir: PathBuf,
pub security_level: SecurityLevel,
}
pub struct GroupBroadcastCommand {
pub session_cid: u64,
pub command: GroupBroadcast,
}
pub struct DisconnectFromHypernode {
pub session_cid: u64,
}
#[allow(variant_size_differences)]
pub enum NodeRequest {
RegisterToHypernode(RegisterToHypernode),
PeerCommand(PeerCommand),
DeregisterFromHypernode(DeregisterFromHypernode),
ConnectToHypernode(ConnectToHypernode),
ReKey(ReKey),
SendObject(SendObject),
PullObject(PullObject),
DeleteObject(DeleteObject),
GroupBroadcastCommand(GroupBroadcastCommand),
DisconnectFromHypernode(DisconnectFromHypernode),
GetActiveSessions,
Shutdown,
}
impl NodeRequest {
pub fn session_cid(&self) -> Option<u64> {
match self {
NodeRequest::RegisterToHypernode(_) => None,
NodeRequest::PeerCommand(PeerCommand { session_cid, .. }) => Some(*session_cid),
NodeRequest::DeregisterFromHypernode(DeregisterFromHypernode {
session_cid, ..
}) => Some(*session_cid),
NodeRequest::ConnectToHypernode(connect) => connect.auth_request.session_cid(),
NodeRequest::ReKey(rk) => Some(rk.v_conn_type.get_session_cid()),
NodeRequest::SendObject(SendObject { session_cid, .. }) => Some(*session_cid),
NodeRequest::PullObject(pull) => Some(pull.v_conn.get_session_cid()),
NodeRequest::DeleteObject(del) => Some(del.v_conn.get_session_cid()),
NodeRequest::GroupBroadcastCommand(GroupBroadcastCommand { session_cid, .. }) => {
Some(*session_cid)
}
NodeRequest::DisconnectFromHypernode(DisconnectFromHypernode { session_cid }) => {
Some(*session_cid)
}
NodeRequest::GetActiveSessions => None,
NodeRequest::Shutdown => None,
}
}
}
impl Debug for NodeRequest {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "NodeRequest")
}
}
#[derive(Default, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
pub struct PreSharedKey {
passwords: Vec<Vec<u8>>,
}
impl PreSharedKey {
pub fn add_password<T: AsRef<[u8]>>(mut self, password: T) -> Self {
let mut hasher = sha3::Sha3_256::default();
hasher.update(password.as_ref());
self.passwords.push(hasher.finalize().to_vec());
self
}
}
impl AsRef<[Vec<u8>]> for PreSharedKey {
fn as_ref(&self) -> &[Vec<u8>] {
&self.passwords
}
}
impl<T: AsRef<[u8]>> From<T> for PreSharedKey {
fn from(password: T) -> Self {
PreSharedKey::default().add_password(password)
}
}