@@ -7,54 +7,161 @@ use crate::{
77 crypto,
88 packets:: smb2:: {
99 CompressionCaps , Dialect , GlobalCapabilities , NegotiateResponse , SigningAlgorithmId ,
10+ TreeCapabilities , TreeConnectShareFlagsCacheMode , TreeShareFlags ,
1011 } ,
1112 ConnectionConfig , Error ,
1213} ;
1314
14- pub trait DialectImpl : std:: fmt:: Debug + Send + Sync {
15- fn get_dialect ( & self ) -> Dialect ;
16- fn get_negotiate_caps_mask ( & self ) -> GlobalCapabilities ;
17- fn process_negotiate_request (
15+ /// This is a utility struct that returns constants and functions for the given dialect.
16+ #[ derive( Debug ) ]
17+ pub struct DialectImpl {
18+ pub dialect : Dialect ,
19+ }
20+
21+ impl DialectImpl {
22+ pub fn new ( dialect : Dialect ) -> Arc < Self > {
23+ Arc :: new ( Self { dialect } )
24+ }
25+
26+ pub fn get_negotiate_caps_mask ( & self ) -> GlobalCapabilities {
27+ let mut mask = GlobalCapabilities :: new ( )
28+ . with_dfs ( true )
29+ . with_leasing ( true )
30+ . with_large_mtu ( true )
31+ . with_multi_channel ( true )
32+ . with_persistent_handles ( true )
33+ . with_directory_leasing ( true ) ;
34+
35+ mask. set_encryption ( Dialect :: Smb030 <= self . dialect && self . dialect <= Dialect :: Smb0302 ) ;
36+ mask. set_notifications ( self . dialect == Dialect :: Smb0311 ) ;
37+
38+ mask
39+ }
40+
41+ pub fn get_share_flags_mask ( & self ) -> TreeShareFlags {
42+ let mut mask = TreeShareFlags :: new ( )
43+ . with_caching_mode ( TreeConnectShareFlagsCacheMode :: All )
44+ . with_dfs ( true )
45+ . with_dfs_root ( true )
46+ . with_restrict_exclusive_opens ( true )
47+ . with_force_shared_delete ( true )
48+ . with_allow_namespace_caching ( true )
49+ . with_access_based_directory_enum ( true )
50+ . with_force_levelii_oplock ( true )
51+ . with_identity_remoting ( true )
52+ . with_isolated_transport ( true ) ;
53+
54+ if self . dialect > Dialect :: Smb0202 {
55+ mask. set_enable_hash_v1 ( true ) ;
56+ }
57+ if self . dialect >= Dialect :: Smb021 {
58+ mask. set_enable_hash_v2 ( true ) ;
59+ }
60+ if self . dialect . is_smb3 ( ) {
61+ mask. set_encrypt_data ( true ) ;
62+ }
63+ if self . dialect >= Dialect :: Smb0311 {
64+ mask. set_compress_data ( true ) ;
65+ }
66+
67+ mask
68+ }
69+
70+ pub fn get_tree_connect_caps_mask ( & self ) -> TreeCapabilities {
71+ let mut mask = TreeCapabilities :: new ( ) . with_dfs ( true ) ;
72+
73+ if self . dialect . is_smb3 ( ) {
74+ mask = mask
75+ . with_continuous_availability ( true )
76+ . with_scaleout ( true )
77+ . with_cluster ( true ) ;
78+ }
79+
80+ if self . dialect >= Dialect :: Smb0302 {
81+ mask. set_asymmetric ( true ) ;
82+ }
83+
84+ if self . dialect == Dialect :: Smb0311 {
85+ mask = mask. with_redirect_to_owner ( true ) ;
86+ }
87+
88+ mask
89+ }
90+
91+ pub fn process_negotiate_request (
1892 & self ,
1993 response : & NegotiateResponse ,
2094 state : & mut NegotiatedProperties ,
2195 config : & ConnectionConfig ,
22- ) -> crate :: Result < ( ) > ;
96+ ) -> crate :: Result < ( ) > {
97+ match self . dialect {
98+ Dialect :: Smb0311 => Smb311 . process_negotiate_request ( response, state, config) ,
99+ Dialect :: Smb0302 | Dialect :: Smb030 => {
100+ Smb300_302 . process_negotiate_request ( response, state, config)
101+ }
102+ _ => unimplemented ! ( ) ,
103+ }
104+ }
23105
24- fn get_signing_nonce ( & self ) -> & [ u8 ] ;
25- fn preauth_hash_supported ( & self ) -> bool ;
26- fn default_signing_algo ( & self ) -> SigningAlgorithmId {
27- SigningAlgorithmId :: HmacSha256
106+ pub fn get_signing_derive_label ( & self ) -> & [ u8 ] {
107+ match self . dialect {
108+ Dialect :: Smb0311 => Smb311 :: SIGNING_KEY_LABEL ,
109+ Dialect :: Smb0302 | Dialect :: Smb030 => Smb300_302 :: SIGNING_KEY_LABEL ,
110+ _ => unimplemented ! ( ) ,
111+ }
112+ }
113+ pub fn preauth_hash_supported ( & self ) -> bool {
114+ self . dialect == Dialect :: Smb0311
115+ }
116+ pub fn default_signing_algo ( & self ) -> SigningAlgorithmId {
117+ match self . dialect {
118+ Dialect :: Smb0311 | Dialect :: Smb0302 | Dialect :: Smb030 => SigningAlgorithmId :: AesCmac ,
119+ Dialect :: Smb0202 | Dialect :: Smb021 => SigningAlgorithmId :: HmacSha256 ,
120+ }
28121 }
29122
30- fn supports_compression ( & self ) -> bool {
31- false
123+ pub fn supports_compression ( & self ) -> bool {
124+ self . dialect == Dialect :: Smb0311
32125 }
33126
34- fn supports_encryption ( & self ) -> bool {
35- false
127+ pub fn supports_encryption ( & self ) -> bool {
128+ self . dialect . is_smb3 ( )
36129 }
37- fn s2c_encryption_key_label ( & self ) -> & [ u8 ] ;
38- fn c2s_encryption_key_label ( & self ) -> & [ u8 ] ;
39- }
40130
41- /// Get the dialect implementation for the given dialect.
42- pub fn get_dialect_impl ( dialect : & Dialect ) -> Arc < dyn DialectImpl > {
43- match dialect {
44- Dialect :: Smb0311 => Arc :: new ( Smb0311Dialect ) ,
45- Dialect :: Smb0302 => Arc :: new ( Smb302Dialect ) ,
46- _ => unimplemented ! ( ) ,
131+ pub fn s2c_encrypt_key_derive_label ( & self ) -> & [ u8 ] {
132+ match self . dialect {
133+ Dialect :: Smb0311 => Smb311 :: ENCRYPTION_S2C_KEY_LABEL ,
134+ Dialect :: Smb0302 | Dialect :: Smb030 => Smb300_302 :: ENCRYPTION_KEY_LABEL ,
135+ _ => panic ! ( "Encryption is not supported for this dialect!" ) ,
136+ }
137+ }
138+ pub fn c2s_encrypt_key_derive_label ( & self ) -> & [ u8 ] {
139+ match self . dialect {
140+ Dialect :: Smb0311 => Smb311 :: ENCRYPTION_C2S_KEY_LABEL ,
141+ Dialect :: Smb0302 | Dialect :: Smb030 => Smb300_302 :: ENCRYPTION_KEY_LABEL ,
142+ _ => panic ! ( "Encryption is not supported for this dialect!" ) ,
143+ }
47144 }
48145}
49146
50- #[ derive( Debug ) ]
51- struct Smb0311Dialect ;
147+ trait DialectMethods {
148+ const SIGNING_KEY_LABEL : & [ u8 ] ;
149+ fn process_negotiate_request (
150+ & self ,
151+ response : & NegotiateResponse ,
152+ _state : & mut NegotiatedProperties ,
153+ config : & ConnectionConfig ,
154+ ) -> crate :: Result < ( ) > ;
155+ }
52156
53- impl DialectImpl for Smb0311Dialect {
54- fn get_dialect ( & self ) -> Dialect {
55- Dialect :: Smb0311
56- }
157+ struct Smb311 ;
158+ impl Smb311 {
159+ pub const ENCRYPTION_S2C_KEY_LABEL : & [ u8 ] = b"SMBS2CCipherKey\x00 " ;
160+ pub const ENCRYPTION_C2S_KEY_LABEL : & [ u8 ] = b"SMBC2SCipherKey\x00 " ;
161+ }
57162
163+ impl DialectMethods for Smb311 {
164+ const SIGNING_KEY_LABEL : & [ u8 ] = b"SMBSigningKey\x00 " ;
58165 fn process_negotiate_request (
59166 & self ,
60167 response : & NegotiateResponse ,
@@ -112,55 +219,15 @@ impl DialectImpl for Smb0311Dialect {
112219
113220 Ok ( ( ) )
114221 }
115-
116- fn get_negotiate_caps_mask ( & self ) -> GlobalCapabilities {
117- GlobalCapabilities :: new ( )
118- . with_dfs ( true )
119- . with_leasing ( true )
120- . with_large_mtu ( true )
121- . with_multi_channel ( true )
122- . with_persistent_handles ( true )
123- . with_directory_leasing ( true )
124- . with_encryption ( false )
125- . with_notifications ( true )
126- }
127-
128- fn get_signing_nonce ( & self ) -> & [ u8 ] {
129- b"SMBSigningKey\x00 "
130- }
131-
132- fn preauth_hash_supported ( & self ) -> bool {
133- true
134- }
135-
136- fn default_signing_algo ( & self ) -> SigningAlgorithmId {
137- SigningAlgorithmId :: AesCmac
138- }
139-
140- fn supports_compression ( & self ) -> bool {
141- true
142- }
143- fn supports_encryption ( & self ) -> bool {
144- true
145- }
146- fn s2c_encryption_key_label ( & self ) -> & [ u8 ] {
147- b"SMBS2CCipherKey\x00 "
148- }
149- fn c2s_encryption_key_label ( & self ) -> & [ u8 ] {
150- b"SMBC2SCipherKey\x00 "
151- }
152222}
153223
154- const SMB2_ENCRYPTION_KEY_LABEL : & [ u8 ] = b"SMB2AESCCM\x00 " ;
155-
156- #[ derive( Debug ) ]
157- struct Smb302Dialect ;
158-
159- impl DialectImpl for Smb302Dialect {
160- fn get_dialect ( & self ) -> Dialect {
161- Dialect :: Smb0302
162- }
224+ struct Smb300_302 ;
225+ impl Smb300_302 {
226+ pub const ENCRYPTION_KEY_LABEL : & [ u8 ] = b"SMB2AESCCM\x00 " ;
227+ }
163228
229+ impl DialectMethods for Smb300_302 {
230+ const SIGNING_KEY_LABEL : & [ u8 ] = b"SMB2AESCMAC\x00 " ;
164231 fn process_negotiate_request (
165232 & self ,
166233 response : & NegotiateResponse ,
@@ -181,40 +248,4 @@ impl DialectImpl for Smb302Dialect {
181248
182249 Ok ( ( ) )
183250 }
184-
185- fn get_negotiate_caps_mask ( & self ) -> GlobalCapabilities {
186- GlobalCapabilities :: new ( )
187- . with_dfs ( true )
188- . with_leasing ( true )
189- . with_large_mtu ( true )
190- . with_multi_channel ( true )
191- . with_persistent_handles ( true )
192- . with_directory_leasing ( true )
193- . with_encryption ( true )
194- . with_notifications ( false )
195- }
196-
197- fn get_signing_nonce ( & self ) -> & [ u8 ] {
198- b"SMB2AESCMAC\x00 "
199- }
200-
201- fn preauth_hash_supported ( & self ) -> bool {
202- false
203- }
204-
205- fn default_signing_algo ( & self ) -> SigningAlgorithmId {
206- SigningAlgorithmId :: AesCmac
207- }
208-
209- fn supports_encryption ( & self ) -> bool {
210- true
211- }
212-
213- fn s2c_encryption_key_label ( & self ) -> & [ u8 ] {
214- SMB2_ENCRYPTION_KEY_LABEL
215- }
216-
217- fn c2s_encryption_key_label ( & self ) -> & [ u8 ] {
218- SMB2_ENCRYPTION_KEY_LABEL
219- }
220251}
0 commit comments