File Coverage

lib/SMB/v1/Commands.pm
Criterion Covered Total %
statement 9 35 25.7
branch 0 8 0.0
condition 0 2 0.0
subroutine 3 4 75.0
pod 0 1 0.0
total 12 50 24.0


line stmt bran cond sub pod time code
1             # SMB-Perl library, Copyright (C) 2014-2018 Mikhael Goikhman, migo@cpan.org
2             #
3             # This program is free software: you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation, either version 3 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16             package SMB::v1::Commands;
17              
18 1     1   4 use strict;
  1         2  
  1         21  
19 1     1   3 use warnings;
  1         2  
  1         17  
20              
21 1     1   326 use SMB::v1::Header;
  1         2  
  1         527  
22              
23             our $header_stamp = "\xffSMB";
24              
25             our @command_names = (
26             'CreateDirectory', # 0x00
27             'DeleteDirectory', # 0x01
28             'Open', # 0x02
29             'Create', # 0x03
30             'Close', # 0x04
31             'Flush', # 0x05
32             'Delete', # 0x06
33             'Rename', # 0x07
34             'QueryInformation', # 0x08
35             'SetInformation', # 0x09
36             'Read', # 0x0A
37             'Write', # 0x0B
38             'LockByteRange', # 0x0C
39             'UnlockByteRange', # 0x0D
40             'CreateTemporary', # 0x0E
41             'CreateNew', # 0x0F
42             'CheckDirectory', # 0x10
43             'ProcessExit', # 0x11
44             'Seek', # 0x12
45             'LockAndRead', # 0x13
46             'WriteAndUnlock', # 0x14
47             '', # 0x15
48             '', # 0x16
49             '', # 0x17
50             '', # 0x18
51             '', # 0x19
52             'ReadRaw', # 0x1A
53             'ReadMpx', # 0x1B
54             'ReadMpx2Secondary', # 0x1C
55             'WriteRaw', # 0x1D
56             'WriteMpx', # 0x1E
57             'WriteMpxSecondary', # 0X1F
58             'WriteComplete', # 0x20
59             'QueryServer', # 0x21
60             'SetInformation2', # 0x22
61             'QueryInformation2', # 0x23
62             'LockingAndX', # 0x24
63             'Transaction', # 0x25
64             'TransactionSecondary', # 0x26
65             'Ioctl', # 0x27
66             'IoctlSecondary', # 0x28
67             'Copy', # 0x29
68             'Move', # 0x2A
69             'Echo', # 0x2B
70             'WriteAndClose', # 0x2C
71             'OpenAndX', # 0x2D
72             'ReadAndX', # 0x2E
73             'WriteAndX', # 0x2F
74             'NewFileSize', # 0x30
75             'CloseAndTreeDisc', # 0x31
76             'Transaction2', # 0x32
77             'Transaction2Secondary', # 0x33
78             'FindClose2', # 0x34
79             'FindNotifyClose', # 0x35
80             '', # 0x36
81             '', # 0x37
82             '', # 0x38
83             '', # 0x39
84             '', # 0x3A
85             '', # 0x3B
86             '', # 0x3C
87             '', # 0x3D
88             '', # 0x3E
89             '', # 0x3F
90             '', # 0x40
91             '', # 0x41
92             '', # 0x42
93             '', # 0x43
94             '', # 0x44
95             '', # 0x45
96             '', # 0x46
97             '', # 0x47
98             '', # 0x48
99             '', # 0x49
100             '', # 0x4A
101             '', # 0x4B
102             '', # 0x4C
103             '', # 0x4D
104             '', # 0x4E
105             '', # 0x4F
106             '', # 0x50
107             '', # 0x51
108             '', # 0x52
109             '', # 0x53
110             '', # 0x54
111             '', # 0x55
112             '', # 0x56
113             '', # 0x57
114             '', # 0x58
115             '', # 0x59
116             '', # 0x5A
117             '', # 0x5B
118             '', # 0x5C
119             '', # 0x5D
120             '', # 0x5E
121             '', # 0x5F
122             '', # 0x60
123             '', # 0x61
124             '', # 0x62
125             '', # 0x63
126             '', # 0x64
127             '', # 0x65
128             '', # 0x66
129             '', # 0x67
130             '', # 0x68
131             '', # 0x69
132             '', # 0x6A
133             '', # 0x6B
134             '', # 0x6C
135             '', # 0x6D
136             '', # 0x6E
137             '', # 0x6F
138             'TreeConnect', # 0x70
139             'TreeDisconnect', # 0x71
140             'Negotiate', # 0x72
141             'SessionSetupAndX', # 0x73
142             'LogoffAndX', # 0x74
143             'TreeConnectAndX', # 0x75
144             '', # 0x76
145             '', # 0x77
146             '', # 0x78
147             '', # 0x79
148             '', # 0x7A
149             '', # 0x7B
150             '', # 0x7C
151             '', # 0x7D
152             'SecurityPackageAndX', # 0x7E
153             '', # 0x7F
154             'QueryInformationDisk', # 0x80
155             'Search', # 0x81
156             'Find', # 0x82
157             'FindUnique', # 0x83
158             'FindClose', # 0x84
159             '', # 0x85
160             '', # 0x86
161             '', # 0x87
162             '', # 0x88
163             '', # 0x89
164             '', # 0x8A
165             '', # 0x8B
166             '', # 0x8C
167             '', # 0x8D
168             '', # 0x8E
169             '', # 0x8F
170             '', # 0x90
171             '', # 0x91
172             '', # 0x92
173             '', # 0x93
174             '', # 0x94
175             '', # 0x95
176             '', # 0x96
177             '', # 0x97
178             '', # 0x98
179             '', # 0x99
180             '', # 0x9A
181             '', # 0x9B
182             '', # 0x9C
183             '', # 0x9D
184             '', # 0x9E
185             '', # 0x9F
186             'NtTransact', # 0xA0
187             'NtTransactSecondary', # 0xA1
188             'NtCreateAndX', # 0xA2
189             '', # 0xA3
190             'NtCancel', # 0xA4
191             'NtRename', # 0xA5
192             '', # 0xA6
193             '', # 0xA7
194             '', # 0xA8
195             '', # 0xA9
196             '', # 0xAA
197             '', # 0xAB
198             '', # 0xAC
199             '', # 0xAD
200             '', # 0xAE
201             '', # 0xAF
202             '', # 0xB0
203             '', # 0xB1
204             '', # 0xB2
205             '', # 0xB3
206             '', # 0xB4
207             '', # 0xB5
208             '', # 0xB6
209             '', # 0xB7
210             '', # 0xB8
211             '', # 0xB9
212             '', # 0xBA
213             '', # 0xBB
214             '', # 0xBC
215             '', # 0xBD
216             '', # 0xBE
217             '', # 0xBF
218             'OpenPrintFile', # 0xC0
219             'WritePrintFile', # 0xC1
220             'ClosePrintFile', # 0xC2
221             'GetPrintQueue', # 0xC3
222             '', # 0xC4
223             '', # 0xC5
224             '', # 0xC6
225             '', # 0xC7
226             '', # 0xC8
227             '', # 0xC9
228             '', # 0xCA
229             '', # 0xCB
230             '', # 0xCC
231             '', # 0xCD
232             '', # 0xCE
233             '', # 0xCF
234             '', # 0xD0
235             '', # 0xD1
236             '', # 0xD2
237             '', # 0xD3
238             '', # 0xD4
239             '', # 0xD5
240             '', # 0xD6
241             '', # 0xD7
242             'ReadBulk', # 0xD8
243             'WriteBulk', # 0xD9
244             'WriteBulkData', # 0xDA
245             '', # 0xDB
246             '', # 0xDC
247             '', # 0xDD
248             '', # 0xDE
249             '', # 0xDF
250             '', # 0xE0
251             '', # 0xE1
252             '', # 0xE2
253             '', # 0xE3
254             '', # 0xE4
255             '', # 0xE5
256             '', # 0xE6
257             '', # 0xE7
258             '', # 0xE8
259             '', # 0xE9
260             '', # 0xEA
261             '', # 0xEB
262             '', # 0xEC
263             '', # 0xED
264             '', # 0xEE
265             '', # 0xEF
266             '', # 0xF0
267             '', # 0xF1
268             '', # 0xF2
269             '', # 0xF3
270             '', # 0xF4
271             '', # 0xF5
272             '', # 0xF6
273             '', # 0xF7
274             '', # 0xF8
275             '', # 0xF9
276             '', # 0xFA
277             '', # 0xFB
278             '', # 0xFC
279             '', # 0xFD
280             '', # 0xFE
281             '', # 0xFF
282             );
283              
284             our %command_codes = map { $command_names[$_] => $_ } 0 .. $#command_names;
285              
286             our $MIN_MESSAGE_SIZE = 33;
287              
288             sub parse ($$) {
289 0     0 0   my $class = shift;
290 0   0       my $parser = shift || die;
291              
292 0 0         if ($parser->size < $MIN_MESSAGE_SIZE) {
293 0           warn sprintf "Too short message to parse (%d, should be at least %d)\n", $parser->size, $MIN_MESSAGE_SIZE;
294 0           return;
295             }
296              
297             # parse header following the SMB1 stamp "\xffSMB"
298 0           my $code = $parser->uint8;
299 0           my $status = $parser->uint32;
300 0           my $flags = $parser->uint8;
301 0           my $flags2 = $parser->uint16;
302 0           my $pid_h = $parser->uint16;
303 0           my $sign = $parser->bytes(8);
304 0           $parser->skip(2); # reserved
305 0           my $tid = $parser->uint16;
306 0           my $pid_l = $parser->uint16;
307 0           my $uid = $parser->uint16;
308 0           my $mid = $parser->uint16;
309              
310 0           my $header = SMB::v1::Header->new(
311             code => $code,
312             status => $status,
313             uid => $uid,
314             tid => $tid,
315             mid => $mid,
316             signature => $sign,
317             pid => $pid_h << 16 + $pid_l,
318             flags => $flags,
319             flags2 => $flags2,
320             );
321              
322 0           my $command_name = $command_names[$code];
323 0           my $command;
324              
325 0 0         if ($command_name) {
326 0           my $command_class = "SMB::v1::Command::$command_name";
327 0           my $command_filename = "SMB/v1/Command/$command_name.pm";
328 0 0         require $command_filename unless $INC{$command_filename};
329              
330 0 0         $command = $command_class->new($header)->parse($parser)
331             or warn sprintf "Failed to parse SMB1 command 0x%x ($command_name)\n", $code;
332             } else {
333 0           warn sprintf "Got unexisting SMB1 command 0x%x\n", $code;
334             }
335              
336 0           return $command;
337             }
338              
339             1;