smb_msg/
session_setup.rs

1//! Session setup messages
2
3use binrw::prelude::*;
4use modular_bitfield::prelude::*;
5
6use smb_dtyp::binrw_util::prelude::*;
7use smb_msg_derive::*;
8
9/// SMB2 SESSION_SETUP Request packet sent by the client to request a new
10/// authenticated session within a new or existing SMB 2 Protocol transport connection.
11///
12/// MS-SMB2 2.2.5
13#[smb_request(size = 25)]
14pub struct SessionSetupRequest {
15    /// Combination of flags for SMB 3.x dialect family
16    pub flags: SetupRequestFlags,
17    /// Security mode field specifying whether SMB signing is enabled or required
18    pub security_mode: SessionSecurityMode,
19    /// Protocol capabilities for the client
20    pub capabilities: NegotiateCapabilities,
21    /// Channel (reserved)
22    reserved: u32,
23    #[bw(calc = PosMarker::default())]
24    #[br(temp)]
25    __security_buffer_offset: PosMarker<u16>,
26    #[bw(calc = u16::try_from(buffer.len()).unwrap())]
27    #[br(temp)]
28    security_buffer_length: u16,
29    /// Previously established session identifier for reconnection after network error
30    pub previous_session_id: u64,
31    #[br(count = security_buffer_length)]
32    #[bw(write_with = PosMarker::write_aoff, args(&__security_buffer_offset))]
33    /// Security buffer containing authentication token
34    pub buffer: Vec<u8>,
35}
36
37/// Security mode field specifying whether SMB signing is enabled or required at the client.
38///
39/// MS-SMB2 2.2.5
40#[smb_dtyp::mbitfield]
41pub struct SessionSecurityMode {
42    /// Security signatures are enabled on the client (ignored by server)
43    pub signing_enabled: bool,
44    /// Security signatures are required by the client
45    pub signing_required: bool,
46    #[skip]
47    __: B6,
48}
49
50/// Flags field for SESSION_SETUP request (SMB 3.x dialect family only).
51///
52/// MS-SMB2 2.2.5
53#[smb_dtyp::mbitfield]
54pub struct SetupRequestFlags {
55    /// Request is to bind an existing session to a new connection
56    pub binding: bool,
57    #[skip]
58    __: B7,
59}
60
61/// Protocol capabilities for the client.
62///
63/// MS-SMB2 2.2.5
64#[smb_dtyp::mbitfield]
65pub struct NegotiateCapabilities {
66    /// Client supports the Distributed File System (DFS)
67    pub dfs: bool,
68    #[skip]
69    __: B31,
70}
71
72impl SessionSetupRequest {
73    pub fn new(
74        buffer: Vec<u8>,
75        security_mode: SessionSecurityMode,
76        flags: SetupRequestFlags,
77        capabilities: NegotiateCapabilities,
78    ) -> SessionSetupRequest {
79        SessionSetupRequest {
80            flags,
81            security_mode,
82            capabilities,
83            previous_session_id: 0,
84            buffer,
85        }
86    }
87}
88
89/// SMB2 SESSION_SETUP Response packet sent by the server in response to a SESSION_SETUP Request.
90///
91/// MS-SMB2 2.2.6
92#[smb_response(size = 9)]
93pub struct SessionSetupResponse {
94    /// Flags indicating additional information about the session
95    pub session_flags: SessionFlags,
96    #[bw(calc = PosMarker::default())]
97    #[br(temp)]
98    _security_buffer_offset: PosMarker<u16>,
99    #[bw(calc = u16::try_from(buffer.len()).unwrap())]
100    #[br(temp)]
101    security_buffer_length: u16,
102    #[br(count = security_buffer_length)]
103    #[bw(write_with = PosMarker::write_aoff, args(&_security_buffer_offset))]
104    /// Security buffer containing authentication token
105    pub buffer: Vec<u8>,
106}
107
108/// Flags indicating additional information about the session.
109///
110/// MS-SMB2 2.2.6
111#[smb_dtyp::mbitfield]
112pub struct SessionFlags {
113    /// Client has been authenticated as a guest user
114    pub is_guest: bool,
115    /// Client has been authenticated as an anonymous user
116    pub is_null_session: bool,
117    /// Server requires encryption of messages on this session (SMB 3.x only)
118    pub encrypt_data: bool,
119    #[skip]
120    __: B13,
121}
122
123impl SessionFlags {
124    pub fn is_guest_or_null_session(&self) -> bool {
125        self.is_guest() || self.is_null_session()
126    }
127}
128
129/// SMB2 LOGOFF Request packet sent by the client to request termination of a particular session.
130///
131/// MS-SMB2 2.2.7
132#[smb_request(size = 4)]
133#[derive(Default)]
134pub struct LogoffRequest {
135    reserved: u16,
136}
137
138/// SMB2 LOGOFF Response packet sent by the server in response to a LOGOFF Request.
139///
140/// MS-SMB2 2.2.8
141#[smb_response(size = 4)]
142#[derive(Default)]
143pub struct LogoffResponse {
144    reserved: u16,
145}
146
147#[cfg(test)]
148mod tests {
149    use smb_tests::*;
150
151    use crate::*;
152
153    use super::*;
154
155    const SETUP_REQUEST_DATA: &'static str = "605706062b0601050502a04d304ba00e300c060a2b06010401823702020aa23904374e544c4d535350000100000097b208e2090009002e00000006000600280000000a005d580000000f41564956564d574f524b47524f5550";
156    test_request! {
157        SessionSetup {
158            flags: SetupRequestFlags::new(),
159            security_mode: SessionSecurityMode::new().with_signing_enabled(true),
160            buffer: hex_to_u8_array! {SETUP_REQUEST_DATA},
161            previous_session_id: 0,
162            capabilities: NegotiateCapabilities::new().with_dfs(true),
163        } => const_format::concatcp!("190000010100000000000000580059000000000000000000", SETUP_REQUEST_DATA)
164    }
165
166    const SETUP_RESPONSE_DATA: &'static str = "a181b03081ada0030a0101a10c060a2b06010401823702020aa281970481944e544c4d53535000020000000c000c003800000015c28ae2abf194bdb756daa9140001000000000050005000440000000a005d580000000f410056004900560056004d0002000c00410056004900560056004d0001000c00410056004900560056004d0004000c00410076006900760056006d0003000c00410076006900760056006d0007000800a876d878c569db0100000000";
167    test_response! {
168        SessionSetup {
169            session_flags: SessionFlags::new(),
170            buffer: hex_to_u8_array! {SETUP_RESPONSE_DATA}
171        } => const_format::concatcp!("090000004800b300", SETUP_RESPONSE_DATA)
172    }
173}