use std::time::Duration;
use crate::packets::{guid::Guid, smb2::Dialect};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum EncryptionMode {
#[default]
Allowed,
Required,
Disabled,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub enum TransportConfig {
#[default]
Tcp,
NetBios,
Quic(QuicConfig),
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct QuicConfig {
pub local_address: Option<String>,
pub cert_validation: QuicCertValidationOptions,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub enum QuicCertValidationOptions {
#[default]
PlatformVerifier,
CustomRootCerts(Vec<String>),
}
impl EncryptionMode {
pub fn is_required(&self) -> bool {
matches!(self, Self::Required)
}
pub fn is_disabled(&self) -> bool {
matches!(self, Self::Disabled)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AuthMethodsConfig {
pub ntlm: bool,
pub kerberos: bool,
}
impl Default for AuthMethodsConfig {
fn default() -> Self {
Self {
ntlm: true,
kerberos: cfg!(feature = "kerberos"),
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ConnectionConfig {
pub port: Option<u16>,
pub timeout: Option<Duration>,
pub min_dialect: Option<Dialect>,
pub max_dialect: Option<Dialect>,
pub encryption_mode: EncryptionMode,
pub allow_unsigned_guest_access: bool,
pub compression_enabled: bool,
pub client_name: Option<String>,
pub client_guid: Option<Guid>,
pub disable_notifications: bool,
pub smb2_only_negotiate: bool,
pub transport: TransportConfig,
pub auth_methods: AuthMethodsConfig,
pub credits_backlog: Option<u16>,
}
impl ConnectionConfig {
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
pub fn validate(&self) -> crate::Result<()> {
if let (Some(min), Some(max)) = (self.min_dialect, self.max_dialect) {
if min > max {
return Err(crate::Error::InvalidConfiguration(
"Minimum dialect is greater than maximum dialect".to_string(),
));
}
}
if let Some(min) = self.min_dialect {
if min < Dialect::Smb0311 && matches!(self.transport, TransportConfig::Quic(_)) {
return Err(crate::Error::InvalidConfiguration(
"SMB over QUIC is not supported by the selected dialect".to_string(),
));
}
}
Ok(())
}
pub fn timeout(&self) -> Duration {
self.timeout.unwrap_or(Self::DEFAULT_TIMEOUT)
}
}