Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Impacket - Collection of Python classes for working with network protocols. 

2# 

3# SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 

4# 

5# This software is provided under a slightly modified version 

6# of the Apache Software License. See the accompanying LICENSE file 

7# for more information. 

8# 

9# Author: 

10# Altered source done by Alberto Solino (@agsolino) 

11# 

12# Copyright and license note from Pysmb: 

13# 

14# Copyright (C) 2001 Michael Teo <michaelteo@bigfoot.com> 

15# smb.py - SMB/CIFS library 

16# 

17# This software is provided 'as-is', without any express or implied warranty. 

18# In no event will the author be held liable for any damages arising from the 

19# use of this software. 

20# 

21# Permission is granted to anyone to use this software for any purpose, 

22# including commercial applications, and to alter it and redistribute it 

23# freely, subject to the following restrictions: 

24# 

25# 1. The origin of this software must not be misrepresented; you must not 

26# claim that you wrote the original software. If you use this software 

27# in a product, an acknowledgment in the product documentation would be 

28# appreciated but is not required. 

29# 

30# 2. Altered source versions must be plainly marked as such, and must not be 

31# misrepresented as being the original software. 

32# 

33# 3. This notice cannot be removed or altered from any source distribution. 

34# 

35# Todo: 

36# [ ] Try [SMB]transport fragmentation using Transact requests 

37# [ ] Try other methods of doing write (write_raw, transact2, write, write_and_unlock, write_and_close, write_mpx) 

38# [-] Try replacements for SMB_COM_NT_CREATE_ANDX (CREATE, T_TRANSACT_CREATE, OPEN_ANDX works 

39# [x] Fix forceWriteAndx, which needs to send a RecvRequest, because recv() will not send it 

40# [x] Fix Recv() when using RecvAndx and the answer comes splet in several packets 

41# [ ] Try [SMB]transport fragmentation with overlapping segments 

42# [ ] Try [SMB]transport fragmentation with out of order segments 

43# [x] Do chained AndX requests 

44# [ ] Transform the rest of the calls to structure 

45# [X] Implement TRANS/TRANS2 reassembly for list_path 

46# 

47from __future__ import division 

48from __future__ import print_function 

49import os 

50import socket 

51from binascii import a2b_hex 

52import datetime 

53from struct import pack, unpack 

54from contextlib import contextmanager 

55from pyasn1.type.univ import noValue 

56 

57from impacket import nmb, ntlm, nt_errors, LOG 

58from impacket.structure import Structure 

59from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp, ASN1_OID, asn1encode, ASN1_AID 

60from impacket.krb5.gssapi import KRB5_AP_REQ 

61 

62# For signing 

63import hashlib 

64 

65unicode_support = 0 

66unicode_convert = 1 

67 

68# Dialect for SMB1 

69SMB_DIALECT = 'NT LM 0.12' 

70 

71# Shared Device Type 

72SHARED_DISK = 0x00 

73SHARED_DISK_HIDDEN = 0x80000000 

74SHARED_PRINT_QUEUE = 0x01 

75SHARED_DEVICE = 0x02 

76SHARED_IPC = 0x03 

77 

78# Extended attributes mask 

79ATTR_ARCHIVE = 0x020 

80ATTR_COMPRESSED = 0x800 

81ATTR_NORMAL = 0x080 

82ATTR_HIDDEN = 0x002 

83ATTR_READONLY = 0x001 

84ATTR_TEMPORARY = 0x100 

85ATTR_DIRECTORY = 0x010 

86ATTR_SYSTEM = 0x004 

87 

88# Service Type 

89SERVICE_DISK = 'A:' 

90SERVICE_PRINTER = 'LPT1:' 

91SERVICE_IPC = 'IPC' 

92SERVICE_COMM = 'COMM' 

93SERVICE_ANY = '?????' 

94 

95# Server Type (Can be used to mask with SMBMachine.get_type() or SMBDomain.get_type()) 

96SV_TYPE_WORKSTATION = 0x00000001 

97SV_TYPE_SERVER = 0x00000002 

98SV_TYPE_SQLSERVER = 0x00000004 

99SV_TYPE_DOMAIN_CTRL = 0x00000008 

100SV_TYPE_DOMAIN_BAKCTRL = 0x00000010 

101SV_TYPE_TIME_SOURCE = 0x00000020 

102SV_TYPE_AFP = 0x00000040 

103SV_TYPE_NOVELL = 0x00000080 

104SV_TYPE_DOMAIN_MEMBER = 0x00000100 

105SV_TYPE_PRINTQ_SERVER = 0x00000200 

106SV_TYPE_DIALIN_SERVER = 0x00000400 

107SV_TYPE_XENIX_SERVER = 0x00000800 

108SV_TYPE_NT = 0x00001000 

109SV_TYPE_WFW = 0x00002000 

110SV_TYPE_SERVER_NT = 0x00004000 

111SV_TYPE_POTENTIAL_BROWSER = 0x00010000 

112SV_TYPE_BACKUP_BROWSER = 0x00020000 

113SV_TYPE_MASTER_BROWSER = 0x00040000 

114SV_TYPE_DOMAIN_MASTER = 0x00080000 

115SV_TYPE_LOCAL_LIST_ONLY = 0x40000000 

116SV_TYPE_DOMAIN_ENUM = 0x80000000 

117 

118# Options values for SMB.stor_file and SMB.retr_file 

119SMB_O_CREAT = 0x10 # Create the file if file does not exists. Otherwise, operation fails. 

120SMB_O_EXCL = 0x00 # When used with SMB_O_CREAT, operation fails if file exists. Cannot be used with SMB_O_OPEN. 

121SMB_O_OPEN = 0x01 # Open the file if the file exists 

122SMB_O_TRUNC = 0x02 # Truncate the file if the file exists 

123 

124# Share Access Mode 

125SMB_SHARE_COMPAT = 0x00 

126SMB_SHARE_DENY_EXCL = 0x10 

127SMB_SHARE_DENY_WRITE = 0x20 

128SMB_SHARE_DENY_READEXEC = 0x30 

129SMB_SHARE_DENY_NONE = 0x40 

130SMB_ACCESS_READ = 0x00 

131SMB_ACCESS_WRITE = 0x01 

132SMB_ACCESS_READWRITE = 0x02 

133SMB_ACCESS_EXEC = 0x03 

134 

135TRANS_DISCONNECT_TID = 1 

136TRANS_NO_RESPONSE = 2 

137 

138STATUS_SUCCESS = 0x00000000 

139STATUS_LOGON_FAILURE = 0xC000006D 

140STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B 

141MAX_TFRAG_SIZE = 5840 

142EVASION_NONE = 0 

143EVASION_LOW = 1 

144EVASION_HIGH = 2 

145EVASION_MAX = 3 

146RPC_X_BAD_STUB_DATA = 0x6F7 

147 

148# SMB_FILE_ATTRIBUTES 

149 

150SMB_FILE_ATTRIBUTE_NORMAL = 0x0000 

151SMB_FILE_ATTRIBUTE_READONLY = 0x0001 

152SMB_FILE_ATTRIBUTE_HIDDEN = 0x0002 

153SMB_FILE_ATTRIBUTE_SYSTEM = 0x0004 

154SMB_FILE_ATTRIBUTE_VOLUME = 0x0008 

155SMB_FILE_ATTRIBUTE_DIRECTORY = 0x0010 

156SMB_FILE_ATTRIBUTE_ARCHIVE = 0x0020 

157SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100 

158SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200 

159SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400 

160SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000 

161SMB_SEARCH_ATTRIBUTE_ARCHIVE = 0x2000 

162 

163# Session SetupAndX Action flags 

164SMB_SETUP_GUEST = 0x01 

165SMB_SETUP_USE_LANMAN_KEY = 0x02 

166 

167# QUERY_INFORMATION levels 

168SMB_INFO_ALLOCATION = 0x0001 

169SMB_INFO_VOLUME = 0x0002 

170FILE_FS_SIZE_INFORMATION = 0x0003 

171SMB_QUERY_FS_VOLUME_INFO = 0x0102 

172SMB_QUERY_FS_SIZE_INFO = 0x0103 

173SMB_QUERY_FILE_EA_INFO = 0x0103 

174SMB_QUERY_FS_DEVICE_INFO = 0x0104 

175SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105 

176SMB_QUERY_FILE_BASIC_INFO = 0x0101 

177SMB_QUERY_FILE_STANDARD_INFO = 0x0102 

178SMB_QUERY_FILE_ALL_INFO = 0x0107 

179FILE_FS_FULL_SIZE_INFORMATION = 0x03EF 

180 

181# SET_INFORMATION levels 

182SMB_SET_FILE_DISPOSITION_INFO = 0x0102 

183SMB_SET_FILE_BASIC_INFO = 0x0101 

184SMB_SET_FILE_END_OF_FILE_INFO = 0x0104 

185 

186# Device Type [MS-CIFS] 2.2.8.2.5 

187FILE_DEVICE_BEEP = 0x0001 

188FILE_DEVICE_CD_ROM = 0x0002 

189FILE_DEVICE_CD_ROM_FILE_SYSTEM = 0x0003 

190FILE_DEVICE_CONTROLLER = 0x0004 

191FILE_DEVICE_DATALINK = 0x0005 

192FILE_DEVICE_DFS = 0x0006 

193FILE_DEVICE_DISK = 0x0007 

194FILE_DEVICE_DISK_FILE_SYSTEM = 0x0008 

195FILE_DEVICE_FILE_SYSTEM = 0x0009 

196FILE_DEVICE_INPORT_PORT = 0x000a 

197FILE_DEVICE_KEYBOARD = 0x000b 

198FILE_DEVICE_MAILSLOT = 0x000c 

199FILE_DEVICE_MIDI_IN = 0x000d 

200FILE_DEVICE_MIDI_OUT = 0x000e 

201FILE_DEVICE_MOUSE = 0x000f 

202FILE_DEVICE_MULTI_UNC_PROVIDER = 0x0010 

203FILE_DEVICE_NAMED_PIPE = 0x0011 

204FILE_DEVICE_NETWORK = 0x0012 

205FILE_DEVICE_NETWORK_BROWSER = 0x0013 

206FILE_DEVICE_NETWORK_FILE_SYSTEM = 0x0014 

207FILE_DEVICE_NULL = 0x0015 

208FILE_DEVICE_PARALLEL_PORT = 0x0016 

209FILE_DEVICE_PHYSICAL_NETCARD = 0x0017 

210FILE_DEVICE_PRINTER = 0x0018 

211FILE_DEVICE_SCANNER = 0x0019 

212FILE_DEVICE_SERIAL_MOUSE_PORT = 0x001a 

213FILE_DEVICE_SERIAL_PORT = 0x001b 

214FILE_DEVICE_SCREEN = 0x001c 

215FILE_DEVICE_SOUND = 0x001d 

216FILE_DEVICE_STREAMS = 0x001e 

217FILE_DEVICE_TAPE = 0x001f 

218FILE_DEVICE_TAPE_FILE_SYSTEM = 0x0020 

219FILE_DEVICE_TRANSPORT = 0x0021 

220FILE_DEVICE_UNKNOWN = 0x0022 

221FILE_DEVICE_VIDEO = 0x0023 

222FILE_DEVICE_VIRTUAL_DISK = 0x0024 

223FILE_DEVICE_WAVE_IN = 0x0025 

224FILE_DEVICE_WAVE_OUT = 0x0026 

225FILE_DEVICE_8042_PORT = 0x0027 

226FILE_DEVICE_NETWORK_REDIRECTOR = 0x0028 

227FILE_DEVICE_BATTERY = 0x0029 

228FILE_DEVICE_BUS_EXTENDER = 0x002a 

229FILE_DEVICE_MODEM = 0x002b 

230FILE_DEVICE_VDM = 0x002c 

231 

232# Device Characteristics [MS-CIFS] 2.2.8.2.5 

233FILE_REMOVABLE_MEDIA = 0x0001 

234FILE_READ_ONLY_DEVICE = 0x0002 

235FILE_FLOPPY_DISKETTE = 0x0004 

236FILE_WRITE_ONCE_MEDIA = 0x0008 

237FILE_REMOTE_DEVICE = 0x0010 

238FILE_DEVICE_IS_MOUNTED = 0x0020 

239FILE_VIRTUAL_VOLUME = 0x0040 

240 

241# File System Attributes 

242FILE_CASE_SENSITIVE_SEARCH = 0x00000001 

243FILE_CASE_PRESERVED_NAMES = 0x00000002 

244FILE_UNICODE_ON_DISK = 0x00000004 

245FILE_PERSISTENT_ACLS = 0x00000008 

246FILE_FILE_COMPRESSION = 0x00000010 

247FILE_VOLUME_IS_COMPRESSED = 0x00008000 

248 

249# FIND_FIRST2 flags and levels 

250SMB_FIND_CLOSE_AFTER_REQUEST = 0x0001 

251SMB_FIND_CLOSE_AT_EOS = 0x0002 

252SMB_FIND_RETURN_RESUME_KEYS = 0x0004 

253SMB_FIND_CONTINUE_FROM_LAST = 0x0008 

254SMB_FIND_WITH_BACKUP_INTENT = 0x0010 

255 

256FILE_DIRECTORY_FILE = 0x00000001 

257FILE_DELETE_ON_CLOSE = 0x00001000 

258FILE_NON_DIRECTORY_FILE = 0x00000040 

259 

260SMB_FIND_INFO_STANDARD = 0x0001 

261SMB_FIND_FILE_DIRECTORY_INFO = 0x0101 

262SMB_FIND_FILE_FULL_DIRECTORY_INFO= 0x0102 

263SMB_FIND_FILE_NAMES_INFO = 0x0103 

264SMB_FIND_FILE_BOTH_DIRECTORY_INFO= 0x0104 

265SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO = 0x105 

266SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO = 0x106 

267 

268 

269# DesiredAccess flags 

270FILE_READ_DATA = 0x00000001 

271FILE_WRITE_DATA = 0x00000002 

272FILE_APPEND_DATA = 0x00000004 

273FILE_EXECUTE = 0x00000020 

274MAXIMUM_ALLOWED = 0x02000000 

275GENERIC_ALL = 0x10000000 

276GENERIC_EXECUTE = 0x20000000 

277GENERIC_WRITE = 0x40000000 

278GENERIC_READ = 0x80000000 

279 

280# ShareAccess flags 

281FILE_SHARE_NONE = 0x00000000 

282FILE_SHARE_READ = 0x00000001 

283FILE_SHARE_WRITE = 0x00000002 

284FILE_SHARE_DELETE = 0x00000004 

285 

286# CreateDisposition flags 

287FILE_SUPERSEDE = 0x00000000 

288FILE_OPEN = 0x00000001 

289FILE_CREATE = 0x00000002 

290FILE_OPEN_IF = 0x00000003 

291FILE_OVERWRITE = 0x00000004 

292FILE_OVERWRITE_IF = 0x00000005 

293 

294def strerror(errclass, errcode): 

295 if errclass == 0x01: 

296 return 'OS error', ERRDOS.get(errcode, 'Unknown error') 

297 elif errclass == 0x02: 

298 return 'Server error', ERRSRV.get(errcode, 'Unknown error') 

299 elif errclass == 0x03: 

300 return 'Hardware error', ERRHRD.get(errcode, 'Unknown error') 

301 # This is not a standard error class for SMB 

302 #elif errclass == 0x80: 

303 # return 'Browse error', ERRBROWSE.get(errcode, 'Unknown error') 

304 elif errclass == 0xff: 

305 return 'Bad command', 'Bad command. Please file bug report' 

306 else: 

307 return 'Unknown error', 'Unknown error' 

308 

309# Raised when an error has occurred during a session 

310class SessionError(Exception): 

311 # SMB X/Open error codes for the ERRDOS error class 

312 ERRsuccess = 0 

313 ERRbadfunc = 1 

314 ERRbadfile = 2 

315 ERRbadpath = 3 

316 ERRnofids = 4 

317 ERRnoaccess = 5 

318 ERRbadfid = 6 

319 ERRbadmcb = 7 

320 ERRnomem = 8 

321 ERRbadmem = 9 

322 ERRbadenv = 10 

323 ERRbadaccess = 12 

324 ERRbaddata = 13 

325 ERRres = 14 

326 ERRbaddrive = 15 

327 ERRremcd = 16 

328 ERRdiffdevice = 17 

329 ERRnofiles = 18 

330 ERRgeneral = 31 

331 ERRbadshare = 32 

332 ERRlock = 33 

333 ERRunsup = 50 

334 ERRnetnamedel = 64 

335 ERRnosuchshare = 67 

336 ERRfilexists = 80 

337 ERRinvalidparam = 87 

338 ERRcannotopen = 110 

339 ERRinsufficientbuffer = 122 

340 ERRinvalidname = 123 

341 ERRunknownlevel = 124 

342 ERRnotlocked = 158 

343 ERRrename = 183 

344 ERRbadpipe = 230 

345 ERRpipebusy = 231 

346 ERRpipeclosing = 232 

347 ERRnotconnected = 233 

348 ERRmoredata = 234 

349 ERRnomoreitems = 259 

350 ERRbaddirectory = 267 

351 ERReasnotsupported = 282 

352 ERRlogonfailure = 1326 

353 ERRbuftoosmall = 2123 

354 ERRunknownipc = 2142 

355 ERRnosuchprintjob = 2151 

356 ERRinvgroup = 2455 

357 

358 # here's a special one from observing NT 

359 ERRnoipc = 66 

360 

361 # These errors seem to be only returned by the NT printer driver system 

362 ERRdriveralreadyinstalled = 1795 

363 ERRunknownprinterport = 1796 

364 ERRunknownprinterdriver = 1797 

365 ERRunknownprintprocessor = 1798 

366 ERRinvalidseparatorfile = 1799 

367 ERRinvalidjobpriority = 1800 

368 ERRinvalidprintername = 1801 

369 ERRprinteralreadyexists = 1802 

370 ERRinvalidprintercommand = 1803 

371 ERRinvaliddatatype = 1804 

372 ERRinvalidenvironment = 1805 

373 

374 ERRunknownprintmonitor = 3000 

375 ERRprinterdriverinuse = 3001 

376 ERRspoolfilenotfound = 3002 

377 ERRnostartdoc = 3003 

378 ERRnoaddjob = 3004 

379 ERRprintprocessoralreadyinstalled = 3005 

380 ERRprintmonitoralreadyinstalled = 3006 

381 ERRinvalidprintmonitor = 3007 

382 ERRprintmonitorinuse = 3008 

383 ERRprinterhasjobsqueued = 3009 

384 

385 # Error codes for the ERRSRV class 

386 

387 ERRerror = 1 

388 ERRbadpw = 2 

389 ERRbadtype = 3 

390 ERRaccess = 4 

391 ERRinvnid = 5 

392 ERRinvnetname = 6 

393 ERRinvdevice = 7 

394 ERRqfull = 49 

395 ERRqtoobig = 50 

396 ERRinvpfid = 52 

397 ERRsmbcmd = 64 

398 ERRsrverror = 65 

399 ERRfilespecs = 67 

400 ERRbadlink = 68 

401 ERRbadpermits = 69 

402 ERRbadpid = 70 

403 ERRsetattrmode = 71 

404 ERRpaused = 81 

405 ERRmsgoff = 82 

406 ERRnoroom = 83 

407 ERRrmuns = 87 

408 ERRtimeout = 88 

409 ERRnoresource = 89 

410 ERRtoomanyuids = 90 

411 ERRbaduid = 91 

412 ERRuseMPX = 250 

413 ERRuseSTD = 251 

414 ERRcontMPX = 252 

415 ERRbadPW = None 

416 ERRnosupport = 0 

417 ERRunknownsmb = 22 

418 

419 # Error codes for the ERRHRD class 

420 

421 ERRnowrite = 19 

422 ERRbadunit = 20 

423 ERRnotready = 21 

424 ERRbadcmd = 22 

425 ERRdata = 23 

426 ERRbadreq = 24 

427 ERRseek = 25 

428 ERRbadmedia = 26 

429 ERRbadsector = 27 

430 ERRnopaper = 28 

431 ERRwrite = 29 

432 ERRread = 30 

433 ERRwrongdisk = 34 

434 ERRFCBunavail = 35 

435 ERRsharebufexc = 36 

436 ERRdiskfull = 39 

437 

438 

439 hard_msgs = { 

440 19: ("ERRnowrite", "Attempt to write on write-protected diskette."), 

441 20: ("ERRbadunit", "Unknown unit."), 

442 21: ("ERRnotready", "Drive not ready."), 

443 22: ("ERRbadcmd", "Unknown command."), 

444 23: ("ERRdata", "Data error (CRC)."), 

445 24: ("ERRbadreq", "Bad request structure length."), 

446 25: ("ERRseek", "Seek error."), 

447 26: ("ERRbadmedia", "Unknown media type."), 

448 27: ("ERRbadsector", "Sector not found."), 

449 28: ("ERRnopaper", "Printer out of paper."), 

450 29: ("ERRwrite", "Write fault."), 

451 30: ("ERRread", "Read fault."), 

452 31: ("ERRgeneral", "General failure."), 

453 32: ("ERRbadshare", "An open conflicts with an existing open."), 

454 33: ("ERRlock", "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."), 

455 34: ("ERRwrongdisk", "The wrong disk was found in a drive."), 

456 35: ("ERRFCBUnavail", "No FCBs are available to process request."), 

457 36: ("ERRsharebufexc", "A sharing buffer has been exceeded.") 

458 } 

459 

460 dos_msgs = { 

461 ERRbadfunc: ("ERRbadfunc", "Invalid function."), 

462 ERRbadfile: ("ERRbadfile", "File not found."), 

463 ERRbadpath: ("ERRbadpath", "Directory invalid."), 

464 ERRnofids: ("ERRnofids", "No file descriptors available"), 

465 ERRnoaccess: ("ERRnoaccess", "Access denied."), 

466 ERRbadfid: ("ERRbadfid", "Invalid file handle."), 

467 ERRbadmcb: ("ERRbadmcb", "Memory control blocks destroyed."), 

468 ERRnomem: ("ERRnomem", "Insufficient server memory to perform the requested function."), 

469 ERRbadmem: ("ERRbadmem", "Invalid memory block address."), 

470 ERRbadenv: ("ERRbadenv", "Invalid environment."), 

471 11: ("ERRbadformat", "Invalid format."), 

472 ERRbadaccess: ("ERRbadaccess", "Invalid open mode."), 

473 ERRbaddata: ("ERRbaddata", "Invalid data."), 

474 ERRres: ("ERRres", "reserved."), 

475 ERRbaddrive: ("ERRbaddrive", "Invalid drive specified."), 

476 ERRremcd: ("ERRremcd", "A Delete Directory request attempted to remove the server's current directory."), 

477 ERRdiffdevice: ("ERRdiffdevice", "Not same device."), 

478 ERRnofiles: ("ERRnofiles", "A File Search command can find no more files matching the specified criteria."), 

479 ERRbadshare: ("ERRbadshare", "The sharing mode specified for an Open conflicts with existing FIDs on the file."), 

480 ERRlock: ("ERRlock", "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."), 

481 ERRunsup: ("ERRunsup", "The operation is unsupported"), 

482 ERRnosuchshare: ("ERRnosuchshare", "You specified an invalid share name"), 

483 ERRfilexists: ("ERRfilexists", "The file named in a Create Directory, Make New File or Link request already exists."), 

484 ERRinvalidname: ("ERRinvalidname", "Invalid name"), 

485 ERRbadpipe: ("ERRbadpipe", "Pipe invalid."), 

486 ERRpipebusy: ("ERRpipebusy", "All instances of the requested pipe are busy."), 

487 ERRpipeclosing: ("ERRpipeclosing", "Pipe close in progress."), 

488 ERRnotconnected: ("ERRnotconnected", "No process on other end of pipe."), 

489 ERRmoredata: ("ERRmoredata", "There is more data to be returned."), 

490 ERRinvgroup: ("ERRinvgroup", "Invalid workgroup (try the -W option)"), 

491 ERRlogonfailure: ("ERRlogonfailure", "Logon failure"), 

492 ERRdiskfull: ("ERRdiskfull", "Disk full"), 

493 ERRgeneral: ("ERRgeneral", "General failure"), 

494 ERRunknownlevel: ("ERRunknownlevel", "Unknown info level") 

495 } 

496 

497 server_msgs = { 

498 1: ("ERRerror", "Non-specific error code."), 

499 2: ("ERRbadpw", "Bad password - name/password pair in a Tree Connect or Session Setup are invalid."), 

500 3: ("ERRbadtype", "reserved."), 

501 4: ("ERRaccess", "The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."), 

502 5: ("ERRinvnid", "The tree ID (TID) specified in a command was invalid."), 

503 6: ("ERRinvnetname", "Invalid network name in tree connect."), 

504 7: ("ERRinvdevice", "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."), 

505 49: ("ERRqfull", "Print queue full (files) -- returned by open print file."), 

506 50: ("ERRqtoobig", "Print queue full -- no space."), 

507 51: ("ERRqeof", "EOF on print queue dump."), 

508 52: ("ERRinvpfid", "Invalid print file FID."), 

509 64: ("ERRsmbcmd", "The server did not recognize the command received."), 

510 65: ("ERRsrverror","The server encountered an internal error, e.g., system file unavailable."), 

511 67: ("ERRfilespecs", "The file handle (FID) and pathname parameters contained an invalid combination of values."), 

512 68: ("ERRreserved", "reserved."), 

513 69: ("ERRbadpermits", "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."), 

514 70: ("ERRreserved", "reserved."), 

515 71: ("ERRsetattrmode", "The attribute mode in the Set File Attribute request is invalid."), 

516 81: ("ERRpaused", "Server is paused."), 

517 82: ("ERRmsgoff", "Not receiving messages."), 

518 83: ("ERRnoroom", "No room to buffer message."), 

519 87: ("ERRrmuns", "Too many remote user names."), 

520 88: ("ERRtimeout", "Operation timed out."), 

521 89: ("ERRnoresource", "No resources currently available for request."), 

522 90: ("ERRtoomanyuids", "Too many UIDs active on this session."), 

523 91: ("ERRbaduid", "The UID is not known as a valid ID on this session."), 

524 250: ("ERRusempx","Temp unable to support Raw, use MPX mode."), 

525 251: ("ERRusestd","Temp unable to support Raw, use standard read/write."), 

526 252: ("ERRcontmpx", "Continue in MPX mode."), 

527 253: ("ERRreserved", "reserved."), 

528 254: ("ERRreserved", "reserved."), 

529 0xFFFF: ("ERRnosupport", "Function not supported.") 

530 } 

531 # Error clases 

532 

533 ERRDOS = 0x1 

534 error_classes = { 0: ("SUCCESS", {}), 

535 ERRDOS: ("ERRDOS", dos_msgs), 

536 0x02: ("ERRSRV",server_msgs), 

537 0x03: ("ERRHRD",hard_msgs), 

538 0x04: ("ERRXOS", {} ), 

539 0xE1: ("ERRRMX1", {} ), 

540 0xE2: ("ERRRMX2", {} ), 

541 0xE3: ("ERRRMX3", {} ), 

542 0xFF: ("ERRCMD", {} ) } 

543 

544 

545 

546 def __init__( self, error_string, error_class, error_code, nt_status = 0, packet=0): 

547 Exception.__init__(self, error_string) 

548 self.nt_status = nt_status 

549 self._args = error_string 

550 if nt_status: 550 ↛ 554line 550 didn't jump to line 554, because the condition on line 550 was never false

551 self.error_class = 0 

552 self.error_code = (error_code << 16) + error_class 

553 else: 

554 self.error_class = error_class 

555 self.error_code = error_code 

556 self.packet = packet 

557 

558 def get_error_class( self ): 

559 return self.error_class 

560 

561 def get_error_code( self ): 

562 return self.error_code 

563 

564 def get_error_packet(self): 

565 return self.packet 

566 

567 def __str__( self ): 

568 error_class = SessionError.error_classes.get( self.error_class, None ) 

569 if not error_class: 

570 error_code_str = self.error_code 

571 error_class_str = self.error_class 

572 else: 

573 error_class_str = error_class[0] 

574 error_code = error_class[1].get( self.error_code, None ) 

575 if not error_code: 

576 error_code_str = self.error_code 

577 else: 

578 error_code_str = '%s(%s)' % error_code 

579 

580 if self.nt_status: 

581 return 'SMB SessionError: %s(%s)' % nt_errors.ERROR_MESSAGES[self.error_code] 

582 else: 

583 # Fall back to the old format 

584 return 'SMB SessionError: class: %s, code: %s' % (error_class_str, error_code_str) 

585 

586 

587# Raised when an supported feature is present/required in the protocol but is not 

588# currently supported by pysmb 

589class UnsupportedFeature(Exception): 

590 pass 

591 

592# Contains information about a SMB shared device/service 

593class SharedDevice: 

594 def __init__(self, name, share_type, comment): 

595 self.__name = name 

596 self.__type = share_type 

597 self.__comment = comment 

598 

599 def get_name(self): 

600 return self.__name 

601 

602 def get_type(self): 

603 return self.__type 

604 

605 def get_comment(self): 

606 return self.__comment 

607 

608 def __repr__(self): 

609 return '<SharedDevice instance: name=' + self.__name + ', type=' + str(self.__type) + ', comment="' + self.__comment + '">' 

610 

611 

612# Contains information about the shared file/directory 

613class SharedFile: 

614 def __init__(self, ctime, atime, mtime, filesize, allocsize, attribs, shortname, longname): 

615 self.__ctime = ctime 

616 self.__atime = atime 

617 self.__mtime = mtime 

618 self.__filesize = filesize 

619 self.__allocsize = allocsize 

620 self.__attribs = attribs 

621 try: 

622 if isinstance(shortname,bytes): 622 ↛ 623line 622 didn't jump to line 623, because the condition on line 622 was never true

623 self.__shortname = shortname[:shortname.index(b'\0')] 

624 else: 

625 self.__shortname = shortname[:shortname.index('\0')] 

626 except (ValueError, TypeError): 

627 self.__shortname = shortname 

628 try: 

629 if isinstance(shortname,bytes): 629 ↛ 630line 629 didn't jump to line 630, because the condition on line 629 was never true

630 self.__longname = longname[:longname.index(b'\0')] 

631 else: 

632 self.__longname = longname[:longname.index('\0')] 

633 except (ValueError, TypeError): 

634 self.__longname = longname 

635 

636 def get_ctime(self): 

637 return self.__ctime 

638 

639 def get_ctime_epoch(self): 

640 return self.__convert_smbtime(self.__ctime) 

641 

642 def get_mtime(self): 

643 return self.__mtime 

644 

645 def get_mtime_epoch(self): 

646 return self.__convert_smbtime(self.__mtime) 

647 

648 def get_atime(self): 

649 return self.__atime 

650 

651 def get_atime_epoch(self): 

652 return self.__convert_smbtime(self.__atime) 

653 

654 def get_filesize(self): 

655 return self.__filesize 

656 

657 def get_allocsize(self): 

658 return self.__allocsize 

659 

660 def get_attributes(self): 

661 return self.__attribs 

662 

663 def is_archive(self): 

664 return self.__attribs & ATTR_ARCHIVE 

665 

666 def is_compressed(self): 

667 return self.__attribs & ATTR_COMPRESSED 

668 

669 def is_normal(self): 

670 return self.__attribs & ATTR_NORMAL 

671 

672 def is_hidden(self): 

673 return self.__attribs & ATTR_HIDDEN 

674 

675 def is_readonly(self): 

676 return self.__attribs & ATTR_READONLY 

677 

678 def is_temporary(self): 

679 return self.__attribs & ATTR_TEMPORARY 

680 

681 def is_directory(self): 

682 return self.__attribs & ATTR_DIRECTORY 

683 

684 def is_system(self): 

685 return self.__attribs & ATTR_SYSTEM 

686 

687 def get_shortname(self): 

688 return self.__shortname 

689 

690 def get_longname(self): 

691 return self.__longname 

692 

693 def __repr__(self): 

694 return '<SharedFile instance: shortname="' + self.__shortname + '", longname="' + self.__longname + '", filesize=' + str(self.__filesize) + '>' 

695 

696 @staticmethod 

697 def __convert_smbtime(t): 

698 x = t >> 32 

699 y = t & 0xffffffff 

700 geo_cal_offset = 11644473600.0 # = 369.0 * 365.25 * 24 * 60 * 60 - (3.0 * 24 * 60 * 60 + 6.0 * 60 * 60) 

701 return (x * 4.0 * (1 << 30) + (y & 0xfff00000)) * 1.0e-7 - geo_cal_offset 

702 

703 

704# Contain information about a SMB machine 

705class SMBMachine: 

706 def __init__(self, nbname, nbt_type, comment): 

707 self.__nbname = nbname 

708 self.__type = nbt_type 

709 self.__comment = comment 

710 

711 def __repr__(self): 

712 return '<SMBMachine instance: nbname="' + self.__nbname + '", type=' + hex(self.__type) + ', comment="' + self.__comment + '">' 

713 

714class SMBDomain: 

715 def __init__(self, nbgroup, domain_type, master_browser): 

716 self.__nbgroup = nbgroup 

717 self.__type = domain_type 

718 self.__master_browser = master_browser 

719 

720 def __repr__(self): 

721 return '<SMBDomain instance: nbgroup="' + self.__nbgroup + '", type=' + hex(self.__type) + ', master browser="' + self.__master_browser + '">' 

722 

723# Represents a SMB Packet 

724class NewSMBPacket(Structure): 

725 structure = ( 

726 ('Signature', '"\xffSMB'), 

727 ('Command','B=0'), 

728 ('ErrorClass','B=0'), 

729 ('_reserved','B=0'), 

730 ('ErrorCode','<H=0'), 

731 ('Flags1','B=0'), 

732 ('Flags2','<H=0'), 

733 ('PIDHigh','<H=0'), 

734 ('SecurityFeatures','8s=""'), 

735 ('Reserved','<H=0'), 

736 ('Tid','<H=0xffff'), 

737 ('Pid','<H=0'), 

738 ('Uid','<H=0'), 

739 ('Mid','<H=0'), 

740 ('Data','*:'), 

741 ) 

742 

743 def __init__(self, **kargs): 

744 Structure.__init__(self, **kargs) 

745 

746 if ('Flags2' in self.fields) is False: 

747 self['Flags2'] = 0 

748 if ('Flags1' in self.fields) is False: 

749 self['Flags1'] = 0 

750 

751 if 'data' not in kargs: 

752 self['Data'] = [] 

753 

754 def addCommand(self, command): 

755 if len(self['Data']) == 0: 755 ↛ 758line 755 didn't jump to line 758, because the condition on line 755 was never false

756 self['Command'] = command.command 

757 else: 

758 self['Data'][-1]['Parameters']['AndXCommand'] = command.command 

759 self['Data'][-1]['Parameters']['AndXOffset'] = len(self) 

760 self['Data'].append(command) 

761 

762 def isMoreData(self): 

763 return (self['Command'] in [SMB.SMB_COM_TRANSACTION, SMB.SMB_COM_READ_ANDX, SMB.SMB_COM_READ_RAW] and 

764 self['ErrorClass'] == 1 and self['ErrorCode'] == SessionError.ERRmoredata) 

765 

766 def isMoreProcessingRequired(self): 

767 return self['ErrorClass'] == 0x16 and self['ErrorCode'] == 0xc000 

768 

769 def isValidAnswer(self, cmd): 

770 # this was inside a loop reading more from the net (with recv_packet(None)) 

771 if self['Command'] == cmd: 771 ↛ 780line 771 didn't jump to line 780, because the condition on line 771 was never false

772 if (self['ErrorClass'] == 0x00 and self['ErrorCode'] == 0x00): 

773 return 1 

774 elif self.isMoreData(): 774 ↛ 775line 774 didn't jump to line 775, because the condition on line 774 was never true

775 return 1 

776 elif self.isMoreProcessingRequired(): 

777 return 1 

778 raise SessionError("SMB Library Error", self['ErrorClass'] + (self['_reserved'] << 8), self['ErrorCode'], self['Flags2'] & SMB.FLAGS2_NT_STATUS, self) 

779 else: 

780 raise UnsupportedFeature("Unexpected answer from server: Got %d, Expected %d" % (self['Command'], cmd)) 

781 

782 

783class SMBCommand(Structure): 

784 structure = ( 

785 ('WordCount', 'B=len(Parameters)//2'), 

786 ('_ParametersLength','_-Parameters','WordCount*2'), 

787 ('Parameters',':'), # default set by constructor 

788 ('ByteCount','<H-Data'), 

789 ('Data',':'), # default set by constructor 

790 ) 

791 

792 def __init__(self, commandOrData = None, data = None, **kargs): 

793 if type(commandOrData) == type(0): 

794 self.command = commandOrData 

795 else: 

796 data = data or commandOrData 

797 

798 Structure.__init__(self, data = data, **kargs) 

799 

800 if data is None: 

801 self['Parameters'] = '' 

802 self['Data'] = '' 

803 

804class AsciiOrUnicodeStructure(Structure): 

805 UnicodeStructure = () 

806 AsciiStructure = () 

807 def __init__(self, flags = 0, **kargs): 

808 if flags & SMB.FLAGS2_UNICODE: 

809 self.structure = self.UnicodeStructure 

810 else: 

811 self.structure = self.AsciiStructure 

812 Structure.__init__(self, **kargs) 

813 

814class SMBCommand_Parameters(Structure): 

815 pass 

816 

817class SMBAndXCommand_Parameters(Structure): 

818 commonHdr = ( 

819 ('AndXCommand','B=0xff'), 

820 ('_reserved','B=0'), 

821 ('AndXOffset','<H=0'), 

822 ) 

823 structure = ( # default structure, overridden by subclasses 

824 ('Data',':=""'), 

825 ) 

826 

827############# TRANSACTIONS RELATED 

828# TRANS2_QUERY_FS_INFORMATION 

829# QUERY_FS Information Levels 

830# SMB_QUERY_FS_ATTRIBUTE_INFO 

831class SMBQueryFsAttributeInfo(Structure): 

832 structure = ( 

833 ('FileSystemAttributes','<L'), 

834 ('MaxFilenNameLengthInBytes','<L'), 

835 ('LengthOfFileSystemName','<L-FileSystemName'), 

836 ('FileSystemName',':'), 

837 ) 

838 

839class SMBQueryFsInfoVolume(AsciiOrUnicodeStructure): 

840 commonHdr = ( 

841 ('ulVolSerialNbr','<L=0xABCDEFAA'), 

842 ('cCharCount','<B-VolumeLabel'), 

843 ) 

844 AsciiStructure = ( 

845 ('VolumeLabel','z'), 

846 ) 

847 UnicodeStructure = ( 

848 ('VolumeLabel','u'), 

849 ) 

850 

851# FILE_FS_SIZE_INFORMATION 

852class FileFsSizeInformation(Structure): 

853 structure = ( 

854 ('TotalAllocationUnits','<q=148529400'), 

855 ('AvailableAllocationUnits','<q=14851044'), 

856 ('SectorsPerAllocationUnit','<L=2'), 

857 ('BytesPerSector','<L=512'), 

858 ) 

859 

860# SMB_QUERY_FS_SIZE_INFO 

861class SMBQueryFsSizeInfo(Structure): 

862 structure = ( 

863 ('TotalAllocationUnits','<q=148529400'), 

864 ('TotalFreeAllocationUnits','<q=14851044'), 

865 ('SectorsPerAllocationUnit','<L=2'), 

866 ('BytesPerSector','<L=512'), 

867 ) 

868# FILE_FS_FULL_SIZE_INFORMATION 

869class SMBFileFsFullSizeInformation(Structure): 

870 structure = ( 

871 ('TotalAllocationUnits','<q=148529400'), 

872 ('CallerAvailableAllocationUnits','<q=148529400'), 

873 ('ActualAvailableAllocationUnits','<q=148529400'), 

874 ('SectorsPerAllocationUnit','<L=15'), 

875 ('BytesPerSector','<L=512') 

876 ) 

877# SMB_QUERY_FS_VOLUME_INFO 

878class SMBQueryFsVolumeInfo(Structure): 

879 structure = ( 

880 ('VolumeCreationTime','<q'), 

881 ('SerialNumber','<L=0xABCDEFAA'), 

882 ('VolumeLabelSize','<L=len(VolumeLabel)'), 

883 ('Reserved','<H=0x10'), 

884 ('VolumeLabel',':') 

885 ) 

886 

887# SMB_QUERY_FS_DEVICE_INFO 

888class SMBQueryFsDeviceInfo(Structure): 

889 structure = ( 

890 ('DeviceType', '<L=0'), 

891 ('DeviceCharacteristics', '<L=0') 

892 ) 

893 

894 

895# SMB_FIND_FILE_BOTH_DIRECTORY_INFO level 

896class SMBFindFileBothDirectoryInfo(AsciiOrUnicodeStructure): 

897 commonHdr = ( 

898 ('NextEntryOffset','<L=0'), 

899 ('FileIndex','<L=0'), 

900 ('CreationTime','<q'), 

901 ('LastAccessTime','<q'), 

902 ('LastWriteTime','<q'), 

903 ('LastChangeTime','<q'), 

904 ('EndOfFile','<q=0'), 

905 ('AllocationSize','<q=0'), 

906 ('ExtFileAttributes','<L=0'), 

907 ) 

908 AsciiStructure = ( 

909 ('FileNameLength','<L-FileName','len(FileName)'), 

910 ('EaSize','<L=0'), 

911 ('ShortNameLength','<B=0'), 

912 ('Reserved','<B=0'), 

913 ('ShortName','24s'), 

914 ('FileName',':'), 

915 ) 

916 UnicodeStructure = ( 

917 ('FileNameLength','<L-FileName','len(FileName)*2'), 

918 ('EaSize','<L=0'), 

919 ('ShortNameLength','<B=0'), 

920 ('Reserved','<B=0'), 

921 ('ShortName','24s'), 

922 ('FileName',':'), 

923 ) 

924 

925# SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO level 

926class SMBFindFileIdFullDirectoryInfo(AsciiOrUnicodeStructure): 

927 commonHdr = ( 

928 ('NextEntryOffset','<L=0'), 

929 ('FileIndex','<L=0'), 

930 ('CreationTime','<q'), 

931 ('LastAccessTime','<q'), 

932 ('LastWriteTime','<q'), 

933 ('LastChangeTime','<q'), 

934 ('EndOfFile','<q=0'), 

935 ('AllocationSize','<q=0'), 

936 ('ExtFileAttributes','<L=0'), 

937 ) 

938 AsciiStructure = ( 

939 ('FileNameLength','<L-FileName','len(FileName)'), 

940 ('EaSize','<L=0'), 

941 ('Reserved', '<L=0'), 

942 ('FileID','<q=0'), 

943 ('FileName','z'), 

944 ) 

945 UnicodeStructure = ( 

946 ('FileNameLength','<L-FileName','len(FileName)*2'), 

947 ('EaSize','<L=0'), 

948 ('Reserved','<L=0'), 

949 ('FileID','<q=0'), 

950 ('FileName',':'), 

951 ) 

952 

953# SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO level 

954class SMBFindFileIdBothDirectoryInfo(AsciiOrUnicodeStructure): 

955 commonHdr = ( 

956 ('NextEntryOffset','<L=0'), 

957 ('FileIndex','<L=0'), 

958 ('CreationTime','<q'), 

959 ('LastAccessTime','<q'), 

960 ('LastWriteTime','<q'), 

961 ('LastChangeTime','<q'), 

962 ('EndOfFile','<q=0'), 

963 ('AllocationSize','<q=0'), 

964 ('ExtFileAttributes','<L=0'), 

965 ) 

966 AsciiStructure = ( 

967 ('FileNameLength','<L-FileName','len(FileName)'), 

968 ('EaSize','<L=0'), 

969 ('ShortNameLength','<B=0'), 

970 ('Reserved','<B=0'), 

971 ('ShortName','24s'), 

972 ('Reserved','<H=0'), 

973 ('FileID','<q=0'), 

974 ('FileName','z'), 

975 ) 

976 UnicodeStructure = ( 

977 ('FileNameLength','<L-FileName','len(FileName)*2'), 

978 ('EaSize','<L=0'), 

979 ('ShortNameLength','<B=0'), 

980 ('Reserved','<B=0'), 

981 ('ShortName','24s'), 

982 ('Reserved','<H=0'), 

983 ('FileID','<q=0'), 

984 ('FileName',':'), 

985 ) 

986 

987# SMB_FIND_FILE_DIRECTORY_INFO level 

988class SMBFindFileDirectoryInfo(AsciiOrUnicodeStructure): 

989 commonHdr = ( 

990 ('NextEntryOffset','<L=0'), 

991 ('FileIndex','<L=0'), 

992 ('CreationTime','<q'), 

993 ('LastAccessTime','<q'), 

994 ('LastWriteTime','<q'), 

995 ('LastChangeTime','<q'), 

996 ('EndOfFile','<q=0'), 

997 ('AllocationSize','<q=1'), 

998 ('ExtFileAttributes','<L=0'), 

999 ) 

1000 AsciiStructure = ( 

1001 ('FileNameLength','<L-FileName','len(FileName)'), 

1002 ('FileName','z'), 

1003 ) 

1004 UnicodeStructure = ( 

1005 ('FileNameLength','<L-FileName','len(FileName)*2'), 

1006 ('FileName',':'), 

1007 ) 

1008 

1009# SMB_FIND_FILE_NAMES_INFO level 

1010class SMBFindFileNamesInfo(AsciiOrUnicodeStructure): 

1011 commonHdr = ( 

1012 ('NextEntryOffset','<L=0'), 

1013 ('FileIndex','<L=0'), 

1014 ) 

1015 AsciiStructure = ( 

1016 ('FileNameLength','<L-FileName','len(FileName)'), 

1017 ('FileName','z'), 

1018 ) 

1019 UnicodeStructure = ( 

1020 ('FileNameLength','<L-FileName','len(FileName)*2'), 

1021 ('FileName',':'), 

1022 ) 

1023 

1024# SMB_FIND_FILE_FULL_DIRECTORY_INFO level 

1025class SMBFindFileFullDirectoryInfo(AsciiOrUnicodeStructure): 

1026 commonHdr = ( 

1027 ('NextEntryOffset','<L=0'), 

1028 ('FileIndex','<L=0'), 

1029 ('CreationTime','<q'), 

1030 ('LastAccessTime','<q'), 

1031 ('LastWriteTime','<q'), 

1032 ('LastChangeTime','<q'), 

1033 ('EndOfFile','<q=0'), 

1034 ('AllocationSize','<q=1'), 

1035 ('ExtFileAttributes','<L=0'), 

1036 ) 

1037 AsciiStructure = ( 

1038 ('FileNameLength','<L-FileName','len(FileName)'), 

1039 ('EaSize','<L'), 

1040 ('FileName','z'), 

1041 ) 

1042 UnicodeStructure = ( 

1043 ('FileNameLength','<L-FileName','len(FileName)*2'), 

1044 ('EaSize','<L'), 

1045 ('FileName',':'), 

1046 ) 

1047 

1048# SMB_FIND_INFO_STANDARD level 

1049class SMBFindInfoStandard(AsciiOrUnicodeStructure): 

1050 commonHdr = ( 

1051 ('ResumeKey','<L=0xff'), 

1052 ('CreationDate','<H=0'), 

1053 ('CreationTime','<H=0'), 

1054 ('LastAccessDate','<H=0'), 

1055 ('LastAccessTime','<H=0'), 

1056 ('LastWriteDate','<H=0'), 

1057 ('LastWriteTime','<H=0'), 

1058 ('EaSize','<L'), 

1059 ('AllocationSize','<L=1'), 

1060 ('ExtFileAttributes','<H=0'), 

1061 ) 

1062 AsciiStructure = ( 

1063 ('FileNameLength','<B-FileName','len(FileName)'), 

1064 ('FileName','z'), 

1065 ) 

1066 UnicodeStructure = ( 

1067 ('FileNameLength','<B-FileName','len(FileName)*2'), 

1068 ('FileName',':'), 

1069 ) 

1070 

1071# SET_FILE_INFORMATION structures 

1072# SMB_SET_FILE_DISPOSITION_INFO 

1073class SMBSetFileDispositionInfo(Structure): 

1074 structure = ( 

1075 ('DeletePending','<B'), 

1076 ) 

1077 

1078# SMB_SET_FILE_BASIC_INFO 

1079class SMBSetFileBasicInfo(Structure): 

1080 structure = ( 

1081 ('CreationTime','<q'), 

1082 ('LastAccessTime','<q'), 

1083 ('LastWriteTime','<q'), 

1084 ('ChangeTime','<q'), 

1085 ('ExtFileAttributes','<H'), 

1086 ('Reserved','<L'), 

1087 ) 

1088 

1089# FILE_STREAM_INFORMATION 

1090class SMBFileStreamInformation(Structure): 

1091 commonHdr = ( 

1092 ('NextEntryOffset','<L=0'), 

1093 ('StreamNameLength','<L=0'), 

1094 ('StreamSize','<q=0'), 

1095 ('StreamAllocationSize','<q=0'), 

1096 ('StreamName',':=""'), 

1097 ) 

1098 

1099# FILE_NETWORK_OPEN_INFORMATION 

1100class SMBFileNetworkOpenInfo(Structure): 

1101 structure = ( 

1102 ('CreationTime','<q=0'), 

1103 ('LastAccessTime','<q=0'), 

1104 ('LastWriteTime','<q=0'), 

1105 ('ChangeTime','<q=0'), 

1106 ('AllocationSize','<q=0'), 

1107 ('EndOfFile','<q=0'), 

1108 ('FileAttributes','<L=0'), 

1109 ('Reserved','<L=0'), 

1110 ) 

1111 

1112# SMB_SET_FILE_END_OF_FILE_INFO 

1113class SMBSetFileEndOfFileInfo(Structure): 

1114 structure = ( 

1115 ('EndOfFile','<q'), 

1116 ) 

1117 

1118# TRANS2_FIND_NEXT2 

1119class SMBFindNext2_Parameters(AsciiOrUnicodeStructure): 

1120 commonHdr = ( 

1121 ('SID','<H'), 

1122 ('SearchCount','<H'), 

1123 ('InformationLevel','<H'), 

1124 ('ResumeKey','<L'), 

1125 ('Flags','<H'), 

1126 ) 

1127 AsciiStructure = ( 

1128 ('FileName','z'), 

1129 ) 

1130 UnicodeStructure = ( 

1131 ('FileName','u'), 

1132 ) 

1133 

1134class SMBFindNext2Response_Parameters(Structure): 

1135 structure = ( 

1136 ('SearchCount','<H'), 

1137 ('EndOfSearch','<H=1'), 

1138 ('EaErrorOffset','<H=0'), 

1139 ('LastNameOffset','<H=0'), 

1140 ) 

1141 

1142class SMBFindNext2_Data(Structure): 

1143 structure = ( 

1144 ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'), 

1145 ('GetExtendedAttributesList',':'), 

1146 ) 

1147 

1148 

1149# TRANS2_FIND_FIRST2 

1150class SMBFindFirst2Response_Parameters(Structure): 

1151 structure = ( 

1152 ('SID','<H'), 

1153 ('SearchCount','<H'), 

1154 ('EndOfSearch','<H=1'), 

1155 ('EaErrorOffset','<H=0'), 

1156 ('LastNameOffset','<H=0'), 

1157 ) 

1158 

1159class SMBFindFirst2_Parameters(AsciiOrUnicodeStructure): 

1160 commonHdr = ( 

1161 ('SearchAttributes','<H'), 

1162 ('SearchCount','<H'), 

1163 ('Flags','<H'), 

1164 ('InformationLevel','<H'), 

1165 ('SearchStorageType','<L'), 

1166 ) 

1167 AsciiStructure = ( 

1168 ('FileName','z'), 

1169 ) 

1170 UnicodeStructure = ( 

1171 ('FileName','u'), 

1172 ) 

1173 

1174class SMBFindFirst2_Data(Structure): 

1175 structure = ( 

1176 ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'), 

1177 ('GetExtendedAttributesList',':'), 

1178 ) 

1179 

1180# TRANS2_SET_PATH_INFORMATION 

1181class SMBSetPathInformation_Parameters(AsciiOrUnicodeStructure): 

1182 commonHdr = ( 

1183 ('InformationLevel','<H'), 

1184 ('Reserved','<L'), 

1185 ) 

1186 AsciiStructure = ( 

1187 ('FileName','z'), 

1188 ) 

1189 UnicodeStructure = ( 

1190 ('FileName','u'), 

1191 ) 

1192 

1193class SMBSetPathInformationResponse_Parameters(Structure): 

1194 structure = ( 

1195 ('EaErrorOffset','<H=0'), 

1196 ) 

1197 

1198# TRANS2_SET_FILE_INFORMATION 

1199class SMBSetFileInformation_Parameters(Structure): 

1200 structure = ( 

1201 ('FID','<H'), 

1202 ('InformationLevel','<H'), 

1203 ('Reserved','<H'), 

1204 ) 

1205 

1206class SMBSetFileInformationResponse_Parameters(Structure): 

1207 structure = ( 

1208 ('EaErrorOffset','<H=0'), 

1209 ) 

1210 

1211# TRANS2_QUERY_FILE_INFORMATION 

1212class SMBQueryFileInformation_Parameters(Structure): 

1213 structure = ( 

1214 ('FID','<H'), 

1215 ('InformationLevel','<H'), 

1216 ) 

1217 

1218class SMBQueryFileInformationResponse_Parameters(Structure): 

1219 structure = ( 

1220 ('EaErrorOffset','<H=0'), 

1221 ) 

1222 

1223class SMBQueryFileInformation_Data(Structure): 

1224 structure = ( 

1225 ('GetExtendedAttributeList',':'), 

1226 ) 

1227 

1228# TRANS2_QUERY_PATH_INFORMATION 

1229class SMBQueryPathInformationResponse_Parameters(Structure): 

1230 structure = ( 

1231 ('EaErrorOffset','<H=0'), 

1232 ) 

1233 

1234class SMBQueryPathInformation_Parameters(AsciiOrUnicodeStructure): 

1235 commonHdr = ( 

1236 ('InformationLevel','<H'), 

1237 ('Reserved','<L=0'), 

1238 ) 

1239 AsciiStructure = ( 

1240 ('FileName','z'), 

1241 ) 

1242 UnicodeStructure = ( 

1243 ('FileName','u'), 

1244 ) 

1245 

1246class SMBQueryPathInformation_Data(Structure): 

1247 structure = ( 

1248 ('GetExtendedAttributeList',':'), 

1249 ) 

1250 

1251 

1252# SMB_QUERY_FILE_EA_INFO 

1253class SMBQueryFileEaInfo(Structure): 

1254 structure = ( 

1255 ('EaSize','<L=0'), 

1256 ) 

1257 

1258# SMB_QUERY_FILE_BASIC_INFO 

1259class SMBQueryFileBasicInfo(Structure): 

1260 structure = ( 

1261 ('CreationTime','<q'), 

1262 ('LastAccessTime','<q'), 

1263 ('LastWriteTime','<q'), 

1264 ('LastChangeTime','<q'), 

1265 ('ExtFileAttributes','<L'), 

1266 #('Reserved','<L=0'), 

1267 ) 

1268 

1269# SMB_QUERY_FILE_STANDARD_INFO 

1270class SMBQueryFileStandardInfo(Structure): 

1271 structure = ( 

1272 ('AllocationSize','<q'), 

1273 ('EndOfFile','<q'), 

1274 ('NumberOfLinks','<L=0'), 

1275 ('DeletePending','<B=0'), 

1276 ('Directory','<B'), 

1277 ) 

1278 

1279# SMB_QUERY_FILE_ALL_INFO 

1280class SMBQueryFileAllInfo(Structure): 

1281 structure = ( 

1282 ('CreationTime','<q'), 

1283 ('LastAccessTime','<q'), 

1284 ('LastWriteTime','<q'), 

1285 ('LastChangeTime','<q'), 

1286 ('ExtFileAttributes','<L'), 

1287 ('Reserved','<L=0'), 

1288 ('AllocationSize','<q'), 

1289 ('EndOfFile','<q'), 

1290 ('NumberOfLinks','<L=0'), 

1291 ('DeletePending','<B=0'), 

1292 ('Directory','<B'), 

1293 ('Reserved','<H=0'), 

1294 ('EaSize','<L=0'), 

1295 ('FileNameLength','<L-FileName','len(FileName)'), 

1296 ('FileName',':'), 

1297 ) 

1298 

1299# \PIPE\LANMAN NetShareEnum 

1300class SMBNetShareEnum(Structure): 

1301 structure = ( 

1302 ('RAPOpcode','<H=0'), 

1303 ('ParamDesc','z'), 

1304 ('DataDesc','z'), 

1305 ('InfoLevel','<H'), 

1306 ('ReceiveBufferSize','<H'), 

1307 ) 

1308 

1309class SMBNetShareEnumResponse(Structure): 

1310 structure = ( 

1311 ('Status','<H=0'), 

1312 ('Convert','<H=0'), 

1313 ('EntriesReturned','<H'), 

1314 ('EntriesAvailable','<H'), 

1315 ) 

1316 

1317class NetShareInfo1(Structure): 

1318 structure = ( 

1319 ('NetworkName','13s'), 

1320 ('Pad','<B=0'), 

1321 ('Type','<H=0'), 

1322 ('RemarkOffsetLow','<H=0'), 

1323 ('RemarkOffsetHigh','<H=0'), 

1324 ) 

1325 

1326# \PIPE\LANMAN NetServerGetInfo 

1327class SMBNetServerGetInfoResponse(Structure): 

1328 structure = ( 

1329 ('Status','<H=0'), 

1330 ('Convert','<H=0'), 

1331 ('TotalBytesAvailable','<H'), 

1332 ) 

1333 

1334class SMBNetServerInfo1(Structure): 

1335 # Level 1 Response 

1336 structure = ( 

1337 ('ServerName','16s'), 

1338 ('MajorVersion','B=5'), 

1339 ('MinorVersion','B=0'), 

1340 ('ServerType','<L=3'), 

1341 ('ServerCommentLow','<H=0'), 

1342 ('ServerCommentHigh','<H=0'), 

1343 ) 

1344 

1345# \PIPE\LANMAN NetShareGetInfo 

1346class SMBNetShareGetInfo(Structure): 

1347 structure = ( 

1348 ('RAPOpcode','<H=0'), 

1349 ('ParamDesc','z'), 

1350 ('DataDesc','z'), 

1351 ('ShareName','z'), 

1352 ('InfoLevel','<H'), 

1353 ('ReceiveBufferSize','<H'), 

1354 ) 

1355 

1356class SMBNetShareGetInfoResponse(Structure): 

1357 structure = ( 

1358 ('Status','<H=0'), 

1359 ('Convert','<H=0'), 

1360 ('TotalBytesAvailable','<H'), 

1361 ) 

1362 

1363############# Security Features 

1364class SecurityFeatures(Structure): 

1365 structure = ( 

1366 ('Key','<L=0'), 

1367 ('CID','<H=0'), 

1368 ('SequenceNumber','<H=0'), 

1369 ) 

1370 

1371############# SMB_COM_QUERY_INFORMATION2 (0x23) 

1372class SMBQueryInformation2_Parameters(Structure): 

1373 structure = ( 

1374 ('Fid','<H'), 

1375 ) 

1376 

1377class SMBQueryInformation2Response_Parameters(Structure): 

1378 structure = ( 

1379 ('CreateDate','<H'), 

1380 ('CreationTime','<H'), 

1381 ('LastAccessDate','<H'), 

1382 ('LastAccessTime','<H'), 

1383 ('LastWriteDate','<H'), 

1384 ('LastWriteTime','<H'), 

1385 ('FileDataSize','<L'), 

1386 ('FileAllocationSize','<L'), 

1387 ('FileAttributes','<L'), 

1388 ) 

1389 

1390 

1391 

1392############# SMB_COM_SESSION_SETUP_ANDX (0x73) 

1393class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters): 

1394 structure = ( 

1395 ('MaxBuffer','<H'), 

1396 ('MaxMpxCount','<H'), 

1397 ('VCNumber','<H'), 

1398 ('SessionKey','<L'), 

1399 ('AnsiPwdLength','<H'), 

1400 ('UnicodePwdLength','<H'), 

1401 ('_reserved','<L=0'), 

1402 ('Capabilities','<L'), 

1403 ) 

1404 

1405class SMBSessionSetupAndX_Extended_Parameters(SMBAndXCommand_Parameters): 

1406 structure = ( 

1407 ('MaxBufferSize','<H'), 

1408 ('MaxMpxCount','<H'), 

1409 ('VcNumber','<H'), 

1410 ('SessionKey','<L'), 

1411 ('SecurityBlobLength','<H'), 

1412 ('Reserved','<L=0'), 

1413 ('Capabilities','<L'), 

1414 ) 

1415 

1416class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure): 

1417 AsciiStructure = ( 

1418 ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'), 

1419 ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'), 

1420 ('AnsiPwd',':=""'), 

1421 ('UnicodePwd',':=""'), 

1422 ('Account','z=""'), 

1423 ('PrimaryDomain','z=""'), 

1424 ('NativeOS','z=""'), 

1425 ('NativeLanMan','z=""'), 

1426 ) 

1427 

1428 UnicodeStructure = ( 

1429 ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'), 

1430 ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'), 

1431 ('AnsiPwd',':=""'), 

1432 ('UnicodePwd',':=""'), 

1433 ('Account','u=""'), 

1434 ('PrimaryDomain','u=""'), 

1435 ('NativeOS','u=""'), 

1436 ('NativeLanMan','u=""'), 

1437 ) 

1438 

1439class SMBSessionSetupAndX_Extended_Data(AsciiOrUnicodeStructure): 

1440 AsciiStructure = ( 

1441 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1442 ('SecurityBlob',':'), 

1443 ('NativeOS','z=""'), 

1444 ('NativeLanMan','z=""'), 

1445 ) 

1446 

1447 UnicodeStructure = ( 

1448 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1449 ('SecurityBlob',':'), 

1450 ('NativeOS','u=""'), 

1451 ('NativeLanMan','u=""'), 

1452 ) 

1453 

1454class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1455 structure = ( 

1456 ('Action','<H'), 

1457 ) 

1458 

1459class SMBSessionSetupAndX_Extended_Response_Parameters(SMBAndXCommand_Parameters): 

1460 structure = ( 

1461 ('Action','<H=0'), 

1462 ('SecurityBlobLength','<H'), 

1463 ) 

1464 

1465class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure): 

1466 AsciiStructure = ( 

1467 ('NativeOS','z=""'), 

1468 ('NativeLanMan','z=""'), 

1469 ('PrimaryDomain','z=""'), 

1470 ) 

1471 

1472 UnicodeStructure = ( 

1473 ('NativeOS','u=""'), 

1474 ('NativeLanMan','u=""'), 

1475 ('PrimaryDomain','u=""'), 

1476 ) 

1477 

1478class SMBSessionSetupAndX_Extended_Response_Data(AsciiOrUnicodeStructure): 

1479 AsciiStructure = ( 

1480 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1481 ('SecurityBlob',':'), 

1482 ('NativeOS','z=""'), 

1483 ('NativeLanMan','z=""'), 

1484 ) 

1485 

1486 UnicodeStructure = ( 

1487 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 

1488 ('SecurityBlob',':'), 

1489 ('PadLen','_-Pad','1 if (len(self["SecurityBlob"]) % 2 == 0) else 0'), 

1490 ('Pad',':=""'), 

1491 ('NativeOS','u=""'), 

1492 ('NativeLanMan','u=""'), 

1493 ) 

1494 def getData(self): 

1495 if self.structure == self.UnicodeStructure: 

1496 if len(str(self['SecurityBlob'])) % 2 == 0: 

1497 self['Pad'] = '\x00' 

1498 return AsciiOrUnicodeStructure.getData(self) 

1499 

1500############# SMB_COM_TREE_CONNECT (0x70) 

1501class SMBTreeConnect_Parameters(SMBCommand_Parameters): 

1502 structure = ( 

1503 ) 

1504 

1505class SMBTreeConnect_Data(SMBCommand_Parameters): 

1506 structure = ( 

1507 ('PathFormat','"\x04'), 

1508 ('Path','z'), 

1509 ('PasswordFormat','"\x04'), 

1510 ('Password','z'), 

1511 ('ServiceFormat','"\x04'), 

1512 ('Service','z'), 

1513 ) 

1514 

1515############# SMB_COM_TREE_CONNECT_ANDX (0x75) 

1516class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters): 

1517 structure = ( 

1518 ('Flags','<H=0'), 

1519 ('PasswordLength','<H'), 

1520 ) 

1521 

1522class SMBTreeConnectAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1523 structure = ( 

1524 ('OptionalSupport','<H=0'), 

1525 ) 

1526 

1527class SMBTreeConnectAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 

1528 structure = ( 

1529 ('OptionalSupport','<H=1'), 

1530 ('MaximalShareAccessRights','<L=0x1fffff'), 

1531 ('GuestMaximalShareAccessRights','<L=0x1fffff'), 

1532 ) 

1533 

1534class SMBTreeConnectAndX_Data(AsciiOrUnicodeStructure): 

1535 AsciiStructure = ( 

1536 ('_PasswordLength','_-Password','self["_PasswordLength"]'), 

1537 ('Password',':'), 

1538 ('Path','z'), 

1539 ('Service','z'), 

1540 ) 

1541 

1542 UnicodeStructure = ( 

1543 ('_PasswordLength','_-Password','self["_PasswordLength"] if self["_PasswordLength"] > 0 else 1'), 

1544 ('Password',':'), 

1545 ('Path','u'), 

1546 ('Service','z'), 

1547 ) 

1548 

1549class SMBTreeConnectAndXResponse_Data(AsciiOrUnicodeStructure): 

1550 AsciiStructure = ( 

1551 ('Service','z'), 

1552 ('PadLen','_-Pad','self["PadLen"]'), 

1553 ('Pad',':=""'), 

1554 ('NativeFileSystem','z'), 

1555 ) 

1556 UnicodeStructure = ( 

1557 ('Service','z'), 

1558 ('PadLen','_-Pad','self["PadLen"]'), 

1559 ('Pad',':=""'), 

1560 ('NativeFileSystem','u'), 

1561 ) 

1562 

1563############# SMB_COM_NT_CREATE_ANDX (0xA2) 

1564class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters): 

1565 structure = ( 

1566 ('_reserved', 'B=0'), 

1567 ('FileNameLength','<H'), # NameLength 

1568 ('CreateFlags','<L'), # Flags 

1569 ('RootFid','<L=0'), # RootDirectoryFID 

1570 ('AccessMask','<L'), # DesiredAccess 

1571 ('AllocationSizeLo','<L=0'), # AllocationSize 

1572 ('AllocationSizeHi','<L=0'), 

1573 ('FileAttributes','<L=0'), # ExtFileAttributes 

1574 ('ShareAccess','<L=3'), # 

1575 ('Disposition','<L=1'), # CreateDisposition 

1576 ('CreateOptions','<L'), # CreateOptions 

1577 ('Impersonation','<L=2'), 

1578 ('SecurityFlags','B=3'), 

1579 ) 

1580 

1581class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1582 # XXX Is there a memory leak in the response for NTCreate (where the Data section would be) in Win 2000, Win XP, and Win 2003? 

1583 structure = ( 

1584 ('OplockLevel', 'B=0'), 

1585 ('Fid','<H'), 

1586 ('CreateAction','<L'), 

1587 ('CreateTime','<q=0'), 

1588 ('LastAccessTime','<q=0'), 

1589 ('LastWriteTime','<q=0'), 

1590 ('LastChangeTime','<q=0'), 

1591 ('FileAttributes','<L=0x80'), 

1592 ('AllocationSize','<q=0'), 

1593 ('EndOfFile','<q=0'), 

1594 ('FileType','<H=0'), 

1595 ('IPCState','<H=0'), 

1596 ('IsDirectory','B'), 

1597 ) 

1598 

1599class SMBNtCreateAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 

1600 # [MS-SMB] Extended response description 

1601 structure = ( 

1602 ('OplockLevel', 'B=0'), 

1603 ('Fid','<H'), 

1604 ('CreateAction','<L'), 

1605 ('CreateTime','<q=0'), 

1606 ('LastAccessTime','<q=0'), 

1607 ('LastWriteTime','<q=0'), 

1608 ('LastChangeTime','<q=0'), 

1609 ('FileAttributes','<L=0x80'), 

1610 ('AllocationSize','<q=0'), 

1611 ('EndOfFile','<q=0'), 

1612 ('FileType','<H=0'), 

1613 ('IPCState','<H=0'), 

1614 ('IsDirectory','B'), 

1615 ('VolumeGUID','16s'), 

1616 ('FileIdLow','<L=0'), 

1617 ('FileIdHigh','<L=0'), 

1618 ('MaximalAccessRights','<L=0x12019b'), 

1619 ('GuestMaximalAccessRights','<L=0x120089'), 

1620 ) 

1621 

1622class SMBNtCreateAndX_Data(AsciiOrUnicodeStructure): 

1623 AsciiStructure = ( 

1624 ('FileName','z'), 

1625 ) 

1626 UnicodeStructure = ( 

1627 ('Pad','B'), 

1628 ('FileName','u'), 

1629 ) 

1630 

1631############# SMB_COM_OPEN_ANDX (0xD2) 

1632class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters): 

1633 structure = ( 

1634 ('Flags','<H=0'), 

1635 ('DesiredAccess','<H=0'), 

1636 ('SearchAttributes','<H=0'), 

1637 ('FileAttributes','<H=0'), 

1638 ('CreationTime','<L=0'), 

1639 ('OpenMode','<H=1'), # SMB_O_OPEN = 1 

1640 ('AllocationSize','<L=0'), 

1641 ('Reserved','8s=""'), 

1642 ) 

1643 

1644class SMBOpenAndX_Data(SMBNtCreateAndX_Data): 

1645 pass 

1646 

1647class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1648 structure = ( 

1649 ('Fid','<H=0'), 

1650 ('FileAttributes','<H=0'), 

1651 ('LastWriten','<L=0'), 

1652 ('FileSize','<L=0'), 

1653 ('GrantedAccess','<H=0'), 

1654 ('FileType','<H=0'), 

1655 ('IPCState','<H=0'), 

1656 ('Action','<H=0'), 

1657 ('ServerFid','<L=0'), 

1658 ('_reserved','<H=0'), 

1659 ) 

1660 

1661############# SMB_COM_WRITE (0x0B) 

1662class SMBWrite_Parameters(SMBCommand_Parameters): 

1663 structure = ( 

1664 ('Fid','<H'), 

1665 ('Count','<H'), 

1666 ('Offset','<L'), 

1667 ('Remaining','<H'), 

1668 ) 

1669 

1670class SMBWriteResponse_Parameters(SMBCommand_Parameters): 

1671 structure = ( 

1672 ('Count','<H'), 

1673 ) 

1674 

1675class SMBWrite_Data(Structure): 

1676 structure = ( 

1677 ('BufferFormat','<B=1'), 

1678 ('DataLength','<H-Data'), 

1679 ('Data',':'), 

1680 ) 

1681 

1682 

1683############# SMB_COM_WRITE_ANDX (0x2F) 

1684class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters): 

1685 structure = ( 

1686 ('Fid','<H=0'), 

1687 ('Offset','<L=0'), 

1688 ('_reserved','<L=0xff'), 

1689 ('WriteMode','<H=8'), 

1690 ('Remaining','<H=0'), 

1691 ('DataLength_Hi','<H=0'), 

1692 ('DataLength','<H=0'), 

1693 ('DataOffset','<H=0'), 

1694 ('HighOffset','<L=0'), 

1695 ) 

1696 

1697class SMBWriteAndX_Data_Short(Structure): 

1698 structure = ( 

1699 ('_PadLen','_-Pad','self["DataOffset"] - 59'), 

1700 ('Pad',':'), 

1701 #('Pad','<B=0'), 

1702 ('DataLength','_-Data','self["DataLength"]'), 

1703 ('Data',':'), 

1704 ) 

1705 

1706class SMBWriteAndX_Data(Structure): 

1707 structure = ( 

1708 ('_PadLen','_-Pad','self["DataOffset"] - 63'), 

1709 ('Pad',':'), 

1710 #('Pad','<B=0'), 

1711 ('DataLength','_-Data','self["DataLength"]'), 

1712 ('Data',':'), 

1713 ) 

1714 

1715 

1716class SMBWriteAndX_Parameters_Short(SMBAndXCommand_Parameters): 

1717 structure = ( 

1718 ('Fid','<H'), 

1719 ('Offset','<L'), 

1720 ('_reserved','<L=0xff'), 

1721 ('WriteMode','<H=8'), 

1722 ('Remaining','<H'), 

1723 ('DataLength_Hi','<H=0'), 

1724 ('DataLength','<H'), 

1725 ('DataOffset','<H=0'), 

1726 ) 

1727 

1728class SMBWriteAndXResponse_Parameters(SMBAndXCommand_Parameters): 

1729 structure = ( 

1730 ('Count','<H'), 

1731 ('Available','<H'), 

1732 ('Reserved','<L=0'), 

1733 ) 

1734 

1735############# SMB_COM_WRITE_RAW (0x1D) 

1736class SMBWriteRaw_Parameters(SMBCommand_Parameters): 

1737 structure = ( 

1738 ('Fid','<H'), 

1739 ('Count','<H'), 

1740 ('_reserved','<H=0'), 

1741 ('Offset','<L'), 

1742 ('Timeout','<L=0'), 

1743 ('WriteMode','<H=0'), 

1744 ('_reserved2','<L=0'), 

1745 ('DataLength','<H'), 

1746 ('DataOffset','<H=0'), 

1747 ) 

1748 

1749############# SMB_COM_READ (0x0A) 

1750class SMBRead_Parameters(SMBCommand_Parameters): 

1751 structure = ( 

1752 ('Fid','<H'), 

1753 ('Count','<H'), 

1754 ('Offset','<L'), 

1755 ('Remaining','<H=Count'), 

1756 ) 

1757 

1758class SMBReadResponse_Parameters(Structure): 

1759 structure = ( 

1760 ('Count','<H=0'), 

1761 ('_reserved','8s=""'), 

1762 ) 

1763 

1764class SMBReadResponse_Data(Structure): 

1765 structure = ( 

1766 ('BufferFormat','<B=0x1'), 

1767 ('DataLength','<H-Data'), 

1768 ('Data',':'), 

1769 ) 

1770 

1771############# SMB_COM_READ_RAW (0x1A) 

1772class SMBReadRaw_Parameters(SMBCommand_Parameters): 

1773 structure = ( 

1774 ('Fid','<H'), 

1775 ('Offset','<L'), 

1776 ('MaxCount','<H'), 

1777 ('MinCount','<H=MaxCount'), 

1778 ('Timeout','<L=0'), 

1779 ('_reserved','<H=0'), 

1780 ) 

1781 

1782############# SMB_COM_NT_TRANSACT (0xA0) 

1783class SMBNTTransaction_Parameters(SMBCommand_Parameters): 

1784 structure = ( 

1785 ('MaxSetupCount','<B=0'), 

1786 ('Reserved1','<H=0'), 

1787 ('TotalParameterCount','<L'), 

1788 ('TotalDataCount','<L'), 

1789 ('MaxParameterCount','<L=1024'), 

1790 ('MaxDataCount','<L=65504'), 

1791 ('ParameterCount','<L'), 

1792 ('ParameterOffset','<L'), 

1793 ('DataCount','<L'), 

1794 ('DataOffset','<L'), 

1795 ('SetupCount','<B=len(Setup)//2'), 

1796 ('Function','<H=0'), 

1797 ('SetupLength','_-Setup','SetupCount*2'), 

1798 ('Setup',':'), 

1799 ) 

1800 

1801class SMBNTTransactionResponse_Parameters(SMBCommand_Parameters): 

1802 structure = ( 

1803 ('Reserved1','3s=""'), 

1804 ('TotalParameterCount','<L'), 

1805 ('TotalDataCount','<L'), 

1806 ('ParameterCount','<L'), 

1807 ('ParameterOffset','<L'), 

1808 ('ParameterDisplacement','<L=0'), 

1809 ('DataCount','<L'), 

1810 ('DataOffset','<L'), 

1811 ('DataDisplacement','<L=0'), 

1812 ('SetupCount','<B=0'), 

1813 ('SetupLength','_-Setup','SetupCount*2'), 

1814 ('Setup',':'), 

1815 ) 

1816 

1817class SMBNTTransaction_Data(Structure): 

1818 structure = ( 

1819 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1820 ('Pad1',':'), 

1821 ('NT_Trans_ParametersLength','_-NT_Trans_Parameters','self["NT_Trans_ParametersLength"]'), 

1822 ('NT_Trans_Parameters',':'), 

1823 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1824 ('Pad2',':'), 

1825 ('NT_Trans_DataLength','_-NT_Trans_Data','self["NT_Trans_DataLength"]'), 

1826 ('NT_Trans_Data',':'), 

1827 ) 

1828 

1829class SMBNTTransactionResponse_Data(Structure): 

1830 structure = ( 

1831 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1832 ('Pad1',':'), 

1833 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1834 ('Trans_Parameters',':'), 

1835 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1836 ('Pad2',':'), 

1837 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1838 ('Trans_Data',':'), 

1839 ) 

1840 

1841 

1842############# SMB_COM_TRANSACTION2_SECONDARY (0x33) 

1843class SMBTransaction2Secondary_Parameters(SMBCommand_Parameters): 

1844 structure = ( 

1845 ('TotalParameterCount','<H'), 

1846 ('TotalDataCount','<H'), 

1847 ('ParameterCount','<H'), 

1848 ('ParameterOffset','<H'), 

1849 ('ParameterDisplacement','<H'), 

1850 ('DataCount','<H'), 

1851 ('DataOffset','<H'), 

1852 ('DataDisplacement','<H=0'), 

1853 ('FID','<H'), 

1854 ) 

1855 

1856class SMBTransaction2Secondary_Data(Structure): 

1857 structure = ( 

1858 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1859 ('Pad1',':'), 

1860 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1861 ('Trans_Parameters',':'), 

1862 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1863 ('Pad2',':'), 

1864 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1865 ('Trans_Data',':'), 

1866 ) 

1867 

1868 

1869############# SMB_COM_TRANSACTION2 (0x32) 

1870 

1871class SMBTransaction2_Parameters(SMBCommand_Parameters): 

1872 structure = ( 

1873 ('TotalParameterCount','<H'), 

1874 ('TotalDataCount','<H'), 

1875 ('MaxParameterCount','<H=1024'), 

1876 ('MaxDataCount','<H=65504'), 

1877 ('MaxSetupCount','<B=0'), 

1878 ('Reserved1','<B=0'), 

1879 ('Flags','<H=0'), 

1880 ('Timeout','<L=0'), 

1881 ('Reserved2','<H=0'), 

1882 ('ParameterCount','<H'), 

1883 ('ParameterOffset','<H'), 

1884 ('DataCount','<H'), 

1885 ('DataOffset','<H'), 

1886 ('SetupCount','<B=len(Setup)//2'), 

1887 ('Reserved3','<B=0'), 

1888 ('SetupLength','_-Setup','SetupCount*2'), 

1889 ('Setup',':'), 

1890 ) 

1891 

1892class SMBTransaction2Response_Parameters(SMBCommand_Parameters): 

1893 structure = ( 

1894 ('TotalParameterCount','<H'), 

1895 ('TotalDataCount','<H'), 

1896 ('Reserved1','<H=0'), 

1897 ('ParameterCount','<H'), 

1898 ('ParameterOffset','<H'), 

1899 ('ParameterDisplacement','<H=0'), 

1900 ('DataCount','<H'), 

1901 ('DataOffset','<H'), 

1902 ('DataDisplacement','<H=0'), 

1903 ('SetupCount','<B=0'), 

1904 ('Reserved2','<B=0'), 

1905 ('SetupLength','_-Setup','SetupCount*2'), 

1906 ('Setup',':'), 

1907 ) 

1908 

1909class SMBTransaction2_Data(Structure): 

1910 structure = ( 

1911# ('NameLength','_-Name','1'), 

1912# ('Name',':'), 

1913 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1914 ('Pad1',':'), 

1915 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1916 ('Trans_Parameters',':'), 

1917 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1918 ('Pad2',':'), 

1919 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1920 ('Trans_Data',':'), 

1921 ) 

1922 

1923class SMBTransaction2Response_Data(Structure): 

1924 structure = ( 

1925 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 

1926 ('Pad1',':'), 

1927 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 

1928 ('Trans_Parameters',':'), 

1929 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 

1930 ('Pad2',':'), 

1931 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 

1932 ('Trans_Data',':'), 

1933 ) 

1934 

1935############# SMB_COM_QUERY_INFORMATION (0x08) 

1936 

1937class SMBQueryInformation_Data(AsciiOrUnicodeStructure): 

1938 AsciiStructure = ( 

1939 ('BufferFormat','B=4'), 

1940 ('FileName','z'), 

1941 ) 

1942 UnicodeStructure = ( 

1943 ('BufferFormat','B=4'), 

1944 ('FileName','u'), 

1945 ) 

1946 

1947 

1948class SMBQueryInformationResponse_Parameters(Structure): 

1949 structure = ( 

1950 ('FileAttributes','<H'), 

1951 ('LastWriteTime','<L'), 

1952 ('FileSize','<L'), 

1953 ('Reserved','"0123456789'), 

1954 ) 

1955 

1956############# SMB_COM_TRANSACTION (0x25) 

1957class SMBTransaction_Parameters(SMBCommand_Parameters): 

1958 structure = ( 

1959 ('TotalParameterCount','<H'), 

1960 ('TotalDataCount','<H'), 

1961 ('MaxParameterCount','<H=1024'), 

1962 ('MaxDataCount','<H=65504'), 

1963 ('MaxSetupCount','<B=0'), 

1964 ('Reserved1','<B=0'), 

1965 ('Flags','<H=0'), 

1966 ('Timeout','<L=0'), 

1967 ('Reserved2','<H=0'), 

1968 ('ParameterCount','<H'), 

1969 ('ParameterOffset','<H'), 

1970 ('DataCount','<H'), 

1971 ('DataOffset','<H'), 

1972 ('SetupCount','<B=len(Setup)//2'), 

1973 ('Reserved3','<B=0'), 

1974 ('SetupLength','_-Setup','SetupCount*2'), 

1975 ('Setup',':'), 

1976 ) 

1977 

1978class SMBTransactionResponse_Parameters(SMBCommand_Parameters): 

1979 structure = ( 

1980 ('TotalParameterCount','<H'), 

1981 ('TotalDataCount','<H'), 

1982 ('Reserved1','<H=0'), 

1983 ('ParameterCount','<H'), 

1984 ('ParameterOffset','<H'), 

1985 ('ParameterDisplacement','<H=0'), 

1986 ('DataCount','<H'), 

1987 ('DataOffset','<H'), 

1988 ('DataDisplacement','<H=0'), 

1989 ('SetupCount','<B'), 

1990 ('Reserved2','<B=0'), 

1991 ('SetupLength','_-Setup','SetupCount*2'), 

1992 ('Setup',':'), 

1993 ) 

1994 

1995# TODO: We should merge these both. But this will require fixing 

1996# the instances where this structure is used on the client side 

1997class SMBTransaction_SData(AsciiOrUnicodeStructure): 

1998 AsciiStructure = ( 

1999 ('Name','z'), 

2000 ('Trans_ParametersLength','_-Trans_Parameters'), 

2001 ('Trans_Parameters',':'), 

2002 ('Trans_DataLength','_-Trans_Data'), 

2003 ('Trans_Data',':'), 

2004 ) 

2005 UnicodeStructure = ( 

2006 ('Pad','B'), 

2007 ('Name','u'), 

2008 ('Trans_ParametersLength','_-Trans_Parameters'), 

2009 ('Trans_Parameters',':'), 

2010 ('Trans_DataLength','_-Trans_Data'), 

2011 ('Trans_Data',':'), 

2012 ) 

2013 

2014class SMBTransaction_Data(Structure): 

2015 structure = ( 

2016 ('NameLength','_-Name'), 

2017 ('Name',':'), 

2018 ('Trans_ParametersLength','_-Trans_Parameters'), 

2019 ('Trans_Parameters',':'), 

2020 ('Trans_DataLength','_-Trans_Data'), 

2021 ('Trans_Data',':'), 

2022 ) 

2023 

2024class SMBTransactionResponse_Data(Structure): 

2025 structure = ( 

2026 ('Trans_ParametersLength','_-Trans_Parameters'), 

2027 ('Trans_Parameters',':'), 

2028 ('Trans_DataLength','_-Trans_Data'), 

2029 ('Trans_Data',':'), 

2030 ) 

2031 

2032############# SMB_COM_READ_ANDX (0x2E) 

2033class SMBReadAndX_Parameters(SMBAndXCommand_Parameters): 

2034 structure = ( 

2035 ('Fid','<H'), 

2036 ('Offset','<L'), 

2037 ('MaxCount','<H'), 

2038 ('MinCount','<H=MaxCount'), 

2039 ('_reserved','<L=0x0'), 

2040 ('Remaining','<H=MaxCount'), 

2041 ('HighOffset','<L=0'), 

2042 ) 

2043 

2044class SMBReadAndX_Parameters2(SMBAndXCommand_Parameters): 

2045 structure = ( 

2046 ('Fid','<H'), 

2047 ('Offset','<L'), 

2048 ('MaxCount','<H'), 

2049 ('MinCount','<H=MaxCount'), 

2050 ('_reserved','<L=0xffffffff'), 

2051 ('Remaining','<H=MaxCount'), 

2052 ) 

2053 

2054class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters): 

2055 structure = ( 

2056 ('Remaining','<H=0'), 

2057 ('DataMode','<H=0'), 

2058 ('_reserved','<H=0'), 

2059 ('DataCount','<H'), 

2060 ('DataOffset','<H'), 

2061 ('DataCount_Hi','<L'), 

2062 ('_reserved2','6s=""'), 

2063 ) 

2064 

2065############# SMB_COM_ECHO (0x2B) 

2066class SMBEcho_Data(Structure): 

2067 structure = ( 

2068 ('Data',':'), 

2069 ) 

2070 

2071class SMBEcho_Parameters(Structure): 

2072 structure = ( 

2073 ('EchoCount','<H'), 

2074 ) 

2075 

2076class SMBEchoResponse_Data(Structure): 

2077 structure = ( 

2078 ('Data',':'), 

2079 ) 

2080 

2081class SMBEchoResponse_Parameters(Structure): 

2082 structure = ( 

2083 ('SequenceNumber','<H=1'), 

2084 ) 

2085 

2086############# SMB_COM_QUERY_INFORMATION_DISK (0x80) 

2087class SMBQueryInformationDiskResponse_Parameters(Structure): 

2088 structure = ( 

2089 ('TotalUnits','<H'), 

2090 ('BlocksPerUnit','<H'), 

2091 ('BlockSize','<H'), 

2092 ('FreeUnits','<H'), 

2093 ('Reserved','<H=0'), 

2094 ) 

2095 

2096 

2097############# SMB_COM_LOGOFF_ANDX (0x74) 

2098class SMBLogOffAndX(SMBAndXCommand_Parameters): 

2099 strucure = () 

2100 

2101############# SMB_COM_CLOSE (0x04) 

2102class SMBClose_Parameters(SMBCommand_Parameters): 

2103 structure = ( 

2104 ('FID','<H'), 

2105 ('Time','<L=0'), 

2106 ) 

2107 

2108############# SMB_COM_FLUSH (0x05) 

2109class SMBFlush_Parameters(SMBCommand_Parameters): 

2110 structure = ( 

2111 ('FID','<H'), 

2112 ) 

2113 

2114############# SMB_COM_CREATE_DIRECTORY (0x00) 

2115class SMBCreateDirectory_Data(AsciiOrUnicodeStructure): 

2116 AsciiStructure = ( 

2117 ('BufferFormat','<B=4'), 

2118 ('DirectoryName','z'), 

2119 ) 

2120 UnicodeStructure = ( 

2121 ('BufferFormat','<B=4'), 

2122 ('DirectoryName','u'), 

2123 ) 

2124 

2125############# SMB_COM_DELETE (0x06) 

2126class SMBDelete_Data(AsciiOrUnicodeStructure): 

2127 AsciiStructure = ( 

2128 ('BufferFormat','<B=4'), 

2129 ('FileName','z'), 

2130 ) 

2131 UnicodeStructure = ( 

2132 ('BufferFormat','<B=4'), 

2133 ('FileName','u'), 

2134 ) 

2135 

2136class SMBDelete_Parameters(Structure): 

2137 structure = ( 

2138 ('SearchAttributes','<H'), 

2139 ) 

2140 

2141############# SMB_COM_DELETE_DIRECTORY (0x01) 

2142class SMBDeleteDirectory_Data(AsciiOrUnicodeStructure): 

2143 AsciiStructure = ( 

2144 ('BufferFormat','<B=4'), 

2145 ('DirectoryName','z'), 

2146 ) 

2147 UnicodeStructure = ( 

2148 ('BufferFormat','<B=4'), 

2149 ('DirectoryName','u'), 

2150 ) 

2151 

2152############# SMB_COM_CHECK_DIRECTORY (0x10) 

2153class SMBCheckDirectory_Data(AsciiOrUnicodeStructure): 

2154 AsciiStructure = ( 

2155 ('BufferFormat','<B=4'), 

2156 ('DirectoryName','z'), 

2157 ) 

2158 UnicodeStructure = ( 

2159 ('BufferFormat','<B=4'), 

2160 ('DirectoryName','u'), 

2161 ) 

2162 

2163############# SMB_COM_RENAME (0x07) 

2164class SMBRename_Parameters(SMBCommand_Parameters): 

2165 structure = ( 

2166 ('SearchAttributes','<H'), 

2167 ) 

2168 

2169class SMBRename_Data(AsciiOrUnicodeStructure): 

2170 AsciiStructure = ( 

2171 ('BufferFormat1','<B=4'), 

2172 ('OldFileName','z'), 

2173 ('BufferFormat2','<B=4'), 

2174 ('NewFileName','z'), 

2175 ) 

2176 UnicodeStructure = ( 

2177 ('BufferFormat1','<B=4'), 

2178 ('OldFileName','u'), 

2179 ('BufferFormat2','<B=4'), 

2180 ('Pad','B=0'), 

2181 ('NewFileName','u'), 

2182 ) 

2183 

2184 

2185############# SMB_COM_OPEN (0x02) 

2186class SMBOpen_Parameters(SMBCommand_Parameters): 

2187 structure = ( 

2188 ('DesiredAccess','<H=0'), 

2189 ('SearchAttributes','<H=0'), 

2190 ) 

2191 

2192class SMBOpen_Data(AsciiOrUnicodeStructure): 

2193 AsciiStructure = ( 

2194 ('FileNameFormat','"\x04'), 

2195 ('FileName','z'), 

2196 ) 

2197 UnicodeStructure = ( 

2198 ('FileNameFormat','"\x04'), 

2199 ('FileName','u'), 

2200 ) 

2201 

2202class SMBOpenResponse_Parameters(SMBCommand_Parameters): 

2203 structure = ( 

2204 ('Fid','<H=0'), 

2205 ('FileAttributes','<H=0'), 

2206 ('LastWriten','<L=0'), 

2207 ('FileSize','<L=0'), 

2208 ('GrantedAccess','<H=0'), 

2209 ) 

2210 

2211############# EXTENDED SECURITY CLASSES 

2212class SMBExtended_Security_Parameters(Structure): 

2213 structure = ( 

2214 ('DialectIndex','<H'), 

2215 ('SecurityMode','<B'), 

2216 ('MaxMpxCount','<H'), 

2217 ('MaxNumberVcs','<H'), 

2218 ('MaxBufferSize','<L'), 

2219 ('MaxRawSize','<L'), 

2220 ('SessionKey','<L'), 

2221 ('Capabilities','<L'), 

2222 ('LowDateTime','<L'), 

2223 ('HighDateTime','<L'), 

2224 ('ServerTimeZone','<H'), 

2225 ('ChallengeLength','<B'), 

2226 ) 

2227 

2228class SMBExtended_Security_Data(Structure): 

2229 structure = ( 

2230 ('ServerGUID','16s'), 

2231 ('SecurityBlob',':'), 

2232 ) 

2233 

2234class SMBNTLMDialect_Parameters(Structure): 

2235 structure = ( 

2236 ('DialectIndex','<H'), 

2237 ('SecurityMode','<B'), 

2238 ('MaxMpxCount','<H'), 

2239 ('MaxNumberVcs','<H'), 

2240 ('MaxBufferSize','<L'), 

2241 ('MaxRawSize','<L'), 

2242 ('SessionKey','<L'), 

2243 ('Capabilities','<L'), 

2244 ('LowDateTime','<L'), 

2245 ('HighDateTime','<L'), 

2246 ('ServerTimeZone','<H'), 

2247 ('ChallengeLength','<B'), 

2248 ) 

2249 

2250class SMBNTLMDialect_Data(Structure): 

2251 structure = ( 

2252 ('ChallengeLength','_-Challenge','self["ChallengeLength"]'), 

2253 ('Challenge',':'), 

2254 ('Payload',':'), 

2255# For some reason on an old Linux this field is not present, we have to check this out. There must be a flag stating this. 

2256 ('DomainName','_'), 

2257 ('ServerName','_'), 

2258 ) 

2259 def __init__(self,data = None, alignment = 0): 

2260 Structure.__init__(self,data,alignment) 

2261 #self['ChallengeLength']=8 

2262 

2263 def fromString(self,data): 

2264 Structure.fromString(self,data) 

2265 self['DomainName'] = '' 

2266 self['ServerName'] = '' 

2267 

2268class SMB(object): 

2269 

2270 class HostnameValidationException(Exception): 

2271 pass 

2272 

2273 # SMB Command Codes 

2274 SMB_COM_CREATE_DIRECTORY = 0x00 

2275 SMB_COM_DELETE_DIRECTORY = 0x01 

2276 SMB_COM_OPEN = 0x02 

2277 SMB_COM_CREATE = 0x03 

2278 SMB_COM_CLOSE = 0x04 

2279 SMB_COM_FLUSH = 0x05 

2280 SMB_COM_DELETE = 0x06 

2281 SMB_COM_RENAME = 0x07 

2282 SMB_COM_QUERY_INFORMATION = 0x08 

2283 SMB_COM_SET_INFORMATION = 0x09 

2284 SMB_COM_READ = 0x0A 

2285 SMB_COM_WRITE = 0x0B 

2286 SMB_COM_LOCK_BYTE_RANGE = 0x0C 

2287 SMB_COM_UNLOCK_BYTE_RANGE = 0x0D 

2288 SMB_COM_CREATE_TEMPORARY = 0x0E 

2289 SMB_COM_CREATE_NEW = 0x0F 

2290 SMB_COM_CHECK_DIRECTORY = 0x10 

2291 SMB_COM_PROCESS_EXIT = 0x11 

2292 SMB_COM_SEEK = 0x12 

2293 SMB_COM_LOCK_AND_READ = 0x13 

2294 SMB_COM_WRITE_AND_UNLOCK = 0x14 

2295 SMB_COM_READ_RAW = 0x1A 

2296 SMB_COM_READ_MPX = 0x1B 

2297 SMB_COM_READ_MPX_SECONDARY = 0x1C 

2298 SMB_COM_WRITE_RAW = 0x1D 

2299 SMB_COM_WRITE_MPX = 0x1E 

2300 SMB_COM_WRITE_MPX_SECONDARY = 0x1F 

2301 SMB_COM_WRITE_COMPLETE = 0x20 

2302 SMB_COM_QUERY_SERVER = 0x21 

2303 SMB_COM_SET_INFORMATION2 = 0x22 

2304 SMB_COM_QUERY_INFORMATION2 = 0x23 

2305 SMB_COM_LOCKING_ANDX = 0x24 

2306 SMB_COM_TRANSACTION = 0x25 

2307 SMB_COM_TRANSACTION_SECONDARY = 0x26 

2308 SMB_COM_IOCTL = 0x27 

2309 SMB_COM_IOCTL_SECONDARY = 0x28 

2310 SMB_COM_COPY = 0x29 

2311 SMB_COM_MOVE = 0x2A 

2312 SMB_COM_ECHO = 0x2B 

2313 SMB_COM_WRITE_AND_CLOSE = 0x2C 

2314 SMB_COM_OPEN_ANDX = 0x2D 

2315 SMB_COM_READ_ANDX = 0x2E 

2316 SMB_COM_WRITE_ANDX = 0x2F 

2317 SMB_COM_NEW_FILE_SIZE = 0x30 

2318 SMB_COM_CLOSE_AND_TREE_DISC = 0x31 

2319 SMB_COM_TRANSACTION2 = 0x32 

2320 SMB_COM_TRANSACTION2_SECONDARY = 0x33 

2321 SMB_COM_FIND_CLOSE2 = 0x34 

2322 SMB_COM_FIND_NOTIFY_CLOSE = 0x35 

2323 # Used by Xenix/Unix 0x60 - 0x6E 

2324 SMB_COM_TREE_CONNECT = 0x70 

2325 SMB_COM_TREE_DISCONNECT = 0x71 

2326 SMB_COM_NEGOTIATE = 0x72 

2327 SMB_COM_SESSION_SETUP_ANDX = 0x73 

2328 SMB_COM_LOGOFF_ANDX = 0x74 

2329 SMB_COM_TREE_CONNECT_ANDX = 0x75 

2330 SMB_COM_QUERY_INFORMATION_DISK = 0x80 

2331 SMB_COM_SEARCH = 0x81 

2332 SMB_COM_FIND = 0x82 

2333 SMB_COM_FIND_UNIQUE = 0x83 

2334 SMB_COM_FIND_CLOSE = 0x84 

2335 SMB_COM_NT_TRANSACT = 0xA0 

2336 SMB_COM_NT_TRANSACT_SECONDARY = 0xA1 

2337 SMB_COM_NT_CREATE_ANDX = 0xA2 

2338 SMB_COM_NT_CANCEL = 0xA4 

2339 SMB_COM_NT_RENAME = 0xA5 

2340 SMB_COM_OPEN_PRINT_FILE = 0xC0 

2341 SMB_COM_WRITE_PRINT_FILE = 0xC1 

2342 SMB_COM_CLOSE_PRINT_FILE = 0xC2 

2343 SMB_COM_GET_PRINT_QUEUE = 0xC3 

2344 SMB_COM_READ_BULK = 0xD8 

2345 SMB_COM_WRITE_BULK = 0xD9 

2346 SMB_COM_WRITE_BULK_DATA = 0xDA 

2347 

2348 # TRANSACT codes 

2349 TRANS_TRANSACT_NMPIPE = 0x26 

2350 

2351 # TRANSACT2 codes 

2352 TRANS2_FIND_FIRST2 = 0x0001 

2353 TRANS2_FIND_NEXT2 = 0x0002 

2354 TRANS2_QUERY_FS_INFORMATION = 0x0003 

2355 TRANS2_QUERY_PATH_INFORMATION = 0x0005 

2356 TRANS2_QUERY_FILE_INFORMATION = 0x0007 

2357 TRANS2_SET_FILE_INFORMATION = 0x0008 

2358 TRANS2_SET_PATH_INFORMATION = 0x0006 

2359 

2360 # Security Share Mode (Used internally by SMB class) 

2361 SECURITY_SHARE_MASK = 0x01 

2362 SECURITY_SHARE_SHARE = 0x00 

2363 SECURITY_SHARE_USER = 0x01 

2364 SECURITY_SIGNATURES_ENABLED = 0X04 

2365 SECURITY_SIGNATURES_REQUIRED = 0X08 

2366 

2367 # Security Auth Mode (Used internally by SMB class) 

2368 SECURITY_AUTH_MASK = 0x02 

2369 SECURITY_AUTH_ENCRYPTED = 0x02 

2370 SECURITY_AUTH_PLAINTEXT = 0x00 

2371 

2372 # Raw Mode Mask (Used internally by SMB class. Good for dialect up to and including LANMAN2.1) 

2373 RAW_READ_MASK = 0x01 

2374 RAW_WRITE_MASK = 0x02 

2375 

2376 # Capabilities Mask (Used internally by SMB class. Good for dialect NT LM 0.12) 

2377 CAP_RAW_MODE = 0x00000001 

2378 CAP_MPX_MODE = 0x0002 

2379 CAP_UNICODE = 0x0004 

2380 CAP_LARGE_FILES = 0x0008 

2381 CAP_EXTENDED_SECURITY = 0x80000000 

2382 CAP_USE_NT_ERRORS = 0x40 

2383 CAP_NT_SMBS = 0x10 

2384 CAP_LARGE_READX = 0x00004000 

2385 CAP_LARGE_WRITEX = 0x00008000 

2386 CAP_RPC_REMOTE_APIS = 0x20 

2387 

2388 # Flags1 Mask 

2389 FLAGS1_LOCK_AND_READ_OK = 0x01 

2390 FLAGS1_PATHCASELESS = 0x08 

2391 FLAGS1_CANONICALIZED_PATHS = 0x10 

2392 FLAGS1_REPLY = 0x80 

2393 

2394 # Flags2 Mask 

2395 FLAGS2_LONG_NAMES = 0x0001 

2396 FLAGS2_EAS = 0x0002 

2397 FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004 

2398 FLAGS2_IS_LONG_NAME = 0x0040 

2399 FLAGS2_DFS = 0x1000 

2400 FLAGS2_PAGING_IO = 0x2000 

2401 FLAGS2_NT_STATUS = 0x4000 

2402 FLAGS2_UNICODE = 0x8000 

2403 FLAGS2_COMPRESSED = 0x0008 

2404 FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED = 0x0010 

2405 FLAGS2_EXTENDED_SECURITY = 0x0800 

2406 

2407 # Dialect's Security Mode flags 

2408 NEGOTIATE_USER_SECURITY = 0x01 

2409 NEGOTIATE_ENCRYPT_PASSWORDS = 0x02 

2410 NEGOTIATE_SECURITY_SIGNATURE_ENABLE = 0x04 

2411 NEGOTIATE_SECURITY_SIGNATURE_REQUIRED = 0x08 

2412 

2413 # Tree Connect AndX Response optionalSuppor flags 

2414 SMB_SUPPORT_SEARCH_BITS = 0x01 

2415 SMB_SHARE_IS_IN_DFS = 0x02 

2416 

2417 def __init__(self, remote_name, remote_host, my_name=None, host_type=nmb.TYPE_SERVER, sess_port=445, timeout=None, 

2418 UDP=0, session=None, negPacket=None): 

2419 # The uid attribute will be set when the client calls the login() method 

2420 self._uid = 0 

2421 self.__server_name = '' 

2422 self.__client_name = '' 

2423 self.__server_os = '' 

2424 self.__server_os_major = None 

2425 self.__server_os_minor = None 

2426 self.__server_os_build = None 

2427 self.__server_lanman = '' 

2428 self.__server_domain = '' 

2429 self.__server_dns_domain_name = '' 

2430 self.__server_dns_host_name = '' 

2431 self.__remote_name = remote_name.upper() 

2432 self.__remote_host = remote_host 

2433 self.__isNTLMv2 = True 

2434 self._dialects_parameters = None 

2435 self._dialects_data = None 

2436 self._doKerberos = False 

2437 

2438 # Credentials 

2439 self.__userName = b'' 

2440 self.__password = b'' 

2441 self.__domain = b'' 

2442 self.__lmhash = b'' 

2443 self.__nthash = b'' 

2444 self.__aesKey = b'' 

2445 self.__kdc = b'' 

2446 self.__TGT = None 

2447 self.__TGS = None 

2448 

2449 # Negotiate Protocol Result, used everywhere 

2450 # Could be extended or not, flags should be checked before 

2451 self._dialect_data = 0 

2452 self._dialect_parameters = 0 

2453 self._action = 0 

2454 self._sess = None 

2455 self.encrypt_passwords = True 

2456 self.tid = 0 

2457 self.fid = 0 

2458 

2459 # Strict host validation - off by default 

2460 self._strict_hostname_validation = False 

2461 self._validation_allow_absent = True 

2462 self._accepted_hostname = '' 

2463 

2464 # Signing stuff 

2465 self._SignSequenceNumber = 0 

2466 self._SigningSessionKey = b'' 

2467 self._SigningChallengeResponse = b'' 

2468 self._SignatureEnabled = False 

2469 self._SignatureVerificationEnabled = False 

2470 self._SignatureRequired = False 

2471 

2472 # Base flags (default flags, can be overridden using set_flags()) 

2473 self.__flags1 = SMB.FLAGS1_PATHCASELESS | SMB.FLAGS1_CANONICALIZED_PATHS 

2474 self.__flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES 

2475 

2476 if timeout is None: 2476 ↛ 2477line 2476 didn't jump to line 2477, because the condition on line 2476 was never true

2477 self.__timeout = 60 

2478 else: 

2479 self.__timeout = timeout 

2480 

2481 # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP. 

2482 # This is to help some old applications still believing 

2483 # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better 

2484 # know about *SMBSERVER's limitations 

2485 if sess_port == 445 and remote_name == '*SMBSERVER': 2485 ↛ 2486line 2485 didn't jump to line 2486, because the condition on line 2485 was never true

2486 self.__remote_name = remote_host 

2487 

2488 # This is on purpose. I'm still not convinced to do a socket.gethostname() if not specified 

2489 if my_name is None: 2489 ↛ 2492line 2489 didn't jump to line 2492, because the condition on line 2489 was never false

2490 self.__client_name = b'' 

2491 else: 

2492 self.__client_name = my_name 

2493 

2494 if session is None: 2494 ↛ 2516line 2494 didn't jump to line 2516, because the condition on line 2494 was never false

2495 if not my_name: 2495 ↛ 2502line 2495 didn't jump to line 2502, because the condition on line 2495 was never false

2496 # If destination port is 139 yes, there's some client disclosure 

2497 my_name = socket.gethostname() 

2498 i = my_name.find('.') 

2499 if i > -1: 2499 ↛ 2500line 2499 didn't jump to line 2500, because the condition on line 2499 was never true

2500 my_name = my_name[:i] 

2501 

2502 if UDP: 2502 ↛ 2503line 2502 didn't jump to line 2503, because the condition on line 2502 was never true

2503 self._sess = nmb.NetBIOSUDPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 

2504 else: 

2505 self._sess = nmb.NetBIOSTCPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 

2506 

2507 # Initialize session values (_dialect_data and _dialect_parameters) 

2508 self.neg_session() 

2509 

2510 # Call login() without any authentication information to 

2511 # setup a session if the remote server 

2512 # is in share mode. 

2513 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 2513 ↛ 2514line 2513 didn't jump to line 2514, because the condition on line 2513 was never true

2514 self.login('', '') 

2515 else: 

2516 self._sess = session 

2517 self.neg_session(negPacket = negPacket) 

2518 # Call login() without any authentication information to 

2519 # setup a session if the remote server 

2520 # is in share mode. 

2521 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 

2522 self.login('', '') 

2523 

2524 @staticmethod 

2525 def ntlm_supported(): 

2526 return False 

2527 

2528 def getKerberos(self): 

2529 return self._doKerberos 

2530 

2531 def get_remote_name(self): 

2532 return self.__remote_name 

2533 

2534 def set_remote_name(self, name): 

2535 self.__remote_name = name 

2536 return True 

2537 

2538 def set_hostname_validation(self, validate, accept_empty, hostname): 

2539 self._strict_hostname_validation = validate 

2540 self._validation_allow_absent = accept_empty 

2541 self._accepted_hostname = hostname 

2542 

2543 def get_remote_host(self): 

2544 return self.__remote_host 

2545 

2546 def get_flags(self): 

2547 return self.__flags1, self.__flags2 

2548 

2549 def set_flags(self, flags1=None, flags2=None): 

2550 if flags1 is not None: 

2551 self.__flags1 = flags1 

2552 if flags2 is not None: 2552 ↛ exitline 2552 didn't return from function 'set_flags', because the condition on line 2552 was never false

2553 self.__flags2 = flags2 

2554 

2555 def set_timeout(self, timeout): 

2556 prev_timeout = self.__timeout 

2557 self.__timeout = timeout 

2558 return prev_timeout 

2559 

2560 def get_timeout(self): 

2561 return self.__timeout 

2562 

2563 @contextmanager 

2564 def use_timeout(self, timeout): 

2565 prev_timeout = self.set_timeout(timeout) 

2566 try: 

2567 yield 

2568 finally: 

2569 self.set_timeout(prev_timeout) 

2570 

2571 def get_session(self): 

2572 return self._sess 

2573 

2574 def get_tid(self): 

2575 return self.tid 

2576 

2577 def get_fid(self): 

2578 return self.fid 

2579 

2580 def isGuestSession(self): 

2581 return self._action & SMB_SETUP_GUEST 

2582 

2583 def doesSupportNTLMv2(self): 

2584 return self.__isNTLMv2 

2585 

2586 def close_session(self): 

2587 if self._sess: 2587 ↛ exitline 2587 didn't return from function 'close_session', because the condition on line 2587 was never false

2588 self._sess.close() 

2589 self._sess = None 

2590 

2591 def recvSMB(self): 

2592 r = self._sess.recv_packet(self.__timeout) 

2593 return NewSMBPacket(data = r.get_trailer()) 

2594 

2595 @staticmethod 

2596 def __decode_trans(params, data): 

2597 totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, dataoffset, datads, setupcnt = unpack('<HHHHHHHHHB', params[:19]) 

2598 if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt: 

2599 has_more = 1 

2600 else: 

2601 has_more = 0 

2602 paramoffset = paramoffset - 55 - setupcnt * 2 

2603 dataoffset = dataoffset - 55 - setupcnt * 2 

2604 return has_more, params[20:20 + setupcnt * 2], data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt] 

2605 

2606 # TODO: Move this to NewSMBPacket, it belongs there 

2607 def signSMB(self, packet, signingSessionKey, signingChallengeResponse): 

2608 # This logic MUST be applied for messages sent in response to any of the higher-layer actions and in 

2609 # compliance with the message sequencing rules. 

2610 # * The client or server that sends the message MUST provide the 32-bit sequence number for this 

2611 # message, as specified in sections 3.2.4.1 and 3.3.4.1. 

2612 # * The SMB_FLAGS2_SMB_SECURITY_SIGNATURE flag in the header MUST be set. 

2613 # * To generate the signature, a 32-bit sequence number is copied into the 

2614 # least significant 32 bits of the SecuritySignature field and the remaining 

2615 # 4 bytes are set to 0x00. 

2616 # * The MD5 algorithm, as specified in [RFC1321], MUST be used to generate a hash of the SMB 

2617 # message from the start of the SMB Header, which is defined as follows. 

2618 # CALL MD5Init( md5context ) 

2619 # CALL MD5Update( md5context, Connection.SigningSessionKey ) 

2620 # CALL MD5Update( md5context, Connection.SigningChallengeResponse ) 

2621 # CALL MD5Update( md5context, SMB message ) 

2622 # CALL MD5Final( digest, md5context ) 

2623 # SET signature TO the first 8 bytes of the digest 

2624 # The resulting 8-byte signature MUST be copied into the SecuritySignature field of the SMB Header, 

2625 # after which the message can be transmitted. 

2626 

2627 #print "seq(%d) signingSessionKey %r, signingChallengeResponse %r" % (self._SignSequenceNumber, signingSessionKey, signingChallengeResponse) 

2628 packet['SecurityFeatures'] = pack('<q',self._SignSequenceNumber) 

2629 # Sign with the sequence 

2630 m = hashlib.md5() 

2631 m.update( signingSessionKey ) 

2632 m.update( signingChallengeResponse ) 

2633 m.update( packet.getData() ) 

2634 # Replace sequence with acual hash 

2635 packet['SecurityFeatures'] = m.digest()[:8] 

2636 if self._SignatureVerificationEnabled: 2636 ↛ 2637line 2636 didn't jump to line 2637, because the condition on line 2636 was never true

2637 self._SignSequenceNumber +=1 

2638 else: 

2639 self._SignSequenceNumber +=2 

2640 

2641 def checkSignSMB(self, packet, signingSessionKey, signingChallengeResponse): 

2642 # Let's check 

2643 signature = packet['SecurityFeatures'] 

2644 #print "Signature received: %r " % signature 

2645 self.signSMB(packet, signingSessionKey, signingChallengeResponse) 

2646 #print "Signature calculated: %r" % packet['SecurityFeatures'] 

2647 if self._SignatureVerificationEnabled is not True: 

2648 self._SignSequenceNumber -= 1 

2649 return packet['SecurityFeatures'] == signature 

2650 

2651 def sendSMB(self,smb): 

2652 smb['Uid'] = self._uid 

2653 #At least on AIX, PIDs can exceed 16 bits, so we mask them out 

2654 smb['Pid'] = (os.getpid() & 0xFFFF) 

2655 # set flags 

2656 smb['Flags1'] |= self.__flags1 

2657 smb['Flags2'] |= self.__flags2 

2658 if self._SignatureEnabled: 

2659 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

2660 self.signSMB(smb, self._SigningSessionKey, self._SigningChallengeResponse) 

2661 

2662 self._sess.send_packet(smb.getData()) 

2663 

2664 @staticmethod 

2665 def isValidAnswer(s, cmd): 

2666 while 1: 

2667 if s.rawData(): 

2668 if s.get_command() == cmd: 

2669 if s.get_error_class() == 0x00 and s.get_error_code() == 0x00: 

2670 return 1 

2671 else: 

2672 raise SessionError( "SMB Library Error", s.get_error_class()+ (s.get_reserved() << 8), s.get_error_code() , s.get_flags2() & SMB.FLAGS2_NT_STATUS) 

2673 else: 

2674 break 

2675 return 0 

2676 

2677 def neg_session(self, extended_security = True, negPacket = None): 

2678 def parsePacket(smb): 

2679 # If server speaks Unicode, let's set that flag from now on 

2680 if smb['Flags2'] & SMB.FLAGS2_UNICODE: 2680 ↛ 2681line 2680 didn't jump to line 2681, because the condition on line 2680 was never true

2681 self.__flags2 |= SMB.FLAGS2_UNICODE 

2682 

2683 if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE): 2683 ↛ 2712line 2683 didn't jump to line 2712, because the condition on line 2683 was never false

2684 sessionResponse = SMBCommand(smb['Data'][0]) 

2685 self._dialects_parameters = SMBNTLMDialect_Parameters(sessionResponse['Parameters']) 

2686 self._dialects_data = SMBNTLMDialect_Data() 

2687 self._dialects_data['ChallengeLength'] = self._dialects_parameters['ChallengeLength'] 

2688 self._dialects_data.fromString(sessionResponse['Data']) 

2689 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 2689 ↛ 2705line 2689 didn't jump to line 2705, because the condition on line 2689 was never false

2690 # Whether we choose it or it is enforced by the server, we go for extended security 

2691 self._dialects_parameters = SMBExtended_Security_Parameters(sessionResponse['Parameters']) 

2692 self._dialects_data = SMBExtended_Security_Data(sessionResponse['Data']) 

2693 # Let's setup some variable for later use 

2694 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 2694 ↛ 2701line 2694 didn't jump to line 2701, because the condition on line 2694 was never false

2695 self._SignatureRequired = True 

2696 

2697 # Interestingly, the security Blob might be missing sometimes. 

2698 #spnego = SPNEGO_NegTokenInit(self._dialects_data['SecurityBlob']) 

2699 #for i in spnego['MechTypes']: 

2700 # print "Mech Found: %s" % MechTypes[i] 

2701 return 1 

2702 

2703 # If not, let's try the old way 

2704 else: 

2705 if self._dialects_data['ServerName'] is not None: 

2706 self.__server_name = self._dialects_data['ServerName'] 

2707 

2708 if self._dialects_parameters['DialectIndex'] == 0xffff: 

2709 raise UnsupportedFeature("Remote server does not know NT LM 0.12") 

2710 return 1 

2711 else: 

2712 return 0 

2713 

2714 if negPacket is None: 2714 ↛ 2732line 2714 didn't jump to line 2732, because the condition on line 2714 was never false

2715 smb = NewSMBPacket() 

2716 negSession = SMBCommand(SMB.SMB_COM_NEGOTIATE) 

2717 flags2 = self.get_flags()[1] 

2718 if extended_security is True: 2718 ↛ 2721line 2718 didn't jump to line 2721, because the condition on line 2718 was never false

2719 self.set_flags(flags2=flags2|SMB.FLAGS2_EXTENDED_SECURITY) 

2720 else: 

2721 self.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY)) 

2722 

2723 negSession['Data'] = b'\x02NT LM 0.12\x00' 

2724 smb.addCommand(negSession) 

2725 self.sendSMB(smb) 

2726 

2727 while 1: 

2728 smb = self.recvSMB() 

2729 return parsePacket(smb) 

2730 else: 

2731 

2732 return parsePacket( NewSMBPacket( data = negPacket)) 

2733 

2734 def tree_connect(self, path, password = '', service = SERVICE_ANY): 

2735 LOG.warning("[MS-CIFS] This is an original Core Protocol command.This command has been deprecated.Client Implementations SHOULD use SMB_COM_TREE_CONNECT_ANDX") 

2736 

2737 # return 0x800 

2738 if password: 

2739 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 

2740 if self._dialects_parameters['ChallengeLength'] > 0: 

2741 # this code is untested 

2742 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 

2743 

2744 if not unicode_support: 

2745 if unicode_convert: 

2746 path = str(path) 

2747 else: 

2748 raise Exception('SMB: Can\t conver path from unicode!') 

2749 

2750 smb = NewSMBPacket() 

2751 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT) 

2752 treeConnect['Parameters'] = SMBTreeConnect_Parameters() 

2753 treeConnect['Data'] = SMBTreeConnect_Data() 

2754 treeConnect['Data']['Path'] = path.upper() 

2755 treeConnect['Data']['Password'] = password 

2756 treeConnect['Data']['Service'] = service 

2757 smb.addCommand(treeConnect) 

2758 self.sendSMB(smb) 

2759 

2760 while 1: 

2761 smb = self.recvSMB() 

2762 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT): 

2763 # XXX Here we are ignoring the rest of the response 

2764 return smb['Tid'] 

2765 return smb['Tid'] 

2766 

2767 def get_uid(self): 

2768 return self._uid 

2769 

2770 def set_uid(self, uid): 

2771 self._uid = uid 

2772 

2773 def tree_connect_andx(self, path, password = None, service = SERVICE_ANY, smb_packet=None): 

2774 if password: 2774 ↛ 2776line 2774 didn't jump to line 2776, because the condition on line 2774 was never true

2775 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 

2776 if self._dialects_parameters['ChallengeLength'] > 0: 

2777 # this code is untested 

2778 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 

2779 else: 

2780 password = '\x00' 

2781 

2782 if not unicode_support: 2782 ↛ 2788line 2782 didn't jump to line 2788, because the condition on line 2782 was never false

2783 if unicode_convert: 2783 ↛ 2786line 2783 didn't jump to line 2786, because the condition on line 2783 was never false

2784 path = str(path) 

2785 else: 

2786 raise Exception('SMB: Can\t convert path from unicode!') 

2787 

2788 if smb_packet is None: 2788 ↛ 2791line 2788 didn't jump to line 2791, because the condition on line 2788 was never false

2789 smb = NewSMBPacket() 

2790 else: 

2791 smb = smb_packet 

2792 

2793 # Just in case this came with the full path ,let's just leave 

2794 # the sharename, we'll take care of the rest 

2795 

2796 share = path.split('\\')[-1] 

2797 try: 

2798 _, _, _, _, sockaddr = socket.getaddrinfo(self.get_remote_host(), 80, 0, 0, socket.IPPROTO_TCP)[0] 

2799 remote_host = sockaddr[0] 

2800 except Exception: 

2801 remote_host = self.get_remote_host() 

2802 

2803 path = '\\\\' + remote_host + '\\' +share 

2804 path = path.upper().encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

2805 

2806 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX) 

2807 treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters() 

2808 treeConnect['Data'] = SMBTreeConnectAndX_Data(flags=self.__flags2) 

2809 treeConnect['Parameters']['PasswordLength'] = len(password) 

2810 treeConnect['Data']['Password'] = password 

2811 treeConnect['Data']['Path'] = path 

2812 treeConnect['Data']['Service'] = service 

2813 

2814 if self.__flags2 & SMB.FLAGS2_UNICODE: 

2815 treeConnect['Data']['Pad'] = 0x0 

2816 

2817 smb.addCommand(treeConnect) 

2818 

2819 # filename = "\PIPE\epmapper" 

2820 

2821 # ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 

2822 # ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 

2823 # ntCreate['Data'] = SMBNtCreateAndX_Data() 

2824 # ntCreate['Parameters']['FileNameLength'] = len(filename) 

2825 # ntCreate['Parameters']['CreateFlags'] = 0 

2826 # ntCreate['Parameters']['AccessMask'] = 0x3 

2827 # ntCreate['Parameters']['CreateOptions'] = 0x0 

2828 # ntCreate['Data']['FileName'] = filename 

2829 

2830 # smb.addCommand(ntCreate) 

2831 self.sendSMB(smb) 

2832 

2833 while 1: 

2834 smb = self.recvSMB() 

2835 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX): 2835 ↛ 2839line 2835 didn't jump to line 2839, because the condition on line 2835 was never false

2836 # XXX Here we are ignoring the rest of the response 

2837 self.tid = smb['Tid'] 

2838 return self.tid 

2839 self.tid = smb['Tid'] 

2840 return self.tid 

2841 

2842 # backwars compatibility 

2843 connect_tree = tree_connect_andx 

2844 

2845 @staticmethod 

2846 def getDialect(): 

2847 return SMB_DIALECT 

2848 

2849 def get_server_name(self): 

2850 #return self._dialects_data['ServerName'] 

2851 return self.__server_name 

2852 

2853 def get_client_name(self): 

2854 return self.__client_name 

2855 

2856 def get_session_key(self): 

2857 return self._SigningSessionKey 

2858 

2859 def set_session_key(self, key): 

2860 self._SignatureEnabled = True 

2861 self._SignSequenceNumber = 2 

2862 self._SigningSessionKey = key 

2863 

2864 def get_encryption_key(self): 

2865 if 'Challenge' in self._dialects_data.fields: 

2866 return self._dialects_data['Challenge'] 

2867 else: 

2868 return None 

2869 

2870 def get_server_time(self): 

2871 timestamp = self._dialects_parameters['HighDateTime'] 

2872 timestamp <<= 32 

2873 timestamp |= self._dialects_parameters['LowDateTime'] 

2874 timestamp -= 116444736000000000 

2875 timestamp //= 10000000 

2876 d = datetime.datetime.utcfromtimestamp(timestamp) 

2877 return d.strftime("%a, %d %b %Y %H:%M:%S GMT") 

2878 

2879 def disconnect_tree(self, tid): 

2880 smb = NewSMBPacket() 

2881 smb['Tid'] = tid 

2882 

2883 smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT)) 

2884 

2885 self.sendSMB(smb) 

2886 self.recvSMB() 

2887 

2888 def open(self, tid, filename, open_mode, desired_access): 

2889 filename = filename.replace('/', '\\') 

2890 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

2891 

2892 smb = NewSMBPacket() 

2893 smb['Tid'] = tid 

2894 

2895 openFile = SMBCommand(SMB.SMB_COM_OPEN) 

2896 openFile['Parameters'] = SMBOpen_Parameters() 

2897 openFile['Parameters']['DesiredAccess'] = desired_access 

2898 openFile['Parameters']['OpenMode'] = open_mode 

2899 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 

2900 openFile['Data'] = SMBOpen_Data(flags=self.__flags2) 

2901 openFile['Data']['FileName'] = filename 

2902 

2903 smb.addCommand(openFile) 

2904 

2905 self.sendSMB(smb) 

2906 

2907 smb = self.recvSMB() 

2908 if smb.isValidAnswer(SMB.SMB_COM_OPEN): 

2909 # XXX Here we are ignoring the rest of the response 

2910 openFileResponse = SMBCommand(smb['Data'][0]) 

2911 openFileParameters = SMBOpenResponse_Parameters(openFileResponse['Parameters']) 

2912 

2913 return ( 

2914 openFileParameters['Fid'], 

2915 openFileParameters['FileAttributes'], 

2916 openFileParameters['LastWriten'], 

2917 openFileParameters['FileSize'], 

2918 openFileParameters['GrantedAccess'], 

2919 ) 

2920 

2921 def open_andx(self, tid, filename, open_mode, desired_access): 

2922 filename = filename.replace('/', '\\') 

2923 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

2924 

2925 smb = NewSMBPacket() 

2926 smb['Tid'] = tid 

2927 

2928 openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX) 

2929 openFile['Parameters'] = SMBOpenAndX_Parameters() 

2930 openFile['Parameters']['DesiredAccess'] = desired_access 

2931 openFile['Parameters']['OpenMode'] = open_mode 

2932 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 

2933 openFile['Data'] = SMBOpenAndX_Data(flags=self.__flags2) 

2934 openFile['Data']['FileName'] = filename 

2935 

2936 if self.__flags2 & SMB.FLAGS2_UNICODE: 

2937 openFile['Data']['Pad'] = 0x0 

2938 

2939 smb.addCommand(openFile) 

2940 

2941 self.sendSMB(smb) 

2942 

2943 smb = self.recvSMB() 

2944 if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX): 

2945 # XXX Here we are ignoring the rest of the response 

2946 openFileResponse = SMBCommand(smb['Data'][0]) 

2947 openFileParameters = SMBOpenAndXResponse_Parameters(openFileResponse['Parameters']) 

2948 

2949 return ( 

2950 openFileParameters['Fid'], 

2951 openFileParameters['FileAttributes'], 

2952 openFileParameters['LastWriten'], 

2953 openFileParameters['FileSize'], 

2954 openFileParameters['GrantedAccess'], 

2955 openFileParameters['FileType'], 

2956 openFileParameters['IPCState'], 

2957 openFileParameters['Action'], 

2958 openFileParameters['ServerFid'], 

2959 ) 

2960 

2961 def close(self, tid, fid): 

2962 smb = NewSMBPacket() 

2963 smb['Tid'] = tid 

2964 

2965 closeFile = SMBCommand(SMB.SMB_COM_CLOSE) 

2966 closeFile['Parameters'] = SMBClose_Parameters() 

2967 closeFile['Parameters']['FID'] = fid 

2968 smb.addCommand(closeFile) 

2969 

2970 self.sendSMB(smb) 

2971 smb = self.recvSMB() 

2972 if smb.isValidAnswer(SMB.SMB_COM_CLOSE): 2972 ↛ 2974line 2972 didn't jump to line 2974, because the condition on line 2972 was never false

2973 return 1 

2974 return 0 

2975 

2976 def send_trans(self, tid, setup, name, param, data, noAnswer = 0): 

2977 smb = NewSMBPacket() 

2978 smb['Tid'] = tid 

2979 

2980 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 

2981 transCommand['Parameters'] = SMBTransaction_Parameters() 

2982 transCommand['Data'] = SMBTransaction_Data() 

2983 

2984 transCommand['Parameters']['Setup'] = setup 

2985 transCommand['Parameters']['TotalParameterCount'] = len(param) 

2986 transCommand['Parameters']['TotalDataCount'] = len(data) 

2987 

2988 transCommand['Parameters']['ParameterCount'] = len(param) 

2989 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 

2990 

2991 transCommand['Parameters']['DataCount'] = len(data) 

2992 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) 

2993 

2994 transCommand['Data']['Name'] = name 

2995 transCommand['Data']['Trans_Parameters'] = param 

2996 transCommand['Data']['Trans_Data'] = data 

2997 

2998 if noAnswer: 

2999 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 

3000 

3001 smb.addCommand(transCommand) 

3002 

3003 self.sendSMB(smb) 

3004 

3005 def send_trans2(self, tid, setup, name, param, data): 

3006 smb = NewSMBPacket() 

3007 smb['Tid'] = tid 

3008 

3009 command = pack('<H', setup) 

3010 

3011 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION2) 

3012 transCommand['Parameters'] = SMBTransaction2_Parameters() 

3013 transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize'] 

3014 transCommand['Data'] = SMBTransaction2_Data() 

3015 

3016 transCommand['Parameters']['Setup'] = command 

3017 transCommand['Parameters']['TotalParameterCount'] = len(param) 

3018 transCommand['Parameters']['TotalDataCount'] = len(data) 

3019 

3020 if len(param) > 0: 3020 ↛ 3025line 3020 didn't jump to line 3025, because the condition on line 3020 was never false

3021 padLen = (4 - (32+2+28 + len(command)) % 4 ) % 4 

3022 padBytes = '\xFF' * padLen 

3023 transCommand['Data']['Pad1'] = padBytes 

3024 else: 

3025 transCommand['Data']['Pad1'] = '' 

3026 padLen = 0 

3027 

3028 transCommand['Parameters']['ParameterCount'] = len(param) 

3029 transCommand['Parameters']['ParameterOffset'] = 32+2+28+len(command)+len(name) + padLen 

3030 

3031 if len(data) > 0: 3031 ↛ 3032line 3031 didn't jump to line 3032, because the condition on line 3031 was never true

3032 pad2Len = (4 - (32+2+28 + len(command) + padLen + len(param)) % 4) % 4 

3033 transCommand['Data']['Pad2'] = '\xFF' * pad2Len 

3034 else: 

3035 transCommand['Data']['Pad2'] = '' 

3036 pad2Len = 0 

3037 

3038 transCommand['Parameters']['DataCount'] = len(data) 

3039 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len 

3040 

3041 transCommand['Data']['Name'] = name 

3042 transCommand['Data']['Trans_Parameters'] = param 

3043 transCommand['Data']['Trans_Data'] = data 

3044 smb.addCommand(transCommand) 

3045 

3046 self.sendSMB(smb) 

3047 

3048 def query_file_info(self, tid, fid, fileInfoClass = SMB_QUERY_FILE_STANDARD_INFO): 

3049 self.send_trans2(tid, SMB.TRANS2_QUERY_FILE_INFORMATION, '\x00', pack('<HH', fid, fileInfoClass), '') 

3050 

3051 resp = self.recvSMB() 

3052 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 3052 ↛ exitline 3052 didn't return from function 'query_file_info', because the condition on line 3052 was never false

3053 trans2Response = SMBCommand(resp['Data'][0]) 

3054 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3055 # Remove Potential Prefix Padding 

3056 return trans2Response['Data'][-trans2Parameters['TotalDataCount']:] 

3057 

3058 def __nonraw_retr_file(self, tid, fid, offset, datasize, callback): 

3059 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 3059 ↛ 3060line 3059 didn't jump to line 3060, because the condition on line 3059 was never true

3060 max_buf_size = 65000 

3061 else: 

3062 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Read in multiple KB blocks 

3063 

3064 read_offset = offset 

3065 while read_offset < datasize: 

3066 data = self.read_andx(tid, fid, read_offset, max_buf_size) 

3067 

3068 callback(data) 

3069 read_offset += len(data) 

3070 

3071 def __nonraw_stor_file(self, tid, fid, offset, datasize, callback): 

3072 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 3072 ↛ 3073line 3072 didn't jump to line 3073, because the condition on line 3072 was never true

3073 max_buf_size = 65000 

3074 else: 

3075 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 

3076 

3077 write_offset = offset 

3078 while 1: 

3079 data = callback(max_buf_size) 

3080 if not data: 

3081 break 

3082 

3083 smb = self.write_andx(tid,fid,data, write_offset) 

3084 writeResponse = SMBCommand(smb['Data'][0]) 

3085 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 

3086 write_offset += writeResponseParameters['Count'] 

3087 

3088 def get_server_domain(self): 

3089 return self.__server_domain 

3090 

3091 def get_server_dns_domain_name(self): 

3092 return self.__server_dns_domain_name 

3093 

3094 def get_server_dns_host_name(self): 

3095 return self.__server_dns_host_name 

3096 

3097 def get_server_os(self): 

3098 return self.__server_os 

3099 

3100 def get_server_os_major(self): 

3101 return self.__server_os_major 

3102 

3103 def get_server_os_minor(self): 

3104 return self.__server_os_minor 

3105 

3106 def get_server_os_build(self): 

3107 return self.__server_os_build 

3108 

3109 def set_server_os(self, os): 

3110 self.__server_os = os 

3111 

3112 def get_server_lanman(self): 

3113 return self.__server_lanman 

3114 

3115 def is_login_required(self): 

3116 # Login is required if share mode is user. 

3117 # Otherwise only public services or services in share mode 

3118 # are allowed. 

3119 return (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_USER 

3120 

3121 def is_signing_required(self): 

3122 return self._SignatureRequired 

3123 

3124 def get_ntlmv1_response(self, key): 

3125 challenge = self._dialects_data['Challenge'] 

3126 return ntlm.get_ntlmv1_response(key, challenge) 

3127 

3128 def perform_hostname_validation(self): 

3129 if self.__server_name == '': 

3130 if not self._validation_allow_absent: 

3131 raise self.HostnameValidationException('Hostname was not supplied by target host and absent validation is disallowed') 

3132 return 

3133 if self.__server_name.lower() != self._accepted_hostname.lower() and self.__server_dns_host_name.lower() != self._accepted_hostname.lower(): 

3134 raise self.HostnameValidationException('Supplied hostname %s does not match reported hostnames %s or %s' % 

3135 (self._accepted_hostname.lower(), self.__server_name.lower(), self.__server_dns_host_name.lower())) 

3136 

3137 

3138 def kerberos_login(self, user, password, domain = '', lmhash = '', nthash = '', aesKey = '', kdcHost = '', TGT=None, TGS=None): 

3139 # Importing down here so pyasn1 is not required if kerberos is not used. 

3140 from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set 

3141 from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS 

3142 from impacket.krb5 import constants 

3143 from impacket.krb5.types import Principal, KerberosTime, Ticket 

3144 from pyasn1.codec.der import decoder, encoder 

3145 import datetime 

3146 

3147 # login feature does not support unicode 

3148 # disable it if enabled 

3149 flags2 = self.__flags2 

3150 if flags2 & SMB.FLAGS2_UNICODE: 

3151 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3152 

3153 # If TGT or TGS are specified, they are in the form of: 

3154 # TGS['KDC_REP'] = the response from the server 

3155 # TGS['cipher'] = the cipher used 

3156 # TGS['sessionKey'] = the sessionKey 

3157 # If we have hashes, normalize them 

3158 if lmhash != '' or nthash != '': 

3159 if len(lmhash) % 2: 3159 ↛ 3160line 3159 didn't jump to line 3160, because the condition on line 3159 was never true

3160 lmhash = '0%s' % lmhash 

3161 if len(nthash) % 2: 3161 ↛ 3162line 3161 didn't jump to line 3162, because the condition on line 3161 was never true

3162 nthash = '0%s' % nthash 

3163 try: # just in case they were converted already 

3164 lmhash = a2b_hex(lmhash) 

3165 nthash = a2b_hex(nthash) 

3166 except: 

3167 pass 

3168 

3169 self.__userName = user 

3170 self.__password = password 

3171 self.__domain = domain 

3172 self.__lmhash = lmhash 

3173 self.__nthash = nthash 

3174 self.__aesKey = aesKey 

3175 self.__kdc = kdcHost 

3176 self.__TGT = TGT 

3177 self.__TGS = TGS 

3178 self._doKerberos= True 

3179 

3180 # First of all, we need to get a TGT for the user 

3181 userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) 

3182 if TGT is None: 3182 ↛ 3186line 3182 didn't jump to line 3186, because the condition on line 3182 was never false

3183 if TGS is None: 3183 ↛ 3192line 3183 didn't jump to line 3192, because the condition on line 3183 was never false

3184 tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost) 

3185 else: 

3186 tgt = TGT['KDC_REP'] 

3187 cipher = TGT['cipher'] 

3188 sessionKey = TGT['sessionKey'] 

3189 

3190 # Now that we have the TGT, we should ask for a TGS for cifs 

3191 

3192 if TGS is None: 3192 ↛ 3196line 3192 didn't jump to line 3196, because the condition on line 3192 was never false

3193 serverName = Principal('cifs/%s' % self.__remote_name, type=constants.PrincipalNameType.NT_SRV_INST.value) 

3194 tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey) 

3195 else: 

3196 tgs = TGS['KDC_REP'] 

3197 cipher = TGS['cipher'] 

3198 sessionKey = TGS['sessionKey'] 

3199 

3200 smb = NewSMBPacket() 

3201 

3202 # Are we required to sign SMB? If so we do it, if not we skip it 

3203 if self._SignatureRequired: 3203 ↛ 3207line 3203 didn't jump to line 3207, because the condition on line 3203 was never false

3204 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3205 

3206 

3207 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3208 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 

3209 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 

3210 

3211 sessionSetup['Parameters']['MaxBufferSize'] = 61440 

3212 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3213 sessionSetup['Parameters']['VcNumber'] = 1 

3214 sessionSetup['Parameters']['SessionKey'] = 0 

3215 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3216 

3217 

3218 # Let's build a NegTokenInit with the NTLMSSP 

3219 # TODO: In the future we should be able to choose different providers 

3220 

3221 blob = SPNEGO_NegTokenInit() 

3222 

3223 # Kerberos v5 mech 

3224 blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']] 

3225 

3226 # Let's extract the ticket from the TGS 

3227 tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0] 

3228 ticket = Ticket() 

3229 ticket.from_asn1(tgs['ticket']) 

3230 

3231 # Now let's build the AP_REQ 

3232 apReq = AP_REQ() 

3233 apReq['pvno'] = 5 

3234 apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value) 

3235 

3236 opts = list() 

3237 apReq['ap-options'] = constants.encodeFlags(opts) 

3238 seq_set(apReq,'ticket', ticket.to_asn1) 

3239 

3240 authenticator = Authenticator() 

3241 authenticator['authenticator-vno'] = 5 

3242 authenticator['crealm'] = domain 

3243 seq_set(authenticator, 'cname', userName.components_to_asn1) 

3244 now = datetime.datetime.utcnow() 

3245 

3246 authenticator['cusec'] = now.microsecond 

3247 authenticator['ctime'] = KerberosTime.to_asn1(now) 

3248 

3249 encodedAuthenticator = encoder.encode(authenticator) 

3250 

3251 # Key Usage 11 

3252 # AP-REQ Authenticator (includes application authenticator 

3253 # subkey), encrypted with the application session key 

3254 # (Section 5.5.1) 

3255 encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None) 

3256 

3257 apReq['authenticator'] = noValue 

3258 apReq['authenticator']['etype'] = cipher.enctype 

3259 apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator 

3260 

3261 blob['MechToken'] = pack('B', ASN1_AID) + asn1encode(pack('B', ASN1_OID) + asn1encode( 

3262 TypesMech['KRB5 - Kerberos 5']) + KRB5_AP_REQ + encoder.encode(apReq)) 

3263 

3264 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 

3265 sessionSetup['Parameters'].getData() 

3266 sessionSetup['Data']['SecurityBlob'] = blob.getData() 

3267 

3268 # Fake Data here, don't want to get us fingerprinted 

3269 sessionSetup['Data']['NativeOS'] = 'Unix' 

3270 sessionSetup['Data']['NativeLanMan'] = 'Samba' 

3271 

3272 smb.addCommand(sessionSetup) 

3273 self.sendSMB(smb) 

3274 

3275 smb = self.recvSMB() 

3276 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3276 ↛ 3300line 3276 didn't jump to line 3300, because the condition on line 3276 was never false

3277 # We will need to use this uid field for all future requests/responses 

3278 self._uid = smb['Uid'] 

3279 

3280 # Now we have to extract the blob to continue the auth process 

3281 sessionResponse = SMBCommand(smb['Data'][0]) 

3282 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 

3283 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 

3284 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 

3285 sessionData.fromString(sessionResponse['Data']) 

3286 

3287 self._action = sessionParameters['Action'] 

3288 # If smb sign required, let's enable it for the rest of the connection 

3289 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3289 ↛ 3295line 3289 didn't jump to line 3295, because the condition on line 3289 was never false

3290 self._SigningSessionKey = sessionKey.contents 

3291 self._SignSequenceNumber = 2 

3292 self._SignatureEnabled = True 

3293 

3294 # restore unicode flag if needed 

3295 if flags2 & SMB.FLAGS2_UNICODE: 

3296 self.__flags2 |= SMB.FLAGS2_UNICODE 

3297 

3298 return 1 

3299 else: 

3300 raise Exception('Error: Could not login successfully') 

3301 

3302 def login_extended(self, user, password, domain = '', lmhash = '', nthash = '', use_ntlmv2 = True ): 

3303 

3304 # login feature does not support unicode 

3305 # disable it if enabled 

3306 flags2 = self.__flags2 

3307 if flags2 & SMB.FLAGS2_UNICODE: 

3308 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3309 

3310 # Once everything's working we should join login methods into a single one 

3311 smb = NewSMBPacket() 

3312 # Are we required to sign SMB? If so we do it, if not we skip it 

3313 if self._SignatureRequired: 3313 ↛ 3316line 3313 didn't jump to line 3316, because the condition on line 3313 was never false

3314 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3315 

3316 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3317 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 

3318 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 

3319 

3320 sessionSetup['Parameters']['MaxBufferSize'] = 61440 

3321 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3322 sessionSetup['Parameters']['VcNumber'] = 1 

3323 sessionSetup['Parameters']['SessionKey'] = 0 

3324 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3325 

3326 

3327 # Let's build a NegTokenInit with the NTLMSSP 

3328 # TODO: In the future we should be able to choose different providers 

3329 

3330 blob = SPNEGO_NegTokenInit() 

3331 

3332 # NTLMSSP 

3333 blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']] 

3334 auth = ntlm.getNTLMSSPType1(self.get_client_name(),domain,self._SignatureRequired, use_ntlmv2 = use_ntlmv2) 

3335 blob['MechToken'] = auth.getData() 

3336 

3337 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 

3338 sessionSetup['Parameters'].getData() 

3339 sessionSetup['Data']['SecurityBlob'] = blob.getData() 

3340 

3341 # Fake Data here, don't want to get us fingerprinted 

3342 sessionSetup['Data']['NativeOS'] = 'Unix' 

3343 sessionSetup['Data']['NativeLanMan'] = 'Samba' 

3344 

3345 smb.addCommand(sessionSetup) 

3346 self.sendSMB(smb) 

3347 

3348 smb = self.recvSMB() 

3349 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3349 ↛ 3446line 3349 didn't jump to line 3446, because the condition on line 3349 was never false

3350 # We will need to use this uid field for all future requests/responses 

3351 self._uid = smb['Uid'] 

3352 

3353 # Now we have to extract the blob to continue the auth process 

3354 sessionResponse = SMBCommand(smb['Data'][0]) 

3355 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 

3356 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 

3357 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 

3358 sessionData.fromString(sessionResponse['Data']) 

3359 respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob']) 

3360 

3361 # Let's parse some data and keep it to ourselves in case it is asked 

3362 ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken']) 

3363 if ntlmChallenge['TargetInfoFields_len'] > 0: 3363 ↛ 3392line 3363 didn't jump to line 3392, because the condition on line 3363 was never false

3364 av_pairs = ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']]) 

3365 if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None: 3365 ↛ 3371line 3365 didn't jump to line 3371, because the condition on line 3365 was never false

3366 try: 

3367 self.__server_name = av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le') 

3368 except UnicodeDecodeError: 

3369 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3370 pass 

3371 if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None: 3371 ↛ 3378line 3371 didn't jump to line 3378, because the condition on line 3371 was never false

3372 try: 

3373 if self.__server_name != av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'): 3373 ↛ 3378line 3373 didn't jump to line 3378, because the condition on line 3373 was never false

3374 self.__server_domain = av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le') 

3375 except UnicodeDecodeError: 

3376 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3377 pass 

3378 if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None: 3378 ↛ 3385line 3378 didn't jump to line 3385, because the condition on line 3378 was never false

3379 try: 

3380 self.__server_dns_domain_name = av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le') 

3381 except UnicodeDecodeError: 

3382 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3383 pass 

3384 

3385 if av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME] is not None: 3385 ↛ 3392line 3385 didn't jump to line 3392, because the condition on line 3385 was never false

3386 try: 

3387 self.__server_dns_host_name = av_pairs[ntlm.NTLMSSP_AV_DNS_HOSTNAME][1].decode('utf-16le') 

3388 except UnicodeDecodeError: 

3389 # For some reason, we couldn't decode Unicode here.. silently discard the operation 

3390 pass 

3391 

3392 if self._strict_hostname_validation: 3392 ↛ 3393line 3392 didn't jump to line 3393, because the condition on line 3392 was never true

3393 self.perform_hostname_validation() 

3394 

3395 # Parse Version to know the target Operating system name. Not provided elsewhere anymore 

3396 if 'Version' in ntlmChallenge.fields: 3396 ↛ 3402line 3396 didn't jump to line 3402, because the condition on line 3396 was never false

3397 version = ntlmChallenge['Version'] 

3398 

3399 if len(version) >= 4: 3399 ↛ 3402line 3399 didn't jump to line 3402, because the condition on line 3399 was never false

3400 self.__server_os_major, self.__server_os_minor, self.__server_os_build = unpack('<BBH',version[:4]) 

3401 

3402 type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 = use_ntlmv2) 

3403 

3404 if exportedSessionKey is not None: 3404 ↛ 3407line 3404 didn't jump to line 3407, because the condition on line 3404 was never false

3405 self._SigningSessionKey = exportedSessionKey 

3406 

3407 smb = NewSMBPacket() 

3408 

3409 # Are we required to sign SMB? If so we do it, if not we skip it 

3410 if self._SignatureRequired: 3410 ↛ 3413line 3410 didn't jump to line 3413, because the condition on line 3410 was never false

3411 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 

3412 

3413 respToken2 = SPNEGO_NegTokenResp() 

3414 respToken2['ResponseToken'] = type3.getData() 

3415 

3416 # Reusing the previous structure 

3417 sessionSetup['Parameters']['SecurityBlobLength'] = len(respToken2) 

3418 sessionSetup['Data']['SecurityBlob'] = respToken2.getData() 

3419 

3420 # Storing some info for later use 

3421 self.__server_os = sessionData['NativeOS'] 

3422 self.__server_lanman = sessionData['NativeLanMan'] 

3423 

3424 smb.addCommand(sessionSetup) 

3425 self.sendSMB(smb) 

3426 

3427 smb = self.recvSMB() 

3428 self._uid = 0 

3429 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3429 ↛ exitline 3429 didn't return from function 'login_extended', because the condition on line 3429 was never false

3430 self._uid = smb['Uid'] 

3431 sessionResponse = SMBCommand(smb['Data'][0]) 

3432 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 

3433 

3434 self._action = sessionParameters['Action'] 

3435 # If smb sign required, let's enable it for the rest of the connection 

3436 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3436 ↛ 3441line 3436 didn't jump to line 3441, because the condition on line 3436 was never false

3437 self._SignSequenceNumber = 2 

3438 self._SignatureEnabled = True 

3439 

3440 # restore unicode flag if needed 

3441 if flags2 & SMB.FLAGS2_UNICODE: 

3442 self.__flags2 |= SMB.FLAGS2_UNICODE 

3443 

3444 return 1 

3445 else: 

3446 raise Exception('Error: Could not login successfully') 

3447 

3448 def getCredentials(self): 

3449 return ( 

3450 self.__userName, 

3451 self.__password, 

3452 self.__domain, 

3453 self.__lmhash, 

3454 self.__nthash, 

3455 self.__aesKey, 

3456 self.__TGT, 

3457 self.__TGS) 

3458 

3459 def getIOCapabilities(self): 

3460 res = dict() 

3461 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 3461 ↛ 3462line 3461 didn't jump to line 3462, because the condition on line 3461 was never true

3462 max_size = 65000 

3463 else: 

3464 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3465 res['MaxReadSize'] = max_size 

3466 res['MaxWriteSize'] = max_size 

3467 return res 

3468 

3469 def login(self, user, password, domain = '', lmhash = '', nthash = '', ntlm_fallback = True): 

3470 

3471 # If we have hashes, normalize them 

3472 if lmhash != '' or nthash != '': 

3473 if len(lmhash) % 2: 3473 ↛ 3474line 3473 didn't jump to line 3474, because the condition on line 3473 was never true

3474 lmhash = '0%s' % lmhash 

3475 if len(nthash) % 2: 3475 ↛ 3476line 3475 didn't jump to line 3476, because the condition on line 3475 was never true

3476 nthash = '0%s' % nthash 

3477 try: # just in case they were converted already 

3478 lmhash = a2b_hex(lmhash) 

3479 nthash = a2b_hex(nthash) 

3480 except: 

3481 pass 

3482 

3483 self.__userName = user 

3484 self.__password = password 

3485 self.__domain = domain 

3486 self.__lmhash = lmhash 

3487 self.__nthash = nthash 

3488 self.__aesKey = '' 

3489 self.__TGT = None 

3490 self.__TGS = None 

3491 

3492 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 3492 ↛ 3502line 3492 didn't jump to line 3502, because the condition on line 3492 was never false

3493 try: 

3494 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = True) 

3495 except: 

3496 # If the target OS is Windows 5.0 or Samba, let's try using NTLMv1 

3497 if ntlm_fallback and ((self.get_server_lanman().find('Windows 2000') != -1) or (self.get_server_lanman().find('Samba') != -1)): 

3498 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = False) 

3499 self.__isNTLMv2 = False 

3500 else: 

3501 raise 

3502 elif ntlm_fallback: 

3503 self.login_standard(user, password, domain, lmhash, nthash) 

3504 self.__isNTLMv2 = False 

3505 else: 

3506 raise SessionError('Cannot authenticate against target, enable ntlm_fallback') 

3507 

3508 def login_standard(self, user, password, domain = '', lmhash = '', nthash = ''): 

3509 

3510 # login feature does not support unicode 

3511 # disable it if enabled 

3512 flags2 = self.__flags2 

3513 if flags2 & SMB.FLAGS2_UNICODE: 

3514 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 

3515 

3516 # Only supports NTLMv1 

3517 # Password is only encrypted if the server passed us an "encryption key" during protocol dialect negotiation 

3518 if self._dialects_parameters['ChallengeLength'] > 0: 

3519 if lmhash != '' or nthash != '': 

3520 pwd_ansi = self.get_ntlmv1_response(lmhash) 

3521 pwd_unicode = self.get_ntlmv1_response(nthash) 

3522 elif password: 

3523 lmhash = ntlm.compute_lmhash(password) 

3524 nthash = ntlm.compute_nthash(password) 

3525 pwd_ansi = self.get_ntlmv1_response(lmhash) 

3526 pwd_unicode = self.get_ntlmv1_response(nthash) 

3527 else: # NULL SESSION 

3528 pwd_ansi = '' 

3529 pwd_unicode = '' 

3530 else: 

3531 pwd_ansi = password 

3532 pwd_unicode = '' 

3533 

3534 smb = NewSMBPacket() 

3535 

3536 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 

3537 sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters() 

3538 sessionSetup['Data'] = SMBSessionSetupAndX_Data() 

3539 

3540 sessionSetup['Parameters']['MaxBuffer'] = 61440 

3541 sessionSetup['Parameters']['MaxMpxCount'] = 2 

3542 sessionSetup['Parameters']['VCNumber'] = os.getpid() & 0xFFFF # Value has to be expressed in 2 bytes 

3543 sessionSetup['Parameters']['SessionKey'] = self._dialects_parameters['SessionKey'] 

3544 sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi) 

3545 sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode) 

3546 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE | SMB.CAP_USE_NT_ERRORS | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 

3547 

3548 sessionSetup['Data']['AnsiPwd'] = pwd_ansi 

3549 sessionSetup['Data']['UnicodePwd'] = pwd_unicode 

3550 sessionSetup['Data']['Account'] = str(user) 

3551 sessionSetup['Data']['PrimaryDomain'] = str(domain) 

3552 sessionSetup['Data']['NativeOS'] = str(os.name) 

3553 sessionSetup['Data']['NativeLanMan'] = 'pysmb' 

3554 smb.addCommand(sessionSetup) 

3555 

3556 self.sendSMB(smb) 

3557 

3558 smb = self.recvSMB() 

3559 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 

3560 # We will need to use this uid field for all future requests/responses 

3561 self._uid = smb['Uid'] 

3562 sessionResponse = SMBCommand(smb['Data'][0]) 

3563 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 

3564 sessionData = SMBSessionSetupAndXResponse_Data(flags = smb['Flags2'], data = sessionResponse['Data']) 

3565 

3566 self._action = sessionParameters['Action'] 

3567 

3568 # Still gotta figure out how to do this with no EXTENDED_SECURITY 

3569 if sessionParameters['Action'] & SMB_SETUP_USE_LANMAN_KEY == 0: 

3570 self._SigningChallengeResponse = sessionSetup['Data']['UnicodePwd'] 

3571 self._SigningSessionKey = nthash 

3572 else: 

3573 self._SigningChallengeResponse = sessionSetup['Data']['AnsiPwd'] 

3574 self._SigningSessionKey = lmhash 

3575 

3576 #self._SignSequenceNumber = 1 

3577 #self.checkSignSMB(smb, self._SigningSessionKey ,self._SigningChallengeResponse) 

3578 #self._SignatureEnabled = True 

3579 self.__server_os = sessionData['NativeOS'] 

3580 self.__server_lanman = sessionData['NativeLanMan'] 

3581 self.__server_domain = sessionData['PrimaryDomain'] 

3582 

3583 # restore unicode flag if needed 

3584 if flags2 & SMB.FLAGS2_UNICODE: 

3585 self.__flags2 |= SMB.FLAGS2_UNICODE 

3586 

3587 return 1 

3588 else: 

3589 raise Exception('Error: Could not login successfully') 

3590 

3591 def waitNamedPipe(self, tid, pipe, timeout = 5, noAnswer = 0): 

3592 smb = NewSMBPacket() 

3593 smb['Tid'] = tid 

3594 

3595 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 

3596 transCommand['Parameters'] = SMBTransaction_Parameters() 

3597 transCommand['Data'] = SMBTransaction_Data() 

3598 

3599 setup = '\x53\x00\x00\x00' 

3600 name = '\\PIPE%s\x00' % pipe 

3601 transCommand['Parameters']['Setup'] = setup 

3602 transCommand['Parameters']['TotalParameterCount'] = 0 

3603 transCommand['Parameters']['TotalDataCount'] = 0 

3604 transCommand['Parameters']['MaxParameterCount'] = 0 

3605 transCommand['Parameters']['MaxDataCount'] = 0 

3606 transCommand['Parameters']['Timeout'] = timeout * 1000 

3607 

3608 transCommand['Parameters']['ParameterCount'] = 0 

3609 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 

3610 

3611 transCommand['Parameters']['DataCount'] = 0 

3612 transCommand['Parameters']['DataOffset'] = 0 

3613 

3614 transCommand['Data']['Name'] = name 

3615 transCommand['Data']['Trans_Parameters'] = '' 

3616 transCommand['Data']['Trans_Data'] = '' 

3617 

3618 if noAnswer: 

3619 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 

3620 

3621 smb.addCommand(transCommand) 

3622 self.sendSMB(smb) 

3623 

3624 smb = self.recvSMB() 

3625 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3626 return 1 

3627 return 0 

3628 

3629 def read(self, tid, fid, offset=0, max_size = None, wait_answer=1): 

3630 if not max_size: 

3631 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3632 

3633 # max_size is not working, because although it would, the server returns an error (More data avail) 

3634 

3635 smb = NewSMBPacket() 

3636 smb['Tid'] = tid 

3637 

3638 read = SMBCommand(SMB.SMB_COM_READ) 

3639 read['Parameters'] = SMBRead_Parameters() 

3640 read['Parameters']['Fid'] = fid 

3641 read['Parameters']['Offset'] = offset 

3642 read['Parameters']['Count'] = max_size 

3643 smb.addCommand(read) 

3644 

3645 if wait_answer: 

3646 while 1: 

3647 self.sendSMB(smb) 

3648 ans = self.recvSMB() 

3649 

3650 if ans.isValidAnswer(SMB.SMB_COM_READ): 

3651 readResponse = SMBCommand(ans['Data'][0]) 

3652 readData = SMBReadResponse_Data(readResponse['Data']) 

3653 

3654 return readData['Data'] 

3655 

3656 return None 

3657 

3658 def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, smb_packet=None): 

3659 if not max_size: 3659 ↛ 3660line 3659 didn't jump to line 3660, because the condition on line 3659 was never true

3660 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 

3661 max_size = 65000 

3662 else: 

3663 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3664 

3665 # max_size is not working, because although it would, the server returns an error (More data avail) 

3666 

3667 if smb_packet is None: 3667 ↛ 3678line 3667 didn't jump to line 3678, because the condition on line 3667 was never false

3668 smb = NewSMBPacket() 

3669 smb['Tid'] = tid 

3670 

3671 readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX) 

3672 readAndX['Parameters'] = SMBReadAndX_Parameters() 

3673 readAndX['Parameters']['Fid'] = fid 

3674 readAndX['Parameters']['Offset'] = offset 

3675 readAndX['Parameters']['MaxCount'] = max_size 

3676 smb.addCommand(readAndX) 

3677 else: 

3678 smb = smb_packet 

3679 

3680 if wait_answer: 3680 ↛ 3699line 3680 didn't jump to line 3699, because the condition on line 3680 was never false

3681 answer = b'' 

3682 while 1: 

3683 self.sendSMB(smb) 

3684 ans = self.recvSMB() 

3685 

3686 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 3686 ↛ 3683line 3686 didn't jump to line 3683, because the condition on line 3686 was never false

3687 # XXX Here we are only using a few fields from the response 

3688 readAndXResponse = SMBCommand(ans['Data'][0]) 

3689 readAndXParameters = SMBReadAndXResponse_Parameters(readAndXResponse['Parameters']) 

3690 

3691 offset = readAndXParameters['DataOffset'] 

3692 count = readAndXParameters['DataCount']+0x10000*readAndXParameters['DataCount_Hi'] 

3693 answer += ans.getData()[offset:offset+count] 

3694 if not ans.isMoreData(): 3694 ↛ 3696line 3694 didn't jump to line 3696, because the condition on line 3694 was never false

3695 return answer 

3696 max_size = min(max_size, readAndXParameters['Remaining']) 

3697 readAndX['Parameters']['Offset'] += count # XXX Offset is not important (apparently) 

3698 else: 

3699 self.sendSMB(smb) 

3700 ans = self.recvSMB() 

3701 

3702 try: 

3703 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 

3704 return ans 

3705 else: 

3706 return None 

3707 except: 

3708 return ans 

3709 

3710 return None 

3711 

3712 def read_raw(self, tid, fid, offset=0, max_size = None, wait_answer=1): 

3713 if not max_size: 

3714 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 

3715 

3716 # max_size is not working, because although it would, the server returns an error (More data avail) 

3717 smb = NewSMBPacket() 

3718 smb['Tid'] = tid 

3719 

3720 readRaw = SMBCommand(SMB.SMB_COM_READ_RAW) 

3721 readRaw['Parameters'] = SMBReadRaw_Parameters() 

3722 readRaw['Parameters']['Fid'] = fid 

3723 readRaw['Parameters']['Offset'] = offset 

3724 readRaw['Parameters']['MaxCount'] = max_size 

3725 smb.addCommand(readRaw) 

3726 

3727 self.sendSMB(smb) 

3728 if wait_answer: 

3729 data = self._sess.recv_packet(self.__timeout).get_trailer() 

3730 if not data: 

3731 # If there is no data it means there was an error 

3732 data = self.read_andx(tid, fid, offset, max_size) 

3733 return data 

3734 

3735 return None 

3736 

3737 def write(self,tid,fid,data, offset = 0, wait_answer=1): 

3738 smb = NewSMBPacket() 

3739 smb['Tid'] = tid 

3740 

3741 write = SMBCommand(SMB.SMB_COM_WRITE) 

3742 write['Parameters'] = SMBWrite_Parameters() 

3743 write['Data'] = SMBWrite_Data() 

3744 write['Parameters']['Fid'] = fid 

3745 write['Parameters']['Count'] = len(data) 

3746 write['Parameters']['Offset'] = offset 

3747 write['Parameters']['Remaining'] = len(data) 

3748 write['Data']['Data'] = data 

3749 smb.addCommand(write) 

3750 

3751 self.sendSMB(smb) 

3752 

3753 if wait_answer: 

3754 smb = self.recvSMB() 

3755 if smb.isValidAnswer(SMB.SMB_COM_WRITE): 

3756 return smb 

3757 return None 

3758 

3759 def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, write_pipe_mode = False, smb_packet=None): 

3760 if smb_packet is None: 3760 ↛ 3810line 3760 didn't jump to line 3810, because the condition on line 3760 was never false

3761 smb = NewSMBPacket() 

3762 smb['Tid'] = tid 

3763 

3764 writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX) 

3765 smb.addCommand(writeAndX) 

3766 

3767 writeAndX['Parameters'] = SMBWriteAndX_Parameters() 

3768 writeAndX['Parameters']['Fid'] = fid 

3769 writeAndX['Parameters']['Offset'] = offset 

3770 writeAndX['Parameters']['WriteMode'] = 8 

3771 writeAndX['Parameters']['Remaining'] = len(data) 

3772 writeAndX['Parameters']['DataLength'] = len(data) 

3773 writeAndX['Parameters']['DataOffset'] = len(smb) # this length already includes the parameter 

3774 writeAndX['Data'] = data 

3775 

3776 if write_pipe_mode is True: 3776 ↛ 3778line 3776 didn't jump to line 3778, because the condition on line 3776 was never true

3777 # First of all we gotta know what the MaxBuffSize is 

3778 maxBuffSize = self._dialects_parameters['MaxBufferSize'] 

3779 if len(data) > maxBuffSize: 

3780 chunks_size = maxBuffSize - 60 

3781 writeAndX['Parameters']['WriteMode'] = 0x0c 

3782 sendData = b'\xff\xff' + data 

3783 totalLen = len(sendData) 

3784 writeAndX['Parameters']['DataLength'] = chunks_size 

3785 writeAndX['Parameters']['Remaining'] = totalLen-2 

3786 writeAndX['Data'] = sendData[:chunks_size] 

3787 

3788 self.sendSMB(smb) 

3789 if wait_answer: 

3790 smbResp = self.recvSMB() 

3791 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 

3792 

3793 alreadySent = chunks_size 

3794 sendData = sendData[chunks_size:] 

3795 

3796 while alreadySent < totalLen: 

3797 writeAndX['Parameters']['WriteMode'] = 0x04 

3798 writeAndX['Parameters']['DataLength'] = len(sendData[:chunks_size]) 

3799 writeAndX['Data'] = sendData[:chunks_size] 

3800 self.sendSMB(smb) 

3801 if wait_answer: 

3802 smbResp = self.recvSMB() 

3803 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 

3804 alreadySent += writeAndX['Parameters']['DataLength'] 

3805 sendData = sendData[chunks_size:] 

3806 

3807 return smbResp 

3808 

3809 else: 

3810 smb = smb_packet 

3811 

3812 self.sendSMB(smb) 

3813 

3814 if wait_answer: 3814 ↛ 3818line 3814 didn't jump to line 3818, because the condition on line 3814 was never false

3815 smb = self.recvSMB() 

3816 if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX): 3816 ↛ 3818line 3816 didn't jump to line 3818, because the condition on line 3816 was never false

3817 return smb 

3818 return None 

3819 

3820 def write_raw(self,tid,fid,data, offset = 0, wait_answer=1): 

3821 LOG.warning("[MS-CIFS] This command was introduced in the CorePlus dialect, but is often listed as part of the LAN Manager 1.0 dialect.This command has been deprecated.Clients SHOULD use SMB_COM_WRITE_ANDX") 

3822 smb = NewSMBPacket() 

3823 smb['Tid'] = tid 

3824 

3825 writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW) 

3826 writeRaw['Parameters'] = SMBWriteRaw_Parameters() 

3827 writeRaw['Parameters']['Fid'] = fid 

3828 writeRaw['Parameters']['Offset'] = offset 

3829 writeRaw['Parameters']['Count'] = len(data) 

3830 writeRaw['Parameters']['DataLength'] = 0 

3831 writeRaw['Parameters']['DataOffset'] = 0 

3832 smb.addCommand(writeRaw) 

3833 

3834 self.sendSMB(smb) 

3835 self._sess.send_packet(data) 

3836 

3837 if wait_answer: 

3838 smb = self.recvSMB() 

3839 if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW): 

3840 return smb 

3841 return None 

3842 

3843 def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer = 1, offset = 0): 

3844 self.send_trans(tid,pack('<HH', 0x26, fid),'\\PIPE\\\x00','',data, noAnswer = noAnswer) 

3845 

3846 if noAnswer or not waitAnswer: 

3847 return 

3848 smb = self.recvSMB() 

3849 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3850 transResponse = SMBCommand(smb['Data'][0]) 

3851 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 

3852 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 

3853 return None 

3854 

3855 def TransactNamedPipeRecv(self): 

3856 s = self.recvSMB() 

3857 if s.isValidAnswer(SMB.SMB_COM_TRANSACTION): 

3858 transResponse = SMBCommand(s['Data'][0]) 

3859 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 

3860 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 

3861 return None 

3862 

3863 def nt_create_andx(self,tid,filename, smb_packet=None, cmd = None, shareAccessMode = FILE_SHARE_READ | FILE_SHARE_WRITE, disposition = FILE_OPEN, accessMask = 0x2019f): 

3864 filename = filename.replace('/', '\\') 

3865 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 

3866 

3867 if smb_packet is None: 3867 ↛ 3871line 3867 didn't jump to line 3871, because the condition on line 3867 was never false

3868 smb = NewSMBPacket() 

3869 smb['Tid'] = tid 

3870 else: 

3871 smb = smb_packet 

3872 

3873 if cmd is None: 

3874 ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 

3875 ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 

3876 ntCreate['Data'] = SMBNtCreateAndX_Data(flags=self.__flags2) 

3877 ntCreate['Parameters']['FileNameLength'] = len(filename) 

3878 ntCreate['Parameters']['CreateFlags'] = 0x16 

3879 ntCreate['Parameters']['AccessMask'] = accessMask 

3880 ntCreate['Parameters']['CreateOptions'] = 0x40 

3881 ntCreate['Parameters']['ShareAccess'] = shareAccessMode 

3882 ntCreate['Parameters']['Disposition'] = disposition 

3883 ntCreate['Data']['FileName'] = filename 

3884 

3885 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3886 ntCreate['Data']['Pad'] = 0x0 

3887 else: 

3888 ntCreate = cmd 

3889 

3890 smb.addCommand(ntCreate) 

3891 

3892 self.sendSMB(smb) 

3893 

3894 while 1: 

3895 smb = self.recvSMB() 

3896 if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX): 3896 ↛ 3895line 3896 didn't jump to line 3895, because the condition on line 3896 was never false

3897 # XXX Here we are ignoring the rest of the response 

3898 ntCreateResponse = SMBCommand(smb['Data'][0]) 

3899 ntCreateParameters = SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters']) 

3900 

3901 self.fid = ntCreateParameters['Fid'] 

3902 return ntCreateParameters['Fid'] 

3903 

3904 def logoff(self): 

3905 smb = NewSMBPacket() 

3906 

3907 logOff = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX) 

3908 logOff['Parameters'] = SMBLogOffAndX() 

3909 smb.addCommand(logOff) 

3910 

3911 self.sendSMB(smb) 

3912 self.recvSMB() 

3913 # Let's clear some fields so you can login again under the same session 

3914 self._uid = 0 

3915 

3916 def list_path(self, service, path = '*', password = None): 

3917 path = path.replace('/', '\\') 

3918 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

3919 

3920 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

3921 try: 

3922 findFirstParameter = SMBFindFirst2_Parameters(self.__flags2) 

3923 findFirstParameter['SearchAttributes'] = SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_HIDDEN | \ 

3924 SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_READONLY | \ 

3925 SMB_FILE_ATTRIBUTE_ARCHIVE 

3926 findFirstParameter['SearchCount'] = 512 

3927 findFirstParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 

3928 findFirstParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 

3929 findFirstParameter['SearchStorageType'] = 0 

3930 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3931 findFirstParameter['FileName'] = path + b'\x00\x00' 

3932 else: 

3933 findFirstParameter['FileName'] = path + '\x00' 

3934 self.send_trans2(tid, SMB.TRANS2_FIND_FIRST2, '\x00', findFirstParameter, '') 

3935 files = [ ] 

3936 

3937 totalDataCount = 1 

3938 findData = b'' 

3939 findFirst2ParameterBlock = b'' 

3940 while len(findData) < totalDataCount: 

3941 resp = self.recvSMB() 

3942 

3943 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 3943 ↛ 3940line 3943 didn't jump to line 3940, because the condition on line 3943 was never false

3944 trans2Response = SMBCommand(resp['Data'][0]) 

3945 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3946 totalDataCount = trans2Parameters['TotalDataCount'] 

3947 findFirst2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 

3948 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 

3949 

3950 findParameterBlock = SMBFindFirst2Response_Parameters(findFirst2ParameterBlock) 

3951 # Save the SID for resume operations 

3952 sid = findParameterBlock['SID'] 

3953 

3954 while findParameterBlock['SearchCount'] > 0: 3954 ↛ 3999line 3954 didn't jump to line 3999, because the condition on line 3954 was never false

3955 record = SMBFindFileBothDirectoryInfo(data = findData) 

3956 

3957 shortname = record['ShortName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else \ 

3958 record['ShortName'].decode('cp437') 

3959 filename = record['FileName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else \ 

3960 record['FileName'].decode('cp437') 

3961 

3962 fileRecord = SharedFile(record['CreationTime'], record['LastAccessTime'], record['LastChangeTime'], 

3963 record['EndOfFile'], record['AllocationSize'], record['ExtFileAttributes'], 

3964 shortname, filename) 

3965 files.append(fileRecord) 

3966 if record['NextEntryOffset'] > 0 and len(findData[record['NextEntryOffset']:]) > 0: 

3967 findData = findData[record['NextEntryOffset']:] 

3968 else: 

3969 # More data to search? 

3970 if findParameterBlock['EndOfSearch'] == 0: 3970 ↛ 3971line 3970 didn't jump to line 3971, because the condition on line 3970 was never true

3971 resume_filename = record['FileName'] 

3972 findNextParameter = SMBFindNext2_Parameters() 

3973 findNextParameter['SID'] = sid 

3974 findNextParameter['SearchCount'] = 1024 

3975 findNextParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 

3976 findNextParameter['ResumeKey'] = 0 

3977 findNextParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 

3978 if self.__flags2 & SMB.FLAGS2_UNICODE: 

3979 findNextParameter['FileName'] = resume_filename + b'\x00\x00' 

3980 else: 

3981 findNextParameter['FileName'] = resume_filename + b'\x00' 

3982 self.send_trans2(tid, SMB.TRANS2_FIND_NEXT2, '\x00', findNextParameter, '') 

3983 findData = b'' 

3984 findNext2ParameterBlock = b'' 

3985 totalDataCount = 1 

3986 while len(findData) < totalDataCount: 

3987 resp = self.recvSMB() 

3988 

3989 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 

3990 trans2Response = SMBCommand(resp['Data'][0]) 

3991 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 

3992 totalDataCount = trans2Parameters['TotalDataCount'] 

3993 findNext2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 

3994 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 

3995 findParameterBlock = SMBFindNext2Response_Parameters(findNext2ParameterBlock) 

3996 else: 

3997 break 

3998 finally: 

3999 self.disconnect_tree(tid) 

4000 

4001 return files 

4002 

4003 def retr_file(self, service, filename, callback, mode = FILE_OPEN, offset = 0, password = None, shareAccessMode = SMB_ACCESS_READ): 

4004 filename = filename.replace('/', '\\') 

4005 

4006 fid = -1 

4007 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4008 try: 

4009 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, accessMask = 0x20089) 

4010 

4011 res = self.query_file_info(tid, fid) 

4012 datasize = SMBQueryFileStandardInfo(res)['EndOfFile'] 

4013 

4014 self.__nonraw_retr_file(tid, fid, offset, datasize, callback) 

4015 finally: 

4016 if fid >= 0: 4016 ↛ 4018line 4016 didn't jump to line 4018, because the condition on line 4016 was never false

4017 self.close(tid, fid) 

4018 self.disconnect_tree(tid) 

4019 

4020 def stor_file(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE): 

4021 filename = filename.replace('/', '\\') 

4022 

4023 fid = -1 

4024 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4025 try: 

4026 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode ) 

4027 

4028 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 

4029 finally: 

4030 if fid >= 0: 4030 ↛ 4032line 4030 didn't jump to line 4032, because the condition on line 4030 was never false

4031 self.close(tid, fid) 

4032 self.disconnect_tree(tid) 

4033 

4034 def stor_file_nonraw(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE ): 

4035 filename = filename.replace('/', '\\') 

4036 

4037 fid = -1 

4038 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4039 try: 

4040 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode) 

4041 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 

4042 finally: 

4043 if fid >= 0: 

4044 self.close(tid, fid) 

4045 self.disconnect_tree(tid) 

4046 

4047 def check_dir(self, service, path, password = None): 

4048 path = path.replace('/', '\\') 

4049 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4050 try: 

4051 smb = NewSMBPacket() 

4052 smb['Tid'] = tid 

4053 smb['Mid'] = 0 

4054 

4055 cmd = SMBCommand(SMB.SMB_COM_CHECK_DIRECTORY) 

4056 cmd['Parameters'] = '' 

4057 cmd['Data'] = SMBCheckDirectory_Data(flags = self.__flags2) 

4058 cmd['Data']['DirectoryName'] = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4059 smb.addCommand(cmd) 

4060 

4061 self.sendSMB(smb) 

4062 

4063 while 1: 

4064 s = self.recvSMB() 

4065 if s.isValidAnswer(SMB.SMB_COM_CHECK_DIRECTORY): 4065 ↛ 4064line 4065 didn't jump to line 4064, because the condition on line 4065 was never false

4066 return 

4067 finally: 

4068 self.disconnect_tree(tid) 

4069 

4070 def remove(self, service, path, password = None): 

4071 path = path.replace('/', '\\') 

4072 # Perform a list to ensure the path exists 

4073 self.list_path(service, path, password) 

4074 

4075 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4076 try: 

4077 smb = NewSMBPacket() 

4078 smb['Tid'] = tid 

4079 smb['Mid'] = 0 

4080 

4081 cmd = SMBCommand(SMB.SMB_COM_DELETE) 

4082 cmd['Parameters'] = SMBDelete_Parameters() 

4083 cmd['Parameters']['SearchAttributes'] = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE 

4084 cmd['Data'] = SMBDelete_Data(flags = self.__flags2) 

4085 cmd['Data']['FileName'] = (path + '\x00').encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else (path + '\x00') 

4086 smb.addCommand(cmd) 

4087 

4088 self.sendSMB(smb) 

4089 

4090 while 1: 

4091 s = self.recvSMB() 

4092 if s.isValidAnswer(SMB.SMB_COM_DELETE): 4092 ↛ 4091line 4092 didn't jump to line 4091, because the condition on line 4092 was never false

4093 return 

4094 finally: 

4095 self.disconnect_tree(tid) 

4096 

4097 def rmdir(self, service, path, password = None): 

4098 path = path.replace('/', '\\') 

4099 # Check that the directory exists 

4100 self.check_dir(service, path, password) 

4101 

4102 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4103 try: 

4104 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4105 

4106 smb = NewSMBPacket() 

4107 smb['Tid'] = tid 

4108 createDir = SMBCommand(SMB.SMB_COM_DELETE_DIRECTORY) 

4109 createDir['Data'] = SMBDeleteDirectory_Data(flags=self.__flags2) 

4110 createDir['Data']['DirectoryName'] = path 

4111 smb.addCommand(createDir) 

4112 

4113 self.sendSMB(smb) 

4114 

4115 while 1: 

4116 s = self.recvSMB() 

4117 if s.isValidAnswer(SMB.SMB_COM_DELETE_DIRECTORY): 4117 ↛ 4116line 4117 didn't jump to line 4116, because the condition on line 4117 was never false

4118 return 

4119 finally: 

4120 self.disconnect_tree(tid) 

4121 

4122 def mkdir(self, service, path, password = None): 

4123 path = path.replace('/', '\\') 

4124 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4125 try: 

4126 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 

4127 

4128 smb = NewSMBPacket() 

4129 smb['Tid'] = tid 

4130 smb['Mid'] = 0 

4131 

4132 createDir = SMBCommand(SMB.SMB_COM_CREATE_DIRECTORY) 

4133 createDir['Data'] = SMBCreateDirectory_Data(flags=self.__flags2) 

4134 createDir['Data']['DirectoryName'] = path 

4135 smb.addCommand(createDir) 

4136 

4137 self.sendSMB(smb) 

4138 

4139 smb = self.recvSMB() 

4140 if smb.isValidAnswer(SMB.SMB_COM_CREATE_DIRECTORY): 4140 ↛ 4142line 4140 didn't jump to line 4142, because the condition on line 4140 was never false

4141 return 1 

4142 return 0 

4143 finally: 

4144 self.disconnect_tree(tid) 

4145 

4146 def rename(self, service, old_path, new_path, password = None): 

4147 old_path = old_path.replace('/', '\\') 

4148 new_path = new_path.replace('/', '\\') 

4149 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 

4150 try: 

4151 smb = NewSMBPacket() 

4152 smb['Tid'] = tid 

4153 smb['Mid'] = 0 

4154 

4155 renameCmd = SMBCommand(SMB.SMB_COM_RENAME) 

4156 renameCmd['Parameters'] = SMBRename_Parameters() 

4157 renameCmd['Parameters']['SearchAttributes'] = ATTR_SYSTEM | ATTR_HIDDEN | ATTR_DIRECTORY 

4158 renameCmd['Data'] = SMBRename_Data(flags = self.__flags2) 

4159 renameCmd['Data']['OldFileName'] = old_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else old_path 

4160 renameCmd['Data']['NewFileName'] = new_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else new_path 

4161 smb.addCommand(renameCmd) 

4162 

4163 self.sendSMB(smb) 

4164 

4165 smb = self.recvSMB() 

4166 if smb.isValidAnswer(SMB.SMB_COM_RENAME): 4166 ↛ 4168line 4166 didn't jump to line 4168, because the condition on line 4166 was never false

4167 return 1 

4168 return 0 

4169 finally: 

4170 self.disconnect_tree(tid) 

4171 

4172 def writeFile(self, treeId, fileId, data, offset = 0): 

4173 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 4173 ↛ 4174line 4173 didn't jump to line 4174, because the condition on line 4173 was never true

4174 max_buf_size = 65000 

4175 else: 

4176 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 

4177 

4178 write_offset = offset 

4179 while 1: 

4180 if len(data) == 0: 

4181 break 

4182 writeData = data[:max_buf_size] 

4183 data = data[max_buf_size:] 

4184 

4185 smb = self.write_andx(treeId,fileId,writeData, write_offset) 

4186 writeResponse = SMBCommand(smb['Data'][0]) 

4187 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 

4188 write_offset += writeResponseParameters['Count'] 

4189 

4190 def get_socket(self): 

4191 return self._sess.get_socket() 

4192 

4193 def send_nt_trans(self, tid, subcommand, max_param_count, setup='', param='', data=''): 

4194 """ 

4195 [MS-CIFS]: 2.2.4.62.1 SMB_COM_NT_TRANSACT request. 

4196 :param tid: 

4197 :param subcommand: The transaction subcommand code 

4198 :param max_param_count: This field MUST be set as specified in the subsections of Transaction subcommands. 

4199 :param setup: Transaction context to the server, depends on transaction subcommand. 

4200 :param param: Subcommand parameter bytes if any, depends on transaction subcommand. 

4201 :param data: Subcommand data bytes if any, depends on transaction subcommand. 

4202 :return: Buffer relative to requested subcommand. 

4203 """ 

4204 smb_packet = NewSMBPacket() 

4205 smb_packet['Tid'] = tid 

4206 # setup depends on NT_TRANSACT subcommands so it may be 0. 

4207 setup_bytes = pack('<H', setup) if setup != '' else '' 

4208 

4209 transCommand = SMBCommand(SMB.SMB_COM_NT_TRANSACT) 

4210 transCommand['Parameters'] = SMBNTTransaction_Parameters() 

4211 transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize'] 

4212 transCommand['Parameters']['Setup'] = setup_bytes 

4213 transCommand['Parameters']['Function'] = subcommand 

4214 transCommand['Parameters']['TotalParameterCount'] = len(param) 

4215 transCommand['Parameters']['TotalDataCount'] = len(data) 

4216 transCommand['Parameters']['MaxParameterCount'] = max_param_count 

4217 transCommand['Parameters']['MaxSetupCount'] = 0 

4218 

4219 transCommand['Data'] = SMBNTTransaction_Data() 

4220 

4221 # SMB header size + SMB_COM_NT_TRANSACT parameters size + length of setup bytes. 

4222 offset = 32 + 3 + 38 + len(setup_bytes) 

4223 transCommand['Data']['Pad1'] = '' 

4224 if offset % 4 != 0: 

4225 transCommand['Data']['Pad1'] = '\0' * (4 - offset % 4) 

4226 offset += (4 - offset % 4) # pad1 length 

4227 

4228 if len(param) > 0: 

4229 transCommand['Parameters']['ParameterOffset'] = offset 

4230 else: 

4231 transCommand['Parameters']['ParameterOffset'] = 0 

4232 

4233 offset += len(param) 

4234 transCommand['Data']['Pad2'] = '' 

4235 if offset % 4 != 0: 

4236 transCommand['Data']['Pad2'] = '\0' * (4 - offset % 4) 

4237 offset += (4 - offset % 4) 

4238 

4239 if len(data) > 0: 

4240 transCommand['Parameters']['DataOffset'] = offset 

4241 else: 

4242 transCommand['Parameters']['DataOffset'] = 0 

4243 

4244 transCommand['Parameters']['DataCount'] = len(data) 

4245 transCommand['Parameters']['ParameterCount'] = len(param) 

4246 transCommand['Data']['NT_Trans_Parameters'] = param 

4247 transCommand['Data']['NT_Trans_Data'] = data 

4248 smb_packet.addCommand(transCommand) 

4249 

4250 self.sendSMB(smb_packet) 

4251 

4252 def query_sec_info(self, tid, fid, additional_information=7): 

4253 """ 

4254 [MS-CIFS]: 2.2.7.6.1 

4255 NT_TRANSACT_QUERY_SECURITY_DESC 0x0006 

4256 :param tid: valid tree id. 

4257 :param fid: valid file handle. 

4258 :param additional_information: SecurityInfoFields. default = owner + group + dacl ie. 7 

4259 :return: security descriptor buffer 

4260 """ 

4261 self.send_nt_trans(tid, subcommand=0x0006, max_param_count=4, 

4262 param=pack('<HHL', fid, 0x0000, additional_information)) 

4263 resp = self.recvSMB() 

4264 if resp.isValidAnswer(SMB.SMB_COM_NT_TRANSACT): 

4265 nt_trans_response = SMBCommand(resp['Data'][0]) 

4266 nt_trans_parameters = SMBNTTransactionResponse_Parameters(nt_trans_response['Parameters']) 

4267 # Remove Potential Prefix Padding 

4268 return nt_trans_response['Data'][-nt_trans_parameters['TotalDataCount']:] 

4269 

4270 def echo(self, text = '', count = 1): 

4271 

4272 smb = NewSMBPacket() 

4273 comEcho = SMBCommand(SMB.SMB_COM_ECHO) 

4274 comEcho['Parameters'] = SMBEcho_Parameters() 

4275 comEcho['Data'] = SMBEcho_Data() 

4276 comEcho['Parameters']['EchoCount'] = count 

4277 comEcho['Data']['Data'] = text 

4278 smb.addCommand(comEcho) 

4279 

4280 self.sendSMB(smb) 

4281 

4282 for i in range(count): 

4283 resp = self.recvSMB() 

4284 resp.isValidAnswer(SMB.SMB_COM_ECHO) 

4285 return True 

4286 

4287ERRDOS = { 1: 'Invalid function', 

4288 2: 'File not found', 

4289 3: 'Invalid directory', 

4290 4: 'Too many open files', 

4291 5: 'Access denied', 

4292 6: 'Invalid file handle. Please file a bug report.', 

4293 7: 'Memory control blocks destroyed', 

4294 8: 'Out of memory', 

4295 9: 'Invalid memory block address', 

4296 10: 'Invalid environment', 

4297 11: 'Invalid format', 

4298 12: 'Invalid open mode', 

4299 13: 'Invalid data', 

4300 15: 'Invalid drive', 

4301 16: 'Attempt to remove server\'s current directory', 

4302 17: 'Not the same device', 

4303 18: 'No files found', 

4304 32: 'Sharing mode conflicts detected', 

4305 33: 'Lock request conflicts detected', 

4306 80: 'File already exists' 

4307 } 

4308 

4309ERRSRV = { 1: 'Non-specific error', 

4310 2: 'Bad password', 

4311 4: 'Access denied', 

4312 5: 'Invalid tid. Please file a bug report.', 

4313 6: 'Invalid network name', 

4314 7: 'Invalid device', 

4315 49: 'Print queue full', 

4316 50: 'Print queue full', 

4317 51: 'EOF on print queue dump', 

4318 52: 'Invalid print file handle', 

4319 64: 'Command not recognized. Please file a bug report.', 

4320 65: 'Internal server error', 

4321 67: 'Invalid path', 

4322 69: 'Invalid access permissions', 

4323 71: 'Invalid attribute mode', 

4324 81: 'Server is paused', 

4325 82: 'Not receiving messages', 

4326 83: 'No room to buffer messages', 

4327 87: 'Too many remote user names', 

4328 88: 'Operation timeout', 

4329 89: 'Out of resources', 

4330 91: 'Invalid user handle. Please file a bug report.', 

4331 250: 'Temporarily unable to support raw mode for transfer', 

4332 251: 'Temporarily unable to support raw mode for transfer', 

4333 252: 'Continue in MPX mode', 

4334 65535: 'Unsupported function' 

4335 } 

4336 

4337ERRHRD = { 19: 'Media is write-protected', 

4338 20: 'Unknown unit', 

4339 21: 'Drive not ready', 

4340 22: 'Unknown command', 

4341 23: 'CRC error', 

4342 24: 'Bad request', 

4343 25: 'Seek error', 

4344 26: 'Unknown media type', 

4345 27: 'Sector not found', 

4346 28: 'Printer out of paper', 

4347 29: 'Write fault', 

4348 30: 'Read fault', 

4349 31: 'General failure', 

4350 32: 'Open conflicts with an existing open', 

4351 33: 'Invalid lock request', 

4352 34: 'Wrong disk in drive', 

4353 35: 'FCBs not available', 

4354 36: 'Sharing buffer exceeded' 

4355 }