#![cfg(all(feature = "sign", feature = "encrypt"))]
use common::make_server_connection;
#[cfg(feature = "async")]
use futures_util::StreamExt;
use serial_test::serial;
use smb::{
connection::EncryptionMode,
packets::{
fscc::*,
smb2::{AdditionalInfo, CreateDisposition, Dialect},
},
resource::Directory,
};
use std::sync::Arc;
mod common;
macro_rules! basic_test {
([$dialect:ident], [$($encrypt_mode:ident),*]) => {
$(
paste::paste! {
#[test_log::test(maybe_async::test(
not(feature = "async"),
async(feature = "async", tokio::test(flavor = "multi_thread"))
))]
#[serial]
pub async fn [<test_smbint_ $dialect:lower _e $encrypt_mode:lower>]() -> Result<(), Box<dyn std::error::Error>> {
test_smb_integration_dialect_encrpytion_mode(Dialect::$dialect, EncryptionMode::$encrypt_mode).await
}
}
)*
};
([$($dialect:ident),*], $encrypt_modes:tt) => {
$(
basic_test!([$dialect], $encrypt_modes);
)*
};
}
basic_test!([Smb030, Smb0302, Smb0311], [Disabled, Required]);
basic_test!([Smb0202, Smb021], [Disabled]);
#[maybe_async::maybe_async]
async fn test_smb_integration_dialect_encrpytion_mode(
force_dialect: Dialect,
encryption_mode: EncryptionMode,
) -> Result<(), Box<dyn std::error::Error>> {
log::info!(
"Testing with dialect: {:?}, enc? {:?}",
force_dialect,
encryption_mode
);
let (_smb, _session, tree) = make_server_connection("MyShare", None).await?;
const TEST_FILE: &str = "test.txt";
const TEST_DATA: &[u8] = b"Hello, World!";
let security = {
let file = tree
.create_file(
TEST_FILE,
CreateDisposition::Create,
FileAccessMask::new()
.with_generic_read(true)
.with_generic_write(true),
)
.await?
.unwrap_file();
file.write_block(TEST_DATA, 0).await?;
file.query_security_info(AdditionalInfo::new().with_owner_security_information(true))
.await?
};
if security.owner_sid.is_none() {
return Err("No owner SID found".into());
}
{
let directory = tree
.open_existing("", FileAccessMask::new().with_generic_read(true))
.await?
.unwrap_dir();
let directory = Arc::new(directory);
let ds =
Directory::query_directory::<FileDirectoryInformation>(&directory, TEST_FILE).await?;
let mut found = false;
ds.for_each(|entry| {
if entry.unwrap().file_name.to_string() == TEST_FILE {
found = true;
}
async { () }
})
.await;
if !found {
return Err("File not found in directory".into());
}
}
{
let file = tree
.open_existing(
TEST_FILE,
FileAccessMask::new()
.with_generic_read(true)
.with_delete(true),
)
.await?
.unwrap_file();
file.set_file_info(FileDispositionInformation {
delete_pending: true.into(),
})
.await?;
let mut buf = [0u8; TEST_DATA.len() + 2];
let read_length = file.read_block(&mut buf, 0, false).await?;
assert_eq!(read_length, TEST_DATA.len());
assert_eq!(&buf[..read_length], TEST_DATA);
let all_info = file.query_info::<FileAllInformation>().await?;
assert_eq!(
all_info.name.file_name.to_string(),
"\\".to_string() + TEST_FILE
);
file.query_fs_info::<FileFsSizeInformation>().await?;
assert_eq!(all_info.standard.end_of_file, TEST_DATA.len() as u64);
}
Ok(())
}