red_smb/smb2/session_setup/
setup_req.rs

1use crate::smb2::Smb2Header;
2use crate::smb2::SMB2_HEADER_SIZE;
3use crate::smb2::header::commands::SMB2_SESSION_SETUP;
4
5const SMB2_SESSION_SETUP_REQUEST_SIZE: u16 = 0x0019;
6
7
8#[derive(Clone, Debug, PartialEq)]
9pub struct Smb2SessionSetupReq {
10    pub header: Smb2Header,
11    pub body: Smb2SessionSetupReqBody
12}
13
14impl Smb2SessionSetupReq {
15
16    pub fn new() -> Self {
17        return Self {
18            header: Smb2Header::new(SMB2_SESSION_SETUP),
19            body: Smb2SessionSetupReqBody::default(),
20        }
21    }
22
23    pub fn build(&self) -> Vec<u8> {
24        let mut raw = self.header.build();
25        raw.extend(self.body.build());
26        return raw;
27    }
28}
29
30
31#[derive(Clone, Debug, Default, PartialEq)]
32pub struct Smb2SessionSetupReqBody {
33    pub flags: u8,
34    pub security_mode: u8,
35    pub capabilities: u32,
36    pub previous_session_id: u64,
37    pub buffer: Vec<u8>,
38}
39
40impl Smb2SessionSetupReqBody {
41    pub fn build(&self) -> Vec<u8> {
42        let mut bytes = SMB2_SESSION_SETUP_REQUEST_SIZE.to_le_bytes().to_vec();
43
44        bytes.push(self.flags);
45        bytes.push(self.security_mode);
46        bytes.extend(&self.capabilities.to_le_bytes());
47
48        // Channel MUST be set to zero
49        bytes.extend(&[0; 4]);
50
51        let offset: u16 = SMB2_HEADER_SIZE + 24;
52        bytes.extend(&offset.to_le_bytes());
53        bytes.extend(&(self.buffer.len() as u16).to_le_bytes());
54
55        bytes.extend(&self.previous_session_id.to_le_bytes());
56
57        bytes.extend(&self.buffer);
58
59        return bytes;
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66    use crate::smb2::session_setup::SMB2_NEGOTIATE_SIGNING_ENABLED;
67
68    const RAW_SESSION_REQ_BODY: &'static [u8] = &[
69        0x19, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70        0x58, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71        0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02, 0xa0, 0x36,
72        0x30, 0x34, 0xa0, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
73        0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22, 0x04, 0x20, 0x4e, 0x54,
74        0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x02,
75        0x88, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77    ];
78
79    #[test]
80    fn test_build_session_setup_request() {
81        let mut sess_req = Smb2SessionSetupReqBody::default();
82        sess_req.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
83        sess_req.buffer = vec![
84            0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02, 0xa0,
85            0x36, 0x30, 0x34, 0xa0, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06,
86            0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22, 0x04,
87            0x20, 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00,
88            0x00, 0x00, 0x05, 0x02, 0x88, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
89            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90        ];
91
92        assert_eq!(RAW_SESSION_REQ_BODY.to_vec(), sess_req.build());
93    }
94}