signing: disable signing if authentication failed but guest login is enabled
[scrambla.git] / smb2 / session_setup.py
1 # coding: utf-8
2
3 # Copyright (C) 2020 by Ronnie Sahlberg<ronniesahlberg@gmail.com>
4 #
5
6 import struct
7 from enum import Enum
8
9 from smb2.header import Direction
10
11 #
12 # SMB2 Session Setup
13 #
14
15 #
16 # Flags
17 #
18 SMB2_SESSION_FLAG_BINDING = 0x01
19
20 #
21 # Security Mode
22 #
23 SMB2_NEGOTIATE_SIGNING_ENABLED  = 0x01
24 SMB2_NEGOTIATE_SIGNING_REQUIRED = 0x02
25
26 #
27 # Capabilities
28 #
29 SMB2_GLOBAL_CAP_DFS = 0x00000001
30
31 #
32 # Session Flags
33 #
34 SMB2_SESSION_FLAG_IS_GUEST     = 0x0001
35 SMB2_SESSION_FLAG_IS_NULL      = 0x0002
36 SMB2_SESSION_FLAG_ENCRYPT_DATA = 0x0004
37
38
39 def _decode_request(hdr):
40     """
41     Decode a Session Setup request
42     """
43     result = {}
44     result.update({'structure_size': struct.unpack_from('<H', hdr, 0)[0]})
45     result.update({'flags': struct.unpack_from('<B', hdr, 2)[0]})
46     result.update({'security_mode': struct.unpack_from('<B', hdr, 3)[0]})
47     result.update({'capabilities': struct.unpack_from('<I', hdr, 4)[0]})
48     result.update({'previous_session_id': hdr[16:16 + 8]})
49
50     _offset = struct.unpack_from('<H', hdr, 12)[0] - 64
51     _len = struct.unpack_from('<H', hdr, 14)[0]
52     if _len:
53         result.update({'security_buffer': hdr[_offset:_offset + _len]})
54
55     return result
56
57 def _encode_request(hdr):
58     """
59     Encode a Session Setup request
60     """
61     result = bytearray(24)
62     struct.pack_into('<H', result, 0, 25)
63     struct.pack_into('<B', result, 2, hdr['flags'])
64     struct.pack_into('<B', result, 3, hdr['security_mode'])    
65     struct.pack_into('<I', result, 4, hdr['capabilities'])
66     if 'previous_session_id' in hdr:
67         result[16:16 + 8] = hdr['previous_session_id']
68
69     if 'security_buffer' in hdr:
70         struct.pack_into('<H', result, 12, 24 + 64)
71         struct.pack_into('<H', result, 14, len(hdr['security_buffer']))
72
73         result = result + hdr['security_buffer']
74
75     return result
76
77 def _decode_reply(hdr):
78     """
79     Decode a Session Setup reply
80     """
81     result = {}
82     result.update({'structure_size': struct.unpack_from('<H', hdr, 0)[0]})
83     result.update({'session_flags': struct.unpack_from('<H', hdr, 2)[0]})
84     _offset = struct.unpack_from('<H', hdr, 4)[0] - 64
85     _len = struct.unpack_from('<H', hdr, 6)[0]
86     if _len:
87         result.update({'security_buffer': hdr[_offset:_offset + _len]})
88     
89     return result
90
91 def _encode_reply(hdr):
92     """
93     Encode a Session Setup reply
94     """
95     result = bytearray(8)
96     struct.pack_into('<H', result, 0, 9)
97     struct.pack_into('<H', result, 2, hdr['session_flags'])
98     struct.pack_into('<H', result, 4, 8 + 64)
99     if 'security_buffer' in hdr:
100         struct.pack_into('<H', result, 6, len(hdr['security_buffer']))
101         result = result + hdr['security_buffer']
102
103     return result
104
105
106 class SessionSetup(object):
107     """
108     A class for Session Setup
109     """
110
111     def __init__(self, **kwargs):
112         True
113
114     def __del__(self):
115         True
116
117     @staticmethod
118     def decode(direction, hdr):
119         """
120         Decode a Session Setup PDU
121         """
122         if direction == Direction.REPLY:
123             return _decode_reply(hdr)
124         return _decode_request(hdr)
125
126     @staticmethod
127     def encode(direction, hdr):
128         """
129         Encode a Session Setup PDU
130         """
131         if direction == Direction.REPLY:
132             return _encode_reply(hdr)
133         return _encode_request(hdr)
134