Skip to content

Commit 145606a

Browse files
committed
Resolve TODOs, add tests for signing + query dir, fix tree disconnect bug
1 parent a44e4da commit 145606a

File tree

8 files changed

+137
-16
lines changed

8 files changed

+137
-16
lines changed

smb/src/connection.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ impl ConnectionMessageHandler {
409409
impl MessageHandler for ConnectionMessageHandler {
410410
#[maybe_async]
411411
async fn sendo(&self, mut msg: OutgoingMessage) -> crate::Result<SendMessageResult> {
412-
// TODO: Add assertion in the struct regarding the selected dialect!
413412
let priority_value = match self.conn_info.get() {
414413
Some(neg_info) => match neg_info.negotiation.dialect_rev {
415414
Dialect::Smb0311 => 1,

smb/src/packets/fscc/query_file_info.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,9 @@ pub struct FileCompressionInformation {
113113
pub compression_unit: u8,
114114
pub chunk_shift: u8,
115115
pub cluster_shift: u8,
116-
#[br(parse_with = binrw::helpers::read_u24)]
117-
#[br(assert(reserved == 0))]
118-
#[bw(align_before = 4)]
119-
#[bw(ignore)]
120-
reserved: u32, // 3-bytes. TODO: Define a normal u24 type for such cases?
116+
117+
#[bw(calc = [0; 3])]
118+
_reserved: [u8; 3],
121119
}
122120

123121
#[binrw::binrw]

smb/src/packets/smb2/create.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,15 +451,13 @@ pub struct DurableHandleRequest {
451451
#[derive(Debug, PartialEq, Eq, Default)]
452452
pub struct DurableHandleResponse {
453453
#[bw(calc = 0)]
454-
#[br(assert(response == 0))]
455-
response: u128,
454+
_reserved: u64,
456455
}
457456

458-
/// TODO: SMB2_FILEID
459457
#[binrw::binrw]
460458
#[derive(Debug, PartialEq, Eq)]
461459
pub struct DurableHandleReconnect {
462-
pub durable_request: u128,
460+
pub durable_request: FileId,
463461
}
464462
#[binrw::binrw]
465463
#[derive(Debug, PartialEq, Eq, Default)]

smb/src/packets/smb2/ioctl/msg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub struct IoctlRequest {
3636
#[bw(calc = 0)]
3737
#[br(assert(reserved2 == 0))]
3838
reserved2: u32,
39-
// TODO: treat FSCTLs differently when having a concrerte data structure.
39+
4040
#[bw(write_with = PosMarker::write_aoff_size, args(&_input_offset, &_input_count))]
4141
#[br(map_stream = |s| s.take_seek(_input_count.value as u64), args(ctl_code, flags))]
4242
pub buffer: IoctlReqData,

smb/src/packets/smb2/negotiate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub struct NegotiateRequest {
2222
_reserved: u16,
2323
pub capabilities: GlobalCapabilities,
2424
pub client_guid: Guid,
25-
// TODO: The 3 fields below are possibly a union in older versions of SMB.
25+
2626
#[bw(calc = PosMarker::default())]
2727
negotiate_context_offset: PosMarker<u32>,
2828
#[bw(try_calc(u16::try_from(negotiate_context_list.as_ref().map(|v| v.len()).unwrap_or(0))))]
@@ -32,7 +32,7 @@ pub struct NegotiateRequest {
3232
reserved2: u16,
3333
#[br(count = dialect_count)]
3434
pub dialects: Vec<Dialect>,
35-
// Only on SMB 3.1.1 we have negotiate contexts.
35+
// Only on SMB 3.1.1 supporting clients we have negotiation contexts.
3636
// Align to 8 bytes.
3737
#[brw(if(dialects.contains(&Dialect::Smb0311)), align_before = 8)]
3838
#[br(count = negotiate_context_count, seek_before = SeekFrom::Start(negotiate_context_offset.value as u64))]

smb/src/packets/smb2/query_dir.rs

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ impl QueryDirectoryResponse {
8080

8181
#[cfg(test)]
8282
mod tests {
83+
use time::macros::datetime;
84+
8385
use super::*;
8486
#[test]
8587
pub fn test_both_directory_information_attribute_parse() {
@@ -135,6 +137,100 @@ mod tests {
135137
.read_output()
136138
.unwrap();
137139

138-
// TODO: Test the contents of the result, not just that it parses.
140+
assert_eq!(
141+
vec![
142+
ChainedItem::new(FileIdBothDirectoryInformationInner {
143+
file_index: 0,
144+
creation_time: FileTime::from(datetime!(2024-12-11 12:32:31.7084985)),
145+
last_access_time: FileTime::from(datetime!(2025-01-03 10:18:15.6499175)),
146+
last_write_time: FileTime::from(datetime!(2024-12-27 14:22:59.9648231)),
147+
change_time: FileTime::from(datetime!(2024-12-27 14:22:59.9648231)),
148+
end_of_file: 0,
149+
allocation_size: 0,
150+
file_attributes: FileAttributes::new().with_directory(true),
151+
ea_size: 0,
152+
short_name_length: 0,
153+
short_name: [0; 12],
154+
fild_id: 562949953454203,
155+
file_name: ".".into(),
156+
}),
157+
ChainedItem::new(FileIdBothDirectoryInformationInner {
158+
file_index: 0,
159+
creation_time: FileTime::from(datetime!(2024-12-11 9:25:15.4208828)),
160+
last_access_time: FileTime::from(datetime!(2025-01-02 19:05:31.8723088)),
161+
last_write_time: FileTime::from(datetime!(2024-12-11 12:32:35.4544738)),
162+
change_time: FileTime::from(datetime!(2024-12-11 12:32:35.4544738)),
163+
end_of_file: 0,
164+
allocation_size: 0,
165+
file_attributes: FileAttributes::new().with_directory(true),
166+
ea_size: 0,
167+
short_name_length: 0,
168+
short_name: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,],
169+
fild_id: 1125899906967338,
170+
file_name: "..".into(),
171+
}),
172+
ChainedItem::new(FileIdBothDirectoryInformationInner {
173+
file_index: 0,
174+
creation_time: FileTime::from(datetime!(2024-12-27 14:22:48.7929947)),
175+
last_access_time: FileTime::from(datetime!(2024-12-27 14:22:48.7929947)),
176+
last_write_time: FileTime::from(datetime!(2024-12-27 14:22:48.7929947)),
177+
change_time: FileTime::from(datetime!(2024-12-27 14:22:49.7460575)),
178+
end_of_file: 0,
179+
allocation_size: 0,
180+
file_attributes: FileAttributes::new().with_archive(true),
181+
ea_size: 0,
182+
short_name_length: 0,
183+
short_name: [0; 12],
184+
fild_id: 2814749767148784,
185+
file_name: "a.txt".into(),
186+
}),
187+
ChainedItem::new(FileIdBothDirectoryInformationInner {
188+
file_index: 0,
189+
creation_time: FileTime::from(datetime!(2024-12-27 14:22:51.5742424)),
190+
last_access_time: FileTime::from(datetime!(2024-12-27 14:23:06.9505662)),
191+
last_write_time: FileTime::from(datetime!(2024-12-27 14:23:06.9505662)),
192+
change_time: FileTime::from(datetime!(2024-12-27 14:23:06.9505662)),
193+
end_of_file: 6,
194+
allocation_size: 8,
195+
file_attributes: FileAttributes::new().with_archive(true),
196+
ea_size: 0,
197+
short_name_length: 0,
198+
short_name: [0; 12],
199+
fild_id: 1125899906906297,
200+
file_name: "b.txt".into(),
201+
}),
202+
ChainedItem::new(FileIdBothDirectoryInformationInner {
203+
file_index: 0,
204+
creation_time: FileTime::from(datetime!(2024-12-27 14:22:52.0116823)),
205+
last_access_time: FileTime::from(datetime!(2024-12-27 14:23:14.7795682)),
206+
last_write_time: FileTime::from(datetime!(2024-12-27 14:23:14.7795682)),
207+
change_time: FileTime::from(datetime!(2024-12-27 14:23:14.7795682)),
208+
end_of_file: 486,
209+
allocation_size: 488,
210+
file_attributes: FileAttributes::new().with_archive(true),
211+
ea_size: 0,
212+
short_name_length: 0,
213+
short_name: [0; 12],
214+
fild_id: 1125899906906299,
215+
file_name: "c.txt".into(),
216+
},),
217+
ChainedItem::new(FileIdBothDirectoryInformationInner {
218+
file_index: 0,
219+
creation_time: FileTime::from(datetime!(2024-12-27 14:22:52.167941),),
220+
last_access_time: FileTime::from(datetime!(2025-01-02 19:05:44.7804931),),
221+
last_write_time: FileTime::from(datetime!(2025-01-02 19:05:44.7804931),),
222+
change_time: FileTime::from(datetime!(2025-01-02 19:05:44.7804931),),
223+
end_of_file: 15910,
224+
allocation_size: 16384,
225+
file_attributes: FileAttributes::new().with_archive(true),
226+
ea_size: 0,
227+
short_name_length: 0,
228+
short_name: [0; 12],
229+
fild_id: 1125899906906300,
230+
file_name: "d.txt".into(),
231+
})
232+
],
233+
_res
234+
);
139235
}
140236
}

smb/src/session/signer.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,34 @@ impl Clone for MessageSigner {
9090

9191
#[cfg(test)]
9292
mod tests {
93-
// TODO: Add tests.
93+
use crate::{crypto::make_signing_algo, packets::smb2::SigningAlgorithmId};
94+
95+
use super::*;
96+
97+
const TEST_SIGNING_KEY: [u8; 16] = [
98+
0xAC, 0x36, 0xE9, 0x54, 0x3C, 0xD8, 0x88, 0xF0, 0xA8, 0x41, 0x23, 0xE4, 0x6B, 0xB2, 0xA0,
99+
0xD7,
100+
];
101+
102+
#[test]
103+
fn test_calc_signature() {
104+
// Some random session logoff request for testing.
105+
let raw_data = vec![
106+
0xfeu8, 0x53, 0x4d, 0x42, 0x40, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0,
107+
0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
108+
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x53, 0x20, 0xc, 0x21, 0x0, 0x0, 0x0, 0x0, 0x76,
109+
0x23, 0x4b, 0x3c, 0x81, 0x2f, 0x51, 0xab, 0x8a, 0x5c, 0xf9, 0xfa, 0x43, 0xd4, 0xeb,
110+
0x28, 0x4, 0x0, 0x0, 0x0,
111+
];
112+
let mut header = Header::read_le(&mut Cursor::new(
113+
&raw_data.as_slice()[..=Header::STRUCT_SIZE],
114+
))
115+
.unwrap();
116+
117+
let mut signer = MessageSigner::new(
118+
make_signing_algo(SigningAlgorithmId::AesGmac, &TEST_SIGNING_KEY).unwrap(),
119+
);
120+
let signature = signer.calculate_signature(&mut header, &raw_data).unwrap();
121+
assert_eq!(signature, 0x28ebd443faf95c8aab512f813c4b2376);
122+
}
94123
}

smb/src/tree.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl TreeMessageHandler {
138138

139139
#[maybe_async]
140140
async fn disconnect(&mut self) -> crate::Result<()> {
141-
let info = self.connect_info.take();
141+
let info = self.connect_info.get();
142142

143143
if !info.is_some() {
144144
return Err(Error::InvalidState(
@@ -155,6 +155,7 @@ impl TreeMessageHandler {
155155
))
156156
.await?;
157157

158+
self.connect_info.take();
158159
log::info!("Disconnected from tree {}", self.tree_name);
159160

160161
Ok(())

0 commit comments

Comments
 (0)