1 # Copyright (c) 2003-2016 CORE Security Technologies 2 # 3 # This software is provided under under a slightly modified version 4 # of the Apache Software License. See the accompanying LICENSE file 5 # for more information. 6 # 7 # Copyright (C) 2001 Michael Teo <michaelteo (at] bigfoot.com> 8 # smb.py - SMB/CIFS library 9 # 10 # This software is provided 'as-is', without any express or implied warranty. 11 # In no event will the author be held liable for any damages arising from the 12 # use of this software. 13 # 14 # Permission is granted to anyone to use this software for any purpose, 15 # including commercial applications, and to alter it and redistribute it 16 # freely, subject to the following restrictions: 17 # 18 # 1. The origin of this software must not be misrepresented; you must not 19 # claim that you wrote the original software. If you use this software 20 # in a product, an acknowledgment in the product documentation would be 21 # appreciated but is not required. 22 # 23 # 2. Altered source versions must be plainly marked as such, and must not be 24 # misrepresented as being the original software. 25 # 26 # 3. This notice cannot be removed or altered from any source distribution. 27 # 28 # Altered source done by Alberto Solino (@agsolino) 29 30 # Todo: 31 # [ ] Try [SMB]transport fragmentation using Transact requests 32 # [ ] Try other methods of doing write (write_raw, transact2, write, write_and_unlock, write_and_close, write_mpx) 33 # [-] Try replacements for SMB_COM_NT_CREATE_ANDX (CREATE, T_TRANSACT_CREATE, OPEN_ANDX works 34 # [x] Fix forceWriteAndx, which needs to send a RecvRequest, because recv() will not send it 35 # [x] Fix Recv() when using RecvAndx and the answer comes splet in several packets 36 # [ ] Try [SMB]transport fragmentation with overlaping segments 37 # [ ] Try [SMB]transport fragmentation with out of order segments 38 # [x] Do chained AndX requests 39 # [ ] Transform the rest of the calls to structure 40 # [X] Implement TRANS/TRANS2 reassembly for list_path 41 42 import os 43 import socket 44 import string 45 from binascii import a2b_hex 46 import datetime 47 from struct import pack, unpack 48 from contextlib import contextmanager 49 50 from impacket import nmb, ntlm, nt_errors, LOG 51 from impacket.structure import Structure 52 from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp 53 54 # For signing 55 import hashlib 56 57 unicode_support = 0 58 unicode_convert = 1 59 60 try: 61 from cStringIO import StringIO 62 except ImportError: 63 from StringIO import StringIO 64 65 # Dialect for SMB1 66 SMB_DIALECT = 'NT LM 0.12' 67 68 # Shared Device Type 69 SHARED_DISK = 0x00 70 SHARED_DISK_HIDDEN = 0x80000000 71 SHARED_PRINT_QUEUE = 0x01 72 SHARED_DEVICE = 0x02 73 SHARED_IPC = 0x03 74 75 # Extended attributes mask 76 ATTR_ARCHIVE = 0x020 77 ATTR_COMPRESSED = 0x800 78 ATTR_NORMAL = 0x080 79 ATTR_HIDDEN = 0x002 80 ATTR_READONLY = 0x001 81 ATTR_TEMPORARY = 0x100 82 ATTR_DIRECTORY = 0x010 83 ATTR_SYSTEM = 0x004 84 85 # Service Type 86 SERVICE_DISK = 'A:' 87 SERVICE_PRINTER = 'LPT1:' 88 SERVICE_IPC = 'IPC' 89 SERVICE_COMM = 'COMM' 90 SERVICE_ANY = '?????' 91 92 # Server Type (Can be used to mask with SMBMachine.get_type() or SMBDomain.get_type()) 93 SV_TYPE_WORKSTATION = 0x00000001 94 SV_TYPE_SERVER = 0x00000002 95 SV_TYPE_SQLSERVER = 0x00000004 96 SV_TYPE_DOMAIN_CTRL = 0x00000008 97 SV_TYPE_DOMAIN_BAKCTRL = 0x00000010 98 SV_TYPE_TIME_SOURCE = 0x00000020 99 SV_TYPE_AFP = 0x00000040 100 SV_TYPE_NOVELL = 0x00000080 101 SV_TYPE_DOMAIN_MEMBER = 0x00000100 102 SV_TYPE_PRINTQ_SERVER = 0x00000200 103 SV_TYPE_DIALIN_SERVER = 0x00000400 104 SV_TYPE_XENIX_SERVER = 0x00000800 105 SV_TYPE_NT = 0x00001000 106 SV_TYPE_WFW = 0x00002000 107 SV_TYPE_SERVER_NT = 0x00004000 108 SV_TYPE_POTENTIAL_BROWSER = 0x00010000 109 SV_TYPE_BACKUP_BROWSER = 0x00020000 110 SV_TYPE_MASTER_BROWSER = 0x00040000 111 SV_TYPE_DOMAIN_MASTER = 0x00080000 112 SV_TYPE_LOCAL_LIST_ONLY = 0x40000000 113 SV_TYPE_DOMAIN_ENUM = 0x80000000 114 115 # Options values for SMB.stor_file and SMB.retr_file 116 SMB_O_CREAT = 0x10 # Create the file if file does not exists. Otherwise, operation fails. 117 SMB_O_EXCL = 0x00 # When used with SMB_O_CREAT, operation fails if file exists. Cannot be used with SMB_O_OPEN. 118 SMB_O_OPEN = 0x01 # Open the file if the file exists 119 SMB_O_TRUNC = 0x02 # Truncate the file if the file exists 120 121 # Share Access Mode 122 SMB_SHARE_COMPAT = 0x00 123 SMB_SHARE_DENY_EXCL = 0x10 124 SMB_SHARE_DENY_WRITE = 0x20 125 SMB_SHARE_DENY_READEXEC = 0x30 126 SMB_SHARE_DENY_NONE = 0x40 127 SMB_ACCESS_READ = 0x00 128 SMB_ACCESS_WRITE = 0x01 129 SMB_ACCESS_READWRITE = 0x02 130 SMB_ACCESS_EXEC = 0x03 131 132 TRANS_DISCONNECT_TID = 1 133 TRANS_NO_RESPONSE = 2 134 135 STATUS_SUCCESS = 0x00000000 136 STATUS_LOGON_FAILURE = 0xC000006D 137 STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B 138 MAX_TFRAG_SIZE = 5840 139 EVASION_NONE = 0 140 EVASION_LOW = 1 141 EVASION_HIGH = 2 142 EVASION_MAX = 3 143 RPC_X_BAD_STUB_DATA = 0x6F7 144 145 # SMB_FILE_ATTRIBUTES 146 147 SMB_FILE_ATTRIBUTE_NORMAL = 0x0000 148 SMB_FILE_ATTRIBUTE_READONLY = 0x0001 149 SMB_FILE_ATTRIBUTE_HIDDEN = 0x0002 150 SMB_FILE_ATTRIBUTE_SYSTEM = 0x0004 151 SMB_FILE_ATTRIBUTE_VOLUME = 0x0008 152 SMB_FILE_ATTRIBUTE_DIRECTORY = 0x0010 153 SMB_FILE_ATTRIBUTE_ARCHIVE = 0x0020 154 SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100 155 SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200 156 SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400 157 SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000 158 SMB_SEARCH_ATTRIBUTE_ARCHIVE = 0x2000 159 160 # Session SetupAndX Action flags 161 SMB_SETUP_GUEST = 0x01 162 SMB_SETUP_USE_LANMAN_KEY = 0x02 163 164 # QUERY_INFORMATION levels 165 SMB_INFO_ALLOCATION = 0x0001 166 SMB_INFO_VOLUME = 0x0002 167 FILE_FS_SIZE_INFORMATION = 0x0003 168 SMB_QUERY_FS_VOLUME_INFO = 0x0102 169 SMB_QUERY_FS_SIZE_INFO = 0x0103 170 SMB_QUERY_FILE_EA_INFO = 0x0103 171 SMB_QUERY_FS_DEVICE_INFO = 0x0104 172 SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105 173 SMB_QUERY_FILE_BASIC_INFO = 0x0101 174 SMB_QUERY_FILE_STANDARD_INFO = 0x0102 175 SMB_QUERY_FILE_ALL_INFO = 0x0107 176 FILE_FS_FULL_SIZE_INFORMATION = 0x03EF 177 178 # SET_INFORMATION levels 179 SMB_SET_FILE_DISPOSITION_INFO = 0x0102 180 SMB_SET_FILE_BASIC_INFO = 0x0101 181 SMB_SET_FILE_END_OF_FILE_INFO = 0x0104 182 183 184 # File System Attributes 185 FILE_CASE_SENSITIVE_SEARCH = 0x00000001 186 FILE_CASE_PRESERVED_NAMES = 0x00000002 187 FILE_UNICODE_ON_DISK = 0x00000004 188 FILE_PERSISTENT_ACLS = 0x00000008 189 FILE_FILE_COMPRESSION = 0x00000010 190 FILE_VOLUME_IS_COMPRESSED = 0x00008000 191 192 # FIND_FIRST2 flags and levels 193 SMB_FIND_CLOSE_AFTER_REQUEST = 0x0001 194 SMB_FIND_CLOSE_AT_EOS = 0x0002 195 SMB_FIND_RETURN_RESUME_KEYS = 0x0004 196 SMB_FIND_CONTINUE_FROM_LAST = 0x0008 197 SMB_FIND_WITH_BACKUP_INTENT = 0x0010 198 199 FILE_DIRECTORY_FILE = 0x00000001 200 FILE_DELETE_ON_CLOSE = 0x00001000 201 FILE_NON_DIRECTORY_FILE = 0x00000040 202 203 SMB_FIND_INFO_STANDARD = 0x0001 204 SMB_FIND_FILE_DIRECTORY_INFO = 0x0101 205 SMB_FIND_FILE_FULL_DIRECTORY_INFO= 0x0102 206 SMB_FIND_FILE_NAMES_INFO = 0x0103 207 SMB_FIND_FILE_BOTH_DIRECTORY_INFO= 0x0104 208 SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO = 0x105 209 SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO = 0x106 210 211 212 # DesiredAccess flags 213 FILE_READ_DATA = 0x00000001 214 FILE_WRITE_DATA = 0x00000002 215 FILE_APPEND_DATA = 0x00000004 216 FILE_EXECUTE = 0x00000020 217 MAXIMUM_ALLOWED = 0x02000000 218 GENERIC_ALL = 0x10000000 219 GENERIC_EXECUTE = 0x20000000 220 GENERIC_WRITE = 0x40000000 221 GENERIC_READ = 0x80000000 222 223 # ShareAccess flags 224 FILE_SHARE_NONE = 0x00000000 225 FILE_SHARE_READ = 0x00000001 226 FILE_SHARE_WRITE = 0x00000002 227 FILE_SHARE_DELETE = 0x00000004 228 229 # CreateDisposition flags 230 FILE_SUPERSEDE = 0x00000000 231 FILE_OPEN = 0x00000001 232 FILE_CREATE = 0x00000002 233 FILE_OPEN_IF = 0x00000003 234 FILE_OVERWRITE = 0x00000004 235 FILE_OVERWRITE_IF = 0x00000005 236 237 def strerror(errclass, errcode): 238 if errclass == 0x01: 239 return 'OS error', ERRDOS.get(errcode, 'Unknown error') 240 elif errclass == 0x02: 241 return 'Server error', ERRSRV.get(errcode, 'Unknown error') 242 elif errclass == 0x03: 243 return 'Hardware error', ERRHRD.get(errcode, 'Unknown error') 244 # This is not a standard error class for SMB 245 #elif errclass == 0x80: 246 # return 'Browse error', ERRBROWSE.get(errcode, 'Unknown error') 247 elif errclass == 0xff: 248 return 'Bad command', 'Bad command. Please file bug report' 249 else: 250 return 'Unknown error', 'Unknown error' 251 252 # Raised when an error has occured during a session 253 class SessionError(Exception): 254 # SMB X/Open error codes for the ERRDOS error class 255 ERRsuccess = 0 256 ERRbadfunc = 1 257 ERRbadfile = 2 258 ERRbadpath = 3 259 ERRnofids = 4 260 ERRnoaccess = 5 261 ERRbadfid = 6 262 ERRbadmcb = 7 263 ERRnomem = 8 264 ERRbadmem = 9 265 ERRbadenv = 10 266 ERRbadaccess = 12 267 ERRbaddata = 13 268 ERRres = 14 269 ERRbaddrive = 15 270 ERRremcd = 16 271 ERRdiffdevice = 17 272 ERRnofiles = 18 273 ERRgeneral = 31 274 ERRbadshare = 32 275 ERRlock = 33 276 ERRunsup = 50 277 ERRnetnamedel = 64 278 ERRnosuchshare = 67 279 ERRfilexists = 80 280 ERRinvalidparam = 87 281 ERRcannotopen = 110 282 ERRinsufficientbuffer = 122 283 ERRinvalidname = 123 284 ERRunknownlevel = 124 285 ERRnotlocked = 158 286 ERRrename = 183 287 ERRbadpipe = 230 288 ERRpipebusy = 231 289 ERRpipeclosing = 232 290 ERRnotconnected = 233 291 ERRmoredata = 234 292 ERRnomoreitems = 259 293 ERRbaddirectory = 267 294 ERReasnotsupported = 282 295 ERRlogonfailure = 1326 296 ERRbuftoosmall = 2123 297 ERRunknownipc = 2142 298 ERRnosuchprintjob = 2151 299 ERRinvgroup = 2455 300 301 # here's a special one from observing NT 302 ERRnoipc = 66 303 304 # These errors seem to be only returned by the NT printer driver system 305 ERRdriveralreadyinstalled = 1795 306 ERRunknownprinterport = 1796 307 ERRunknownprinterdriver = 1797 308 ERRunknownprintprocessor = 1798 309 ERRinvalidseparatorfile = 1799 310 ERRinvalidjobpriority = 1800 311 ERRinvalidprintername = 1801 312 ERRprinteralreadyexists = 1802 313 ERRinvalidprintercommand = 1803 314 ERRinvaliddatatype = 1804 315 ERRinvalidenvironment = 1805 316 317 ERRunknownprintmonitor = 3000 318 ERRprinterdriverinuse = 3001 319 ERRspoolfilenotfound = 3002 320 ERRnostartdoc = 3003 321 ERRnoaddjob = 3004 322 ERRprintprocessoralreadyinstalled = 3005 323 ERRprintmonitoralreadyinstalled = 3006 324 ERRinvalidprintmonitor = 3007 325 ERRprintmonitorinuse = 3008 326 ERRprinterhasjobsqueued = 3009 327 328 # Error codes for the ERRSRV class 329 330 ERRerror = 1 331 ERRbadpw = 2 332 ERRbadtype = 3 333 ERRaccess = 4 334 ERRinvnid = 5 335 ERRinvnetname = 6 336 ERRinvdevice = 7 337 ERRqfull = 49 338 ERRqtoobig = 50 339 ERRinvpfid = 52 340 ERRsmbcmd = 64 341 ERRsrverror = 65 342 ERRfilespecs = 67 343 ERRbadlink = 68 344 ERRbadpermits = 69 345 ERRbadpid = 70 346 ERRsetattrmode = 71 347 ERRpaused = 81 348 ERRmsgoff = 82 349 ERRnoroom = 83 350 ERRrmuns = 87 351 ERRtimeout = 88 352 ERRnoresource = 89 353 ERRtoomanyuids = 90 354 ERRbaduid = 91 355 ERRuseMPX = 250 356 ERRuseSTD = 251 357 ERRcontMPX = 252 358 ERRbadPW = None 359 ERRnosupport = 0 360 ERRunknownsmb = 22 361 362 # Error codes for the ERRHRD class 363 364 ERRnowrite = 19 365 ERRbadunit = 20 366 ERRnotready = 21 367 ERRbadcmd = 22 368 ERRdata = 23 369 ERRbadreq = 24 370 ERRseek = 25 371 ERRbadmedia = 26 372 ERRbadsector = 27 373 ERRnopaper = 28 374 ERRwrite = 29 375 ERRread = 30 376 ERRwrongdisk = 34 377 ERRFCBunavail = 35 378 ERRsharebufexc = 36 379 ERRdiskfull = 39 380 381 382 hard_msgs = { 383 19: ("ERRnowrite", "Attempt to write on write-protected diskette."), 384 20: ("ERRbadunit", "Unknown unit."), 385 21: ("ERRnotready", "Drive not ready."), 386 22: ("ERRbadcmd", "Unknown command."), 387 23: ("ERRdata", "Data error (CRC)."), 388 24: ("ERRbadreq", "Bad request structure length."), 389 25: ("ERRseek", "Seek error."), 390 26: ("ERRbadmedia", "Unknown media type."), 391 27: ("ERRbadsector", "Sector not found."), 392 28: ("ERRnopaper", "Printer out of paper."), 393 29: ("ERRwrite", "Write fault."), 394 30: ("ERRread", "Read fault."), 395 31: ("ERRgeneral", "General failure."), 396 32: ("ERRbadshare", "An open conflicts with an existing open."), 397 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."), 398 34: ("ERRwrongdisk", "The wrong disk was found in a drive."), 399 35: ("ERRFCBUnavail", "No FCBs are available to process request."), 400 36: ("ERRsharebufexc", "A sharing buffer has been exceeded.") 401 } 402 403 dos_msgs = { 404 ERRbadfunc: ("ERRbadfunc", "Invalid function."), 405 ERRbadfile: ("ERRbadfile", "File not found."), 406 ERRbadpath: ("ERRbadpath", "Directory invalid."), 407 ERRnofids: ("ERRnofids", "No file descriptors available"), 408 ERRnoaccess: ("ERRnoaccess", "Access denied."), 409 ERRbadfid: ("ERRbadfid", "Invalid file handle."), 410 ERRbadmcb: ("ERRbadmcb", "Memory control blocks destroyed."), 411 ERRnomem: ("ERRnomem", "Insufficient server memory to perform the requested function."), 412 ERRbadmem: ("ERRbadmem", "Invalid memory block address."), 413 ERRbadenv: ("ERRbadenv", "Invalid environment."), 414 11: ("ERRbadformat", "Invalid format."), 415 ERRbadaccess: ("ERRbadaccess", "Invalid open mode."), 416 ERRbaddata: ("ERRbaddata", "Invalid data."), 417 ERRres: ("ERRres", "reserved."), 418 ERRbaddrive: ("ERRbaddrive", "Invalid drive specified."), 419 ERRremcd: ("ERRremcd", "A Delete Directory request attempted to remove the server's current directory."), 420 ERRdiffdevice: ("ERRdiffdevice", "Not same device."), 421 ERRnofiles: ("ERRnofiles", "A File Search command can find no more files matching the specified criteria."), 422 ERRbadshare: ("ERRbadshare", "The sharing mode specified for an Open conflicts with existing FIDs on the file."), 423 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."), 424 ERRunsup: ("ERRunsup", "The operation is unsupported"), 425 ERRnosuchshare: ("ERRnosuchshare", "You specified an invalid share name"), 426 ERRfilexists: ("ERRfilexists", "The file named in a Create Directory, Make New File or Link request already exists."), 427 ERRinvalidname: ("ERRinvalidname", "Invalid name"), 428 ERRbadpipe: ("ERRbadpipe", "Pipe invalid."), 429 ERRpipebusy: ("ERRpipebusy", "All instances of the requested pipe are busy."), 430 ERRpipeclosing: ("ERRpipeclosing", "Pipe close in progress."), 431 ERRnotconnected: ("ERRnotconnected", "No process on other end of pipe."), 432 ERRmoredata: ("ERRmoredata", "There is more data to be returned."), 433 ERRinvgroup: ("ERRinvgroup", "Invalid workgroup (try the -W option)"), 434 ERRlogonfailure: ("ERRlogonfailure", "Logon failure"), 435 ERRdiskfull: ("ERRdiskfull", "Disk full"), 436 ERRgeneral: ("ERRgeneral", "General failure"), 437 ERRunknownlevel: ("ERRunknownlevel", "Unknown info level") 438 } 439 440 server_msgs = { 441 1: ("ERRerror", "Non-specific error code."), 442 2: ("ERRbadpw", "Bad password - name/password pair in a Tree Connect or Session Setup are invalid."), 443 3: ("ERRbadtype", "reserved."), 444 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."), 445 5: ("ERRinvnid", "The tree ID (TID) specified in a command was invalid."), 446 6: ("ERRinvnetname", "Invalid network name in tree connect."), 447 7: ("ERRinvdevice", "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."), 448 49: ("ERRqfull", "Print queue full (files) -- returned by open print file."), 449 50: ("ERRqtoobig", "Print queue full -- no space."), 450 51: ("ERRqeof", "EOF on print queue dump."), 451 52: ("ERRinvpfid", "Invalid print file FID."), 452 64: ("ERRsmbcmd", "The server did not recognize the command received."), 453 65: ("ERRsrverror","The server encountered an internal error, e.g., system file unavailable."), 454 67: ("ERRfilespecs", "The file handle (FID) and pathname parameters contained an invalid combination of values."), 455 68: ("ERRreserved", "reserved."), 456 69: ("ERRbadpermits", "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."), 457 70: ("ERRreserved", "reserved."), 458 71: ("ERRsetattrmode", "The attribute mode in the Set File Attribute request is invalid."), 459 81: ("ERRpaused", "Server is paused."), 460 82: ("ERRmsgoff", "Not receiving messages."), 461 83: ("ERRnoroom", "No room to buffer message."), 462 87: ("ERRrmuns", "Too many remote user names."), 463 88: ("ERRtimeout", "Operation timed out."), 464 89: ("ERRnoresource", "No resources currently available for request."), 465 90: ("ERRtoomanyuids", "Too many UIDs active on this session."), 466 91: ("ERRbaduid", "The UID is not known as a valid ID on this session."), 467 250: ("ERRusempx","Temp unable to support Raw, use MPX mode."), 468 251: ("ERRusestd","Temp unable to support Raw, use standard read/write."), 469 252: ("ERRcontmpx", "Continue in MPX mode."), 470 253: ("ERRreserved", "reserved."), 471 254: ("ERRreserved", "reserved."), 472 0xFFFF: ("ERRnosupport", "Function not supported.") 473 } 474 # Error clases 475 476 ERRDOS = 0x1 477 error_classes = { 0: ("SUCCESS", {}), 478 ERRDOS: ("ERRDOS", dos_msgs), 479 0x02: ("ERRSRV",server_msgs), 480 0x03: ("ERRHRD",hard_msgs), 481 0x04: ("ERRXOS", {} ), 482 0xE1: ("ERRRMX1", {} ), 483 0xE2: ("ERRRMX2", {} ), 484 0xE3: ("ERRRMX3", {} ), 485 0xFF: ("ERRCMD", {} ) } 486 487 488 489 def __init__( self, error_string, error_class, error_code, nt_status = 0): 490 Exception.__init__(self, error_string) 491 self.nt_status = nt_status 492 self._args = error_string 493 if nt_status: 494 self.error_class = 0 495 self.error_code = (error_code << 16) + error_class 496 else: 497 self.error_class = error_class 498 self.error_code = error_code 499 500 501 def get_error_class( self ): 502 return self.error_class 503 504 def get_error_code( self ): 505 return self.error_code 506 507 def __str__( self ): 508 error_class = SessionError.error_classes.get( self.error_class, None ) 509 if not error_class: 510 error_code_str = self.error_code 511 error_class_str = self.error_class 512 else: 513 error_class_str = error_class[0] 514 error_code = error_class[1].get( self.error_code, None ) 515 if not error_code: 516 error_code_str = self.error_code 517 else: 518 error_code_str = '%s(%s)' % error_code 519 520 if self.nt_status: 521 return 'SMB SessionError: %s(%s)' % nt_errors.ERROR_MESSAGES[self.error_code] 522 else: 523 # Fall back to the old format 524 return 'SMB SessionError: class: %s, code: %s' % (error_class_str, error_code_str) 525 526 527 # Raised when an supported feature is present/required in the protocol but is not 528 # currently supported by pysmb 529 class UnsupportedFeature(Exception): pass 530 531 # Contains information about a SMB shared device/service 532 class SharedDevice: 533 def __init__(self, name, share_type, comment): 534 self.__name = name 535 self.__type = share_type 536 self.__comment = comment 537 538 def get_name(self): 539 return self.__name 540 541 def get_type(self): 542 return self.__type 543 544 def get_comment(self): 545 return self.__comment 546 547 def __repr__(self): 548 return '<SharedDevice instance: name=' + self.__name + ', type=' + str(self.__type) + ', comment="' + self.__comment + '">' 549 550 551 # Contains information about the shared file/directory 552 class SharedFile: 553 def __init__(self, ctime, atime, mtime, filesize, allocsize, attribs, shortname, longname): 554 self.__ctime = ctime 555 self.__atime = atime 556 self.__mtime = mtime 557 self.__filesize = filesize 558 self.__allocsize = allocsize 559 self.__attribs = attribs 560 try: 561 self.__shortname = shortname[:string.index(shortname, '\0')] 562 except ValueError: 563 self.__shortname = shortname 564 try: 565 self.__longname = longname[:string.index(longname, '\0')] 566 except ValueError: 567 self.__longname = longname 568 569 def get_ctime(self): 570 return self.__ctime 571 572 def get_ctime_epoch(self): 573 return self.__convert_smbtime(self.__ctime) 574 575 def get_mtime(self): 576 return self.__mtime 577 578 def get_mtime_epoch(self): 579 return self.__convert_smbtime(self.__mtime) 580 581 def get_atime(self): 582 return self.__atime 583 584 def get_atime_epoch(self): 585 return self.__convert_smbtime(self.__atime) 586 587 def get_filesize(self): 588 return self.__filesize 589 590 def get_allocsize(self): 591 return self.__allocsize 592 593 def get_attributes(self): 594 return self.__attribs 595 596 def is_archive(self): 597 return self.__attribs & ATTR_ARCHIVE 598 599 def is_compressed(self): 600 return self.__attribs & ATTR_COMPRESSED 601 602 def is_normal(self): 603 return self.__attribs & ATTR_NORMAL 604 605 def is_hidden(self): 606 return self.__attribs & ATTR_HIDDEN 607 608 def is_readonly(self): 609 return self.__attribs & ATTR_READONLY 610 611 def is_temporary(self): 612 return self.__attribs & ATTR_TEMPORARY 613 614 def is_directory(self): 615 return self.__attribs & ATTR_DIRECTORY 616 617 def is_system(self): 618 return self.__attribs & ATTR_SYSTEM 619 620 def get_shortname(self): 621 return self.__shortname 622 623 def get_longname(self): 624 return self.__longname 625 626 def __repr__(self): 627 return '<SharedFile instance: shortname="' + self.__shortname + '", longname="' + self.__longname + '", filesize=' + str(self.__filesize) + '>' 628 629 @staticmethod 630 def __convert_smbtime(t): 631 x = t >> 32 632 y = t & 0xffffffffL 633 geo_cal_offset = 11644473600.0 # = 369.0 * 365.25 * 24 * 60 * 60 - (3.0 * 24 * 60 * 60 + 6.0 * 60 * 60) 634 return (x * 4.0 * (1 << 30) + (y & 0xfff00000L)) * 1.0e-7 - geo_cal_offset 635 636 637 # Contain information about a SMB machine 638 class SMBMachine: 639 def __init__(self, nbname, nbt_type, comment): 640 self.__nbname = nbname 641 self.__type = nbt_type 642 self.__comment = comment 643 644 def __repr__(self): 645 return '<SMBMachine instance: nbname="' + self.__nbname + '", type=' + hex(self.__type) + ', comment="' + self.__comment + '">' 646 647 class SMBDomain: 648 def __init__(self, nbgroup, domain_type, master_browser): 649 self.__nbgroup = nbgroup 650 self.__type = domain_type 651 self.__master_browser = master_browser 652 653 def __repr__(self): 654 return '<SMBDomain instance: nbgroup="' + self.__nbgroup + '", type=' + hex(self.__type) + ', master browser="' + self.__master_browser + '">' 655 656 # Represents a SMB Packet 657 class NewSMBPacket(Structure): 658 structure = ( 659 ('Signature', '"\xffSMB'), 660 ('Command','B=0'), 661 ('ErrorClass','B=0'), 662 ('_reserved','B=0'), 663 ('ErrorCode','<H=0'), 664 ('Flags1','B=0'), 665 ('Flags2','<H=0'), 666 ('PIDHigh','<H=0'), 667 ('SecurityFeatures','8s=""'), 668 ('Reserved','<H=0'), 669 ('Tid','<H=0xffff'), 670 ('Pid','<H=0'), 671 ('Uid','<H=0'), 672 ('Mid','<H=0'), 673 ('Data','*:'), 674 ) 675 676 def __init__(self, **kargs): 677 Structure.__init__(self, **kargs) 678 679 if self.fields.has_key('Flags2') is False: 680 self['Flags2'] = 0 681 if self.fields.has_key('Flags1') is False: 682 self['Flags1'] = 0 683 684 if not kargs.has_key('data'): 685 self['Data'] = [] 686 687 def addCommand(self, command): 688 if len(self['Data']) == 0: 689 self['Command'] = command.command 690 else: 691 self['Data'][-1]['Parameters']['AndXCommand'] = command.command 692 self['Data'][-1]['Parameters']['AndXOffset'] = len(self) 693 self['Data'].append(command) 694 695 def isMoreData(self): 696 return (self['Command'] in [SMB.SMB_COM_TRANSACTION, SMB.SMB_COM_READ_ANDX, SMB.SMB_COM_READ_RAW] and 697 self['ErrorClass'] == 1 and self['ErrorCode'] == SessionError.ERRmoredata) 698 699 def isMoreProcessingRequired(self): 700 return self['ErrorClass'] == 0x16 and self['ErrorCode'] == 0xc000 701 702 def isValidAnswer(self, cmd): 703 # this was inside a loop reading more from the net (with recv_packet(None)) 704 if self['Command'] == cmd: 705 if (self['ErrorClass'] == 0x00 and 706 self['ErrorCode'] == 0x00): 707 return 1 708 elif self.isMoreData(): 709 return 1 710 elif self.isMoreProcessingRequired(): 711 return 1 712 raise SessionError, ("SMB Library Error", self['ErrorClass'] + (self['_reserved'] << 8), self['ErrorCode'], self['Flags2'] & SMB.FLAGS2_NT_STATUS) 713 else: 714 raise UnsupportedFeature, ("Unexpected answer from server: Got %d, Expected %d" % (self['Command'], cmd)) 715 716 717 class SMBCommand(Structure): 718 structure = ( 719 ('WordCount', 'B=len(Parameters)/2'), 720 ('_ParametersLength','_-Parameters','WordCount*2'), 721 ('Parameters',':'), # default set by constructor 722 ('ByteCount','<H-Data'), 723 ('Data',':'), # default set by constructor 724 ) 725 726 def __init__(self, commandOrData = None, data = None, **kargs): 727 if type(commandOrData) == type(0): 728 self.command = commandOrData 729 else: 730 data = data or commandOrData 731 732 Structure.__init__(self, data = data, **kargs) 733 734 if data is None: 735 self['Parameters'] = '' 736 self['Data'] = '' 737 738 class AsciiOrUnicodeStructure(Structure): 739 UnicodeStructure = () 740 AsciiStructure = () 741 def __init__(self, flags = 0, **kargs): 742 if flags & SMB.FLAGS2_UNICODE: 743 self.structure = self.UnicodeStructure 744 else: 745 self.structure = self.AsciiStructure 746 Structure.__init__(self, **kargs) 747 748 class SMBCommand_Parameters(Structure): 749 pass 750 751 class SMBAndXCommand_Parameters(Structure): 752 commonHdr = ( 753 ('AndXCommand','B=0xff'), 754 ('_reserved','B=0'), 755 ('AndXOffset','<H=0'), 756 ) 757 structure = ( # default structure, overriden by subclasses 758 ('Data',':=""'), 759 ) 760 761 ############# TRANSACTIONS RELATED 762 # TRANS2_QUERY_FS_INFORMATION 763 # QUERY_FS Information Levels 764 # SMB_QUERY_FS_ATTRIBUTE_INFO 765 class SMBQueryFsAttributeInfo(Structure): 766 structure = ( 767 ('FileSystemAttributes','<L'), 768 ('MaxFilenNameLengthInBytes','<L'), 769 ('LengthOfFileSystemName','<L-FileSystemName'), 770 ('FileSystemName',':'), 771 ) 772 773 class SMBQueryFsInfoVolume(AsciiOrUnicodeStructure): 774 commonHdr = ( 775 ('ulVolSerialNbr','<L=0xABCDEFAA'), 776 ('cCharCount','<B-VolumeLabel'), 777 ) 778 AsciiStructure = ( 779 ('VolumeLabel','z'), 780 ) 781 UnicodeStructure = ( 782 ('VolumeLabel','u'), 783 ) 784 785 # FILE_FS_SIZE_INFORMATION 786 class FileFsSizeInformation(Structure): 787 structure = ( 788 ('TotalAllocationUnits','<q=148529400'), 789 ('AvailableAllocationUnits','<q=14851044'), 790 ('SectorsPerAllocationUnit','<L=2'), 791 ('BytesPerSector','<L=512'), 792 ) 793 794 # SMB_QUERY_FS_SIZE_INFO 795 class SMBQueryFsSizeInfo(Structure): 796 structure = ( 797 ('TotalAllocationUnits','<q=148529400'), 798 ('TotalFreeAllocationUnits','<q=14851044'), 799 ('SectorsPerAllocationUnit','<L=2'), 800 ('BytesPerSector','<L=512'), 801 ) 802 # FILE_FS_FULL_SIZE_INFORMATION 803 class SMBFileFsFullSizeInformation(Structure): 804 structure = ( 805 ('TotalAllocationUnits','<q=148529400'), 806 ('CallerAvailableAllocationUnits','<q=148529400'), 807 ('ActualAvailableAllocationUnits','<q=148529400'), 808 ('SectorsPerAllocationUnit','<L=15'), 809 ('BytesPerSector','<L=512') 810 ) 811 # SMB_QUERY_FS_VOLUME_INFO 812 class SMBQueryFsVolumeInfo(Structure): 813 structure = ( 814 ('VolumeCreationTime','<q'), 815 ('SerialNumber','<L=0xABCDEFAA'), 816 ('VolumeLabelSize','<L=len(VolumeLabel)'), 817 ('Reserved','<H=0x10'), 818 ('VolumeLabel',':') 819 ) 820 # SMB_FIND_FILE_BOTH_DIRECTORY_INFO level 821 class SMBFindFileBothDirectoryInfo(AsciiOrUnicodeStructure): 822 commonHdr = ( 823 ('NextEntryOffset','<L=0'), 824 ('FileIndex','<L=0'), 825 ('CreationTime','<q'), 826 ('LastAccessTime','<q'), 827 ('LastWriteTime','<q'), 828 ('LastChangeTime','<q'), 829 ('EndOfFile','<q=0'), 830 ('AllocationSize','<q=0'), 831 ('ExtFileAttributes','<L=0'), 832 ) 833 AsciiStructure = ( 834 ('FileNameLength','<L-FileName','len(FileName)'), 835 ('EaSize','<L=0'), 836 ('ShortNameLength','<B=0'), 837 ('Reserved','<B=0'), 838 ('ShortName','24s'), 839 ('FileName',':'), 840 ) 841 UnicodeStructure = ( 842 ('FileNameLength','<L-FileName','len(FileName)*2'), 843 ('EaSize','<L=0'), 844 ('ShortNameLength','<B=0'), 845 ('Reserved','<B=0'), 846 ('ShortName','24s'), 847 ('FileName',':'), 848 ) 849 850 # SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO level 851 class SMBFindFileIdFullDirectoryInfo(AsciiOrUnicodeStructure): 852 commonHdr = ( 853 ('NextEntryOffset','<L=0'), 854 ('FileIndex','<L=0'), 855 ('CreationTime','<q'), 856 ('LastAccessTime','<q'), 857 ('LastWriteTime','<q'), 858 ('LastChangeTime','<q'), 859 ('EndOfFile','<q=0'), 860 ('AllocationSize','<q=0'), 861 ('ExtFileAttributes','<L=0'), 862 ) 863 AsciiStructure = ( 864 ('FileNameLength','<L-FileName','len(FileName)'), 865 ('EaSize','<L=0'), 866 ('FileID','<q=0'), 867 ('FileName',':'), 868 ) 869 UnicodeStructure = ( 870 ('FileNameLength','<L-FileName','len(FileName)*2'), 871 ('EaSize','<L=0'), 872 ('FileID','<q=0'), 873 ('FileName',':'), 874 ) 875 876 # SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO level 877 class SMBFindFileIdBothDirectoryInfo(AsciiOrUnicodeStructure): 878 commonHdr = ( 879 ('NextEntryOffset','<L=0'), 880 ('FileIndex','<L=0'), 881 ('CreationTime','<q'), 882 ('LastAccessTime','<q'), 883 ('LastWriteTime','<q'), 884 ('LastChangeTime','<q'), 885 ('EndOfFile','<q=0'), 886 ('AllocationSize','<q=0'), 887 ('ExtFileAttributes','<L=0'), 888 ) 889 AsciiStructure = ( 890 ('FileNameLength','<L-FileName','len(FileName)'), 891 ('EaSize','<L=0'), 892 ('ShortNameLength','<B=0'), 893 ('Reserved','<B=0'), 894 ('ShortName','24s'), 895 ('Reserved','<H=0'), 896 ('FileID','<q=0'), 897 ('FileName','z'), 898 ) 899 UnicodeStructure = ( 900 ('FileNameLength','<L-FileName','len(FileName)*2'), 901 ('EaSize','<L=0'), 902 ('ShortNameLength','<B=0'), 903 ('Reserved','<B=0'), 904 ('ShortName','24s'), 905 ('Reserved','<H=0'), 906 ('FileID','<q=0'), 907 ('FileName',':'), 908 ) 909 910 # SMB_FIND_FILE_DIRECTORY_INFO level 911 class SMBFindFileDirectoryInfo(AsciiOrUnicodeStructure): 912 commonHdr = ( 913 ('NextEntryOffset','<L=0'), 914 ('FileIndex','<L=0'), 915 ('CreationTime','<q'), 916 ('LastAccessTime','<q'), 917 ('LastWriteTime','<q'), 918 ('LastChangeTime','<q'), 919 ('EndOfFile','<q=0'), 920 ('AllocationSize','<q=1'), 921 ('ExtFileAttributes','<L=0'), 922 ) 923 AsciiStructure = ( 924 ('FileNameLength','<L-FileName','len(FileName)'), 925 ('FileName','z'), 926 ) 927 UnicodeStructure = ( 928 ('FileNameLength','<L-FileName','len(FileName)*2'), 929 ('FileName',':'), 930 ) 931 932 # SMB_FIND_FILE_NAMES_INFO level 933 class SMBFindFileNamesInfo(AsciiOrUnicodeStructure): 934 commonHdr = ( 935 ('NextEntryOffset','<L=0'), 936 ('FileIndex','<L=0'), 937 ) 938 AsciiStructure = ( 939 ('FileNameLength','<L-FileName','len(FileName)'), 940 ('FileName','z'), 941 ) 942 UnicodeStructure = ( 943 ('FileNameLength','<L-FileName','len(FileName)*2'), 944 ('FileName',':'), 945 ) 946 947 # SMB_FIND_FILE_FULL_DIRECTORY_INFO level 948 class SMBFindFileFullDirectoryInfo(AsciiOrUnicodeStructure): 949 commonHdr = ( 950 ('NextEntryOffset','<L=0'), 951 ('FileIndex','<L=0'), 952 ('CreationTime','<q'), 953 ('LastAccessTime','<q'), 954 ('LastWriteTime','<q'), 955 ('LastChangeTime','<q'), 956 ('EndOfFile','<q=0'), 957 ('AllocationSize','<q=1'), 958 ('ExtFileAttributes','<L=0'), 959 ) 960 AsciiStructure = ( 961 ('FileNameLength','<L-FileName','len(FileName)'), 962 ('EaSize','<L'), 963 ('FileName','z'), 964 ) 965 UnicodeStructure = ( 966 ('FileNameLength','<L-FileName','len(FileName)*2'), 967 ('EaSize','<L'), 968 ('FileName',':'), 969 ) 970 971 # SMB_FIND_INFO_STANDARD level 972 class SMBFindInfoStandard(AsciiOrUnicodeStructure): 973 commonHdr = ( 974 ('ResumeKey','<L=0xff'), 975 ('CreationDate','<H=0'), 976 ('CreationTime','<H=0'), 977 ('LastAccessDate','<H=0'), 978 ('LastAccessTime','<H=0'), 979 ('LastWriteDate','<H=0'), 980 ('LastWriteTime','<H=0'), 981 ('EaSize','<L'), 982 ('AllocationSize','<L=1'), 983 ('ExtFileAttributes','<H=0'), 984 ) 985 AsciiStructure = ( 986 ('FileNameLength','<B-FileName','len(FileName)'), 987 ('FileName','z'), 988 ) 989 UnicodeStructure = ( 990 ('FileNameLength','<B-FileName','len(FileName)*2'), 991 ('FileName',':'), 992 ) 993 994 # SET_FILE_INFORMATION structures 995 # SMB_SET_FILE_DISPOSITION_INFO 996 class SMBSetFileDispositionInfo(Structure): 997 structure = ( 998 ('DeletePending','<B'), 999 ) 1000 1001 # SMB_SET_FILE_BASIC_INFO 1002 class SMBSetFileBasicInfo(Structure): 1003 structure = ( 1004 ('CreationTime','<q'), 1005 ('LastAccessTime','<q'), 1006 ('LastWriteTime','<q'), 1007 ('ChangeTime','<q'), 1008 ('ExtFileAttributes','<H'), 1009 ('Reserved','<L'), 1010 ) 1011 1012 # FILE_STREAM_INFORMATION 1013 class SMBFileStreamInformation(Structure): 1014 commonHdr = ( 1015 ('NextEntryOffset','<L=0'), 1016 ('StreamNameLength','<L=0'), 1017 ('StreamSize','<q=0'), 1018 ('StreamAllocationSize','<q=0'), 1019 ('StreamName',':=""'), 1020 ) 1021 1022 # FILE_NETWORK_OPEN_INFORMATION 1023 class SMBFileNetworkOpenInfo(Structure): 1024 structure = ( 1025 ('CreationTime','<q=0'), 1026 ('LastAccessTime','<q=0'), 1027 ('LastWriteTime','<q=0'), 1028 ('ChangeTime','<q=0'), 1029 ('AllocationSize','<q=0'), 1030 ('EndOfFile','<q=0'), 1031 ('FileAttributes','<L=0'), 1032 ('Reserved','<L=0'), 1033 ) 1034 1035 # SMB_SET_FILE_END_OF_FILE_INFO 1036 class SMBSetFileEndOfFileInfo(Structure): 1037 structure = ( 1038 ('EndOfFile','<q'), 1039 ) 1040 1041 # TRANS2_FIND_NEXT2 1042 class SMBFindNext2_Parameters(AsciiOrUnicodeStructure): 1043 commonHdr = ( 1044 ('SID','<H'), 1045 ('SearchCount','<H'), 1046 ('InformationLevel','<H'), 1047 ('ResumeKey','<L'), 1048 ('Flags','<H'), 1049 ) 1050 AsciiStructure = ( 1051 ('FileName','z'), 1052 ) 1053 UnicodeStructure = ( 1054 ('FileName','u'), 1055 ) 1056 1057 class SMBFindNext2Response_Parameters(Structure): 1058 structure = ( 1059 ('SearchCount','<H'), 1060 ('EndOfSearch','<H=1'), 1061 ('EaErrorOffset','<H=0'), 1062 ('LastNameOffset','<H=0'), 1063 ) 1064 1065 class SMBFindNext2_Data(Structure): 1066 structure = ( 1067 ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'), 1068 ('GetExtendedAttributesList',':'), 1069 ) 1070 1071 1072 # TRANS2_FIND_FIRST2 1073 class SMBFindFirst2Response_Parameters(Structure): 1074 structure = ( 1075 ('SID','<H'), 1076 ('SearchCount','<H'), 1077 ('EndOfSearch','<H=1'), 1078 ('EaErrorOffset','<H=0'), 1079 ('LastNameOffset','<H=0'), 1080 ) 1081 1082 class SMBFindFirst2_Parameters(AsciiOrUnicodeStructure): 1083 commonHdr = ( 1084 ('SearchAttributes','<H'), 1085 ('SearchCount','<H'), 1086 ('Flags','<H'), 1087 ('InformationLevel','<H'), 1088 ('SearchStorageType','<L'), 1089 ) 1090 AsciiStructure = ( 1091 ('FileName','z'), 1092 ) 1093 UnicodeStructure = ( 1094 ('FileName','u'), 1095 ) 1096 1097 class SMBFindFirst2_Data(Structure): 1098 structure = ( 1099 ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'), 1100 ('GetExtendedAttributesList',':'), 1101 ) 1102 1103 # TRANS2_SET_PATH_INFORMATION 1104 class SMBSetPathInformation_Parameters(AsciiOrUnicodeStructure): 1105 commonHdr = ( 1106 ('InformationLevel','<H'), 1107 ('Reserved','<L'), 1108 ) 1109 AsciiStructure = ( 1110 ('FileName','z'), 1111 ) 1112 UnicodeStructure = ( 1113 ('FileName','u'), 1114 ) 1115 1116 class SMBSetPathInformationResponse_Parameters(Structure): 1117 structure = ( 1118 ('EaErrorOffset','<H=0'), 1119 ) 1120 1121 # TRANS2_SET_FILE_INFORMATION 1122 class SMBSetFileInformation_Parameters(Structure): 1123 structure = ( 1124 ('FID','<H'), 1125 ('InformationLevel','<H'), 1126 ('Reserved','<H'), 1127 ) 1128 1129 class SMBSetFileInformationResponse_Parameters(Structure): 1130 structure = ( 1131 ('EaErrorOffset','<H=0'), 1132 ) 1133 1134 # TRANS2_QUERY_FILE_INFORMATION 1135 class SMBQueryFileInformation_Parameters(Structure): 1136 structure = ( 1137 ('FID','<H'), 1138 ('InformationLevel','<H'), 1139 ) 1140 1141 class SMBQueryFileInformationResponse_Parameters(Structure): 1142 structure = ( 1143 ('EaErrorOffset','<H=0'), 1144 ) 1145 1146 class SMBQueryFileInformation_Data(Structure): 1147 structure = ( 1148 ('GetExtendedAttributeList',':'), 1149 ) 1150 1151 # TRANS2_QUERY_PATH_INFORMATION 1152 class SMBQueryPathInformationResponse_Parameters(Structure): 1153 structure = ( 1154 ('EaErrorOffset','<H=0'), 1155 ) 1156 1157 class SMBQueryPathInformation_Parameters(AsciiOrUnicodeStructure): 1158 commonHdr = ( 1159 ('InformationLevel','<H'), 1160 ('Reserved','<L=0'), 1161 ) 1162 AsciiStructure = ( 1163 ('FileName','z'), 1164 ) 1165 UnicodeStructure = ( 1166 ('FileName','u'), 1167 ) 1168 1169 class SMBQueryPathInformation_Data(Structure): 1170 structure = ( 1171 ('GetExtendedAttributeList',':'), 1172 ) 1173 1174 1175 # SMB_QUERY_FILE_EA_INFO 1176 class SMBQueryFileEaInfo(Structure): 1177 structure = ( 1178 ('EaSize','<L=0'), 1179 ) 1180 1181 # SMB_QUERY_FILE_BASIC_INFO 1182 class SMBQueryFileBasicInfo(Structure): 1183 structure = ( 1184 ('CreationTime','<q'), 1185 ('LastAccessTime','<q'), 1186 ('LastWriteTime','<q'), 1187 ('LastChangeTime','<q'), 1188 ('ExtFileAttributes','<L'), 1189 #('Reserved','<L=0'), 1190 ) 1191 1192 # SMB_QUERY_FILE_STANDARD_INFO 1193 class SMBQueryFileStandardInfo(Structure): 1194 structure = ( 1195 ('AllocationSize','<q'), 1196 ('EndOfFile','<q'), 1197 ('NumberOfLinks','<L=0'), 1198 ('DeletePending','<B=0'), 1199 ('Directory','<B'), 1200 ) 1201 1202 # SMB_QUERY_FILE_ALL_INFO 1203 class SMBQueryFileAllInfo(Structure): 1204 structure = ( 1205 ('CreationTime','<q'), 1206 ('LastAccessTime','<q'), 1207 ('LastWriteTime','<q'), 1208 ('LastChangeTime','<q'), 1209 ('ExtFileAttributes','<L'), 1210 ('Reserved','<L=0'), 1211 ('AllocationSize','<q'), 1212 ('EndOfFile','<q'), 1213 ('NumberOfLinks','<L=0'), 1214 ('DeletePending','<B=0'), 1215 ('Directory','<B'), 1216 ('Reserved','<H=0'), 1217 ('EaSize','<L=0'), 1218 ('FileNameLength','<L-FileName','len(FileName)'), 1219 ('FileName',':'), 1220 ) 1221 1222 # \PIPE\LANMAN NetShareEnum 1223 class SMBNetShareEnum(Structure): 1224 structure = ( 1225 ('RAPOpcode','<H=0'), 1226 ('ParamDesc','z'), 1227 ('DataDesc','z'), 1228 ('InfoLevel','<H'), 1229 ('ReceiveBufferSize','<H'), 1230 ) 1231 1232 class SMBNetShareEnumResponse(Structure): 1233 structure = ( 1234 ('Status','<H=0'), 1235 ('Convert','<H=0'), 1236 ('EntriesReturned','<H'), 1237 ('EntriesAvailable','<H'), 1238 ) 1239 1240 class NetShareInfo1(Structure): 1241 structure = ( 1242 ('NetworkName','13s'), 1243 ('Pad','<B=0'), 1244 ('Type','<H=0'), 1245 ('RemarkOffsetLow','<H=0'), 1246 ('RemarkOffsetHigh','<H=0'), 1247 ) 1248 1249 # \PIPE\LANMAN NetServerGetInfo 1250 class SMBNetServerGetInfoResponse(Structure): 1251 structure = ( 1252 ('Status','<H=0'), 1253 ('Convert','<H=0'), 1254 ('TotalBytesAvailable','<H'), 1255 ) 1256 1257 class SMBNetServerInfo1(Structure): 1258 # Level 1 Response 1259 structure = ( 1260 ('ServerName','16s'), 1261 ('MajorVersion','B=5'), 1262 ('MinorVersion','B=0'), 1263 ('ServerType','<L=3'), 1264 ('ServerCommentLow','<H=0'), 1265 ('ServerCommentHigh','<H=0'), 1266 ) 1267 1268 # \PIPE\LANMAN NetShareGetInfo 1269 class SMBNetShareGetInfo(Structure): 1270 structure = ( 1271 ('RAPOpcode','<H=0'), 1272 ('ParamDesc','z'), 1273 ('DataDesc','z'), 1274 ('ShareName','z'), 1275 ('InfoLevel','<H'), 1276 ('ReceiveBufferSize','<H'), 1277 ) 1278 1279 class SMBNetShareGetInfoResponse(Structure): 1280 structure = ( 1281 ('Status','<H=0'), 1282 ('Convert','<H=0'), 1283 ('TotalBytesAvailable','<H'), 1284 ) 1285 1286 ############# Security Features 1287 class SecurityFeatures(Structure): 1288 structure = ( 1289 ('Key','<L=0'), 1290 ('CID','<H=0'), 1291 ('SequenceNumber','<H=0'), 1292 ) 1293 1294 ############# SMB_COM_QUERY_INFORMATION2 (0x23) 1295 class SMBQueryInformation2_Parameters(Structure): 1296 structure = ( 1297 ('Fid','<H'), 1298 ) 1299 1300 class SMBQueryInformation2Response_Parameters(Structure): 1301 structure = ( 1302 ('CreateDate','<H'), 1303 ('CreationTime','<H'), 1304 ('LastAccessDate','<H'), 1305 ('LastAccessTime','<H'), 1306 ('LastWriteDate','<H'), 1307 ('LastWriteTime','<H'), 1308 ('FileDataSize','<L'), 1309 ('FileAllocationSize','<L'), 1310 ('FileAttributes','<L'), 1311 ) 1312 1313 1314 1315 ############# SMB_COM_SESSION_SETUP_ANDX (0x73) 1316 class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters): 1317 structure = ( 1318 ('MaxBuffer','<H'), 1319 ('MaxMpxCount','<H'), 1320 ('VCNumber','<H'), 1321 ('SessionKey','<L'), 1322 ('AnsiPwdLength','<H'), 1323 ('UnicodePwdLength','<H'), 1324 ('_reserved','<L=0'), 1325 ('Capabilities','<L'), 1326 ) 1327 1328 class SMBSessionSetupAndX_Extended_Parameters(SMBAndXCommand_Parameters): 1329 structure = ( 1330 ('MaxBufferSize','<H'), 1331 ('MaxMpxCount','<H'), 1332 ('VcNumber','<H'), 1333 ('SessionKey','<L'), 1334 ('SecurityBlobLength','<H'), 1335 ('Reserved','<L=0'), 1336 ('Capabilities','<L'), 1337 ) 1338 1339 class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure): 1340 AsciiStructure = ( 1341 ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'), 1342 ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'), 1343 ('AnsiPwd',':=""'), 1344 ('UnicodePwd',':=""'), 1345 ('Account','z=""'), 1346 ('PrimaryDomain','z=""'), 1347 ('NativeOS','z=""'), 1348 ('NativeLanMan','z=""'), 1349 ) 1350 1351 UnicodeStructure = ( 1352 ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'), 1353 ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'), 1354 ('AnsiPwd',':=""'), 1355 ('UnicodePwd',':=""'), 1356 ('Account','u=""'), 1357 ('PrimaryDomain','u=""'), 1358 ('NativeOS','u=""'), 1359 ('NativeLanMan','u=""'), 1360 ) 1361 1362 class SMBSessionSetupAndX_Extended_Data(AsciiOrUnicodeStructure): 1363 AsciiStructure = ( 1364 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 1365 ('SecurityBlob',':'), 1366 ('NativeOS','z=""'), 1367 ('NativeLanMan','z=""'), 1368 ) 1369 1370 UnicodeStructure = ( 1371 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 1372 ('SecurityBlob',':'), 1373 ('NativeOS','u=""'), 1374 ('NativeLanMan','u=""'), 1375 ) 1376 1377 class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters): 1378 structure = ( 1379 ('Action','<H'), 1380 ) 1381 1382 class SMBSessionSetupAndX_Extended_Response_Parameters(SMBAndXCommand_Parameters): 1383 structure = ( 1384 ('Action','<H=0'), 1385 ('SecurityBlobLength','<H'), 1386 ) 1387 1388 class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure): 1389 AsciiStructure = ( 1390 ('NativeOS','z=""'), 1391 ('NativeLanMan','z=""'), 1392 ('PrimaryDomain','z=""'), 1393 ) 1394 1395 UnicodeStructure = ( 1396 ('NativeOS','u=""'), 1397 ('NativeLanMan','u=""'), 1398 ('PrimaryDomain','u=""'), 1399 ) 1400 1401 class SMBSessionSetupAndX_Extended_Response_Data(AsciiOrUnicodeStructure): 1402 AsciiStructure = ( 1403 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 1404 ('SecurityBlob',':'), 1405 ('NativeOS','z=""'), 1406 ('NativeLanMan','z=""'), 1407 ) 1408 1409 UnicodeStructure = ( 1410 ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'), 1411 ('SecurityBlob',':'), 1412 ('NativeOS','u=""'), 1413 ('NativeLanMan','u=""'), 1414 ) 1415 1416 ############# SMB_COM_TREE_CONNECT (0x70) 1417 class SMBTreeConnect_Parameters(SMBCommand_Parameters): 1418 structure = ( 1419 ) 1420 1421 class SMBTreeConnect_Data(SMBCommand_Parameters): 1422 structure = ( 1423 ('PathFormat','"\x04'), 1424 ('Path','z'), 1425 ('PasswordFormat','"\x04'), 1426 ('Password','z'), 1427 ('ServiceFormat','"\x04'), 1428 ('Service','z'), 1429 ) 1430 1431 ############# SMB_COM_TREE_CONNECT_ANDX (0x75) 1432 class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters): 1433 structure = ( 1434 ('Flags','<H=0'), 1435 ('PasswordLength','<H'), 1436 ) 1437 1438 class SMBTreeConnectAndXResponse_Parameters(SMBAndXCommand_Parameters): 1439 structure = ( 1440 ('OptionalSupport','<H=0'), 1441 ) 1442 1443 class SMBTreeConnectAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 1444 structure = ( 1445 ('OptionalSupport','<H=1'), 1446 ('MaximalShareAccessRights','<L=0x1fffff'), 1447 ('GuestMaximalShareAccessRights','<L=0x1fffff'), 1448 ) 1449 1450 class SMBTreeConnectAndX_Data(AsciiOrUnicodeStructure): 1451 AsciiStructure = ( 1452 ('_PasswordLength','_-Password','self["_PasswordLength"]'), 1453 ('Password',':'), 1454 ('Path','z'), 1455 ('Service','z'), 1456 ) 1457 1458 UnicodeStructure = ( 1459 ('_PasswordLength','_-Password','self["_PasswordLength"] if self["_PasswordLength"] > 0 else 1'), 1460 ('Password',':'), 1461 ('Path','u'), 1462 ('Service','z'), 1463 ) 1464 1465 class SMBTreeConnectAndXResponse_Data(AsciiOrUnicodeStructure): 1466 AsciiStructure = ( 1467 ('Service','z'), 1468 ('PadLen','_-Pad','self["PadLen"]'), 1469 ('Pad',':=""'), 1470 ('NativeFileSystem','z'), 1471 ) 1472 UnicodeStructure = ( 1473 ('Service','z'), 1474 ('PadLen','_-Pad','self["PadLen"]'), 1475 ('Pad',':=""'), 1476 ('NativeFileSystem','u'), 1477 ) 1478 1479 ############# SMB_COM_NT_CREATE_ANDX (0xA2) 1480 class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters): 1481 structure = ( 1482 ('_reserved', 'B=0'), 1483 ('FileNameLength','<H'), # NameLength 1484 ('CreateFlags','<L'), # Flags 1485 ('RootFid','<L=0'), # RootDirectoryFID 1486 ('AccessMask','<L'), # DesiredAccess 1487 ('AllocationSizeLo','<L=0'), # AllocationSize 1488 ('AllocationSizeHi','<L=0'), 1489 ('FileAttributes','<L=0'), # ExtFileAttributes 1490 ('ShareAccess','<L=3'), # 1491 ('Disposition','<L=1'), # CreateDisposition 1492 ('CreateOptions','<L'), # CreateOptions 1493 ('Impersonation','<L=2'), 1494 ('SecurityFlags','B=3'), 1495 ) 1496 1497 class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters): 1498 # 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? 1499 structure = ( 1500 ('OplockLevel', 'B=0'), 1501 ('Fid','<H'), 1502 ('CreateAction','<L'), 1503 ('CreateTime','<q=0'), 1504 ('LastAccessTime','<q=0'), 1505 ('LastWriteTime','<q=0'), 1506 ('LastChangeTime','<q=0'), 1507 ('FileAttributes','<L=0x80'), 1508 ('AllocationSize','<q=0'), 1509 ('EndOfFile','<q=0'), 1510 ('FileType','<H=0'), 1511 ('IPCState','<H=0'), 1512 ('IsDirectory','B'), 1513 ) 1514 1515 class SMBNtCreateAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters): 1516 # [MS-SMB] Extended response description 1517 structure = ( 1518 ('OplockLevel', 'B=0'), 1519 ('Fid','<H'), 1520 ('CreateAction','<L'), 1521 ('CreateTime','<q=0'), 1522 ('LastAccessTime','<q=0'), 1523 ('LastWriteTime','<q=0'), 1524 ('LastChangeTime','<q=0'), 1525 ('FileAttributes','<L=0x80'), 1526 ('AllocationSize','<q=0'), 1527 ('EndOfFile','<q=0'), 1528 ('FileType','<H=0'), 1529 ('IPCState','<H=0'), 1530 ('IsDirectory','B'), 1531 ('VolumeGUID','16s'), 1532 ('FileIdLow','<L=0'), 1533 ('FileIdHigh','<L=0'), 1534 ('MaximalAccessRights','<L=0x12019b'), 1535 ('GuestMaximalAccessRights','<L=0x120089'), 1536 ) 1537 1538 class SMBNtCreateAndX_Data(AsciiOrUnicodeStructure): 1539 AsciiStructure = ( 1540 ('FileName','z'), 1541 ) 1542 UnicodeStructure = ( 1543 ('Pad','B'), 1544 ('FileName','u'), 1545 ) 1546 1547 ############# SMB_COM_OPEN_ANDX (0xD2) 1548 class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters): 1549 structure = ( 1550 ('Flags','<H=0'), 1551 ('DesiredAccess','<H=0'), 1552 ('SearchAttributes','<H=0'), 1553 ('FileAttributes','<H=0'), 1554 ('CreationTime','<L=0'), 1555 ('OpenMode','<H=1'), # SMB_O_OPEN = 1 1556 ('AllocationSize','<L=0'), 1557 ('Reserved','8s=""'), 1558 ) 1559 1560 class SMBOpenAndX_Data(SMBNtCreateAndX_Data): 1561 pass 1562 1563 class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters): 1564 structure = ( 1565 ('Fid','<H=0'), 1566 ('FileAttributes','<H=0'), 1567 ('LastWriten','<L=0'), 1568 ('FileSize','<L=0'), 1569 ('GrantedAccess','<H=0'), 1570 ('FileType','<H=0'), 1571 ('IPCState','<H=0'), 1572 ('Action','<H=0'), 1573 ('ServerFid','<L=0'), 1574 ('_reserved','<H=0'), 1575 ) 1576 1577 ############# SMB_COM_WRITE (0x0B) 1578 class SMBWrite_Parameters(SMBCommand_Parameters): 1579 structure = ( 1580 ('Fid','<H'), 1581 ('Count','<H'), 1582 ('Offset','<L'), 1583 ('Remaining','<H'), 1584 ) 1585 1586 class SMBWriteResponse_Parameters(SMBCommand_Parameters): 1587 structure = ( 1588 ('Count','<H'), 1589 ) 1590 1591 class SMBWrite_Data(Structure): 1592 structure = ( 1593 ('BufferFormat','<B=1'), 1594 ('DataLength','<H-Data'), 1595 ('Data',':'), 1596 ) 1597 1598 1599 ############# SMB_COM_WRITE_ANDX (0x2F) 1600 class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters): 1601 structure = ( 1602 ('Fid','<H=0'), 1603 ('Offset','<L=0'), 1604 ('_reserved','<L=0xff'), 1605 ('WriteMode','<H=8'), 1606 ('Remaining','<H=0'), 1607 ('DataLength_Hi','<H=0'), 1608 ('DataLength','<H=0'), 1609 ('DataOffset','<H=0'), 1610 ('HighOffset','<L=0'), 1611 ) 1612 1613 class SMBWriteAndX_Data_Short(Structure): 1614 structure = ( 1615 ('_PadLen','_-Pad','self["DataOffset"] - 59'), 1616 ('Pad',':'), 1617 #('Pad','<B=0'), 1618 ('DataLength','_-Data','self["DataLength"]'), 1619 ('Data',':'), 1620 ) 1621 1622 class SMBWriteAndX_Data(Structure): 1623 structure = ( 1624 ('_PadLen','_-Pad','self["DataOffset"] - 63'), 1625 ('Pad',':'), 1626 #('Pad','<B=0'), 1627 ('DataLength','_-Data','self["DataLength"]'), 1628 ('Data',':'), 1629 ) 1630 1631 1632 class SMBWriteAndX_Parameters_Short(SMBAndXCommand_Parameters): 1633 structure = ( 1634 ('Fid','<H'), 1635 ('Offset','<L'), 1636 ('_reserved','<L=0xff'), 1637 ('WriteMode','<H=8'), 1638 ('Remaining','<H'), 1639 ('DataLength_Hi','<H=0'), 1640 ('DataLength','<H'), 1641 ('DataOffset','<H=0'), 1642 ) 1643 1644 class SMBWriteAndXResponse_Parameters(SMBAndXCommand_Parameters): 1645 structure = ( 1646 ('Count','<H'), 1647 ('Available','<H'), 1648 ('Reserved','<L=0'), 1649 ) 1650 1651 ############# SMB_COM_WRITE_RAW (0x1D) 1652 class SMBWriteRaw_Parameters(SMBCommand_Parameters): 1653 structure = ( 1654 ('Fid','<H'), 1655 ('Count','<H'), 1656 ('_reserved','<H=0'), 1657 ('Offset','<L'), 1658 ('Timeout','<L=0'), 1659 ('WriteMode','<H=0'), 1660 ('_reserved2','<L=0'), 1661 ('DataLength','<H'), 1662 ('DataOffset','<H=0'), 1663 ) 1664 1665 ############# SMB_COM_READ (0x0A) 1666 class SMBRead_Parameters(SMBCommand_Parameters): 1667 structure = ( 1668 ('Fid','<H'), 1669 ('Count','<H'), 1670 ('Offset','<L'), 1671 ('Remaining','<H=Count'), 1672 ) 1673 1674 class SMBReadResponse_Parameters(Structure): 1675 structure = ( 1676 ('Count','<H=0'), 1677 ('_reserved','8s=""'), 1678 ) 1679 1680 class SMBReadResponse_Data(Structure): 1681 structure = ( 1682 ('BufferFormat','<B=0x1'), 1683 ('DataLength','<H-Data'), 1684 ('Data',':'), 1685 ) 1686 1687 ############# SMB_COM_READ_RAW (0x1A) 1688 class SMBReadRaw_Parameters(SMBCommand_Parameters): 1689 structure = ( 1690 ('Fid','<H'), 1691 ('Offset','<L'), 1692 ('MaxCount','<H'), 1693 ('MinCount','<H=MaxCount'), 1694 ('Timeout','<L=0'), 1695 ('_reserved','<H=0'), 1696 ) 1697 1698 ############# SMB_COM_NT_TRANSACT (0xA0) 1699 class SMBNTTransaction_Parameters(SMBCommand_Parameters): 1700 structure = ( 1701 ('MaxSetupCount','<B=0'), 1702 ('Reserved1','<H=0'), 1703 ('TotalParameterCount','<L'), 1704 ('TotalDataCount','<L'), 1705 ('MaxParameterCount','<L=1024'), 1706 ('MaxDataCount','<L=65504'), 1707 ('ParameterCount','<L'), 1708 ('ParameterOffset','<L'), 1709 ('DataCount','<L'), 1710 ('DataOffset','<L'), 1711 ('SetupCount','<B=len(Setup)/2'), 1712 ('Function','<H=0'), 1713 ('SetupLength','_-Setup','SetupCount*2'), 1714 ('Setup',':'), 1715 ) 1716 1717 class SMBNTTransactionResponse_Parameters(SMBCommand_Parameters): 1718 structure = ( 1719 ('Reserved1','3s=""'), 1720 ('TotalParameterCount','<L'), 1721 ('TotalDataCount','<L'), 1722 ('ParameterCount','<L'), 1723 ('ParameterOffset','<L'), 1724 ('ParameterDisplacement','<L=0'), 1725 ('DataCount','<L'), 1726 ('DataOffset','<L'), 1727 ('DataDisplacement','<L=0'), 1728 ('SetupCount','<B=0'), 1729 ('SetupLength','_-Setup','SetupCount*2'), 1730 ('Setup',':'), 1731 ) 1732 1733 class SMBNTTransaction_Data(Structure): 1734 structure = ( 1735 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 1736 ('Pad1',':'), 1737 ('NT_Trans_ParametersLength','_-NT_Trans_Parameters','self["NT_Trans_ParametersLength"]'), 1738 ('NT_Trans_Parameters',':'), 1739 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 1740 ('Pad2',':'), 1741 ('NT_Trans_DataLength','_-NT_Trans_Data','self["NT_Trans_DataLength"]'), 1742 ('NT_Trans_Data',':'), 1743 ) 1744 1745 class SMBNTTransactionResponse_Data(Structure): 1746 structure = ( 1747 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 1748 ('Pad1',':'), 1749 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 1750 ('Trans_Parameters',':'), 1751 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 1752 ('Pad2',':'), 1753 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 1754 ('Trans_Data',':'), 1755 ) 1756 1757 1758 ############# SMB_COM_TRANSACTION2_SECONDARY (0x33) 1759 class SMBTransaction2Secondary_Parameters(SMBCommand_Parameters): 1760 structure = ( 1761 ('TotalParameterCount','<H'), 1762 ('TotalDataCount','<H'), 1763 ('ParameterCount','<H'), 1764 ('ParameterOffset','<H'), 1765 ('DataCount','<H'), 1766 ('DataOffset','<H'), 1767 ('DataDisplacement','<H=0'), 1768 ('FID','<H'), 1769 ) 1770 1771 class SMBTransaction2Secondary_Data(Structure): 1772 structure = ( 1773 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 1774 ('Pad1',':'), 1775 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 1776 ('Trans_Parameters',':'), 1777 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 1778 ('Pad2',':'), 1779 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 1780 ('Trans_Data',':'), 1781 ) 1782 1783 1784 ############# SMB_COM_TRANSACTION2 (0x32) 1785 1786 class SMBTransaction2_Parameters(SMBCommand_Parameters): 1787 structure = ( 1788 ('TotalParameterCount','<H'), 1789 ('TotalDataCount','<H'), 1790 ('MaxParameterCount','<H=1024'), 1791 ('MaxDataCount','<H=65504'), 1792 ('MaxSetupCount','<B=0'), 1793 ('Reserved1','<B=0'), 1794 ('Flags','<H=0'), 1795 ('Timeout','<L=0'), 1796 ('Reserved2','<H=0'), 1797 ('ParameterCount','<H'), 1798 ('ParameterOffset','<H'), 1799 ('DataCount','<H'), 1800 ('DataOffset','<H'), 1801 ('SetupCount','<B=len(Setup)/2'), 1802 ('Reserved3','<B=0'), 1803 ('SetupLength','_-Setup','SetupCount*2'), 1804 ('Setup',':'), 1805 ) 1806 1807 class SMBTransaction2Response_Parameters(SMBCommand_Parameters): 1808 structure = ( 1809 ('TotalParameterCount','<H'), 1810 ('TotalDataCount','<H'), 1811 ('Reserved1','<H=0'), 1812 ('ParameterCount','<H'), 1813 ('ParameterOffset','<H'), 1814 ('ParameterDisplacement','<H=0'), 1815 ('DataCount','<H'), 1816 ('DataOffset','<H'), 1817 ('DataDisplacement','<H=0'), 1818 ('SetupCount','<B=0'), 1819 ('Reserved2','<B=0'), 1820 ('SetupLength','_-Setup','SetupCount*2'), 1821 ('Setup',':'), 1822 ) 1823 1824 class SMBTransaction2_Data(Structure): 1825 structure = ( 1826 # ('NameLength','_-Name','1'), 1827 # ('Name',':'), 1828 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 1829 ('Pad1',':'), 1830 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 1831 ('Trans_Parameters',':'), 1832 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 1833 ('Pad2',':'), 1834 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 1835 ('Trans_Data',':'), 1836 ) 1837 1838 class SMBTransaction2Response_Data(Structure): 1839 structure = ( 1840 ('Pad1Length','_-Pad1','self["Pad1Length"]'), 1841 ('Pad1',':'), 1842 ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'), 1843 ('Trans_Parameters',':'), 1844 ('Pad2Length','_-Pad2','self["Pad2Length"]'), 1845 ('Pad2',':'), 1846 ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'), 1847 ('Trans_Data',':'), 1848 ) 1849 1850 ############# SMB_COM_QUERY_INFORMATION (0x08) 1851 1852 class SMBQueryInformation_Data(AsciiOrUnicodeStructure): 1853 AsciiStructure = ( 1854 ('BufferFormat','B=4'), 1855 ('FileName','z'), 1856 ) 1857 UnicodeStructure = ( 1858 ('BufferFormat','B=4'), 1859 ('FileName','u'), 1860 ) 1861 1862 1863 class SMBQueryInformationResponse_Parameters(Structure): 1864 structure = ( 1865 ('FileAttributes','<H'), 1866 ('LastWriteTime','<L'), 1867 ('FileSize','<L'), 1868 ('Reserved','"0123456789'), 1869 ) 1870 1871 ############# SMB_COM_TRANSACTION (0x25) 1872 class SMBTransaction_Parameters(SMBCommand_Parameters): 1873 structure = ( 1874 ('TotalParameterCount','<H'), 1875 ('TotalDataCount','<H'), 1876 ('MaxParameterCount','<H=1024'), 1877 ('MaxDataCount','<H=65504'), 1878 ('MaxSetupCount','<B=0'), 1879 ('Reserved1','<B=0'), 1880 ('Flags','<H=0'), 1881 ('Timeout','<L=0'), 1882 ('Reserved2','<H=0'), 1883 ('ParameterCount','<H'), 1884 ('ParameterOffset','<H'), 1885 ('DataCount','<H'), 1886 ('DataOffset','<H'), 1887 ('SetupCount','<B=len(Setup)/2'), 1888 ('Reserved3','<B=0'), 1889 ('SetupLength','_-Setup','SetupCount*2'), 1890 ('Setup',':'), 1891 ) 1892 1893 class SMBTransactionResponse_Parameters(SMBCommand_Parameters): 1894 structure = ( 1895 ('TotalParameterCount','<H'), 1896 ('TotalDataCount','<H'), 1897 ('Reserved1','<H=0'), 1898 ('ParameterCount','<H'), 1899 ('ParameterOffset','<H'), 1900 ('ParameterDisplacement','<H=0'), 1901 ('DataCount','<H'), 1902 ('DataOffset','<H'), 1903 ('DataDisplacement','<H=0'), 1904 ('SetupCount','<B'), 1905 ('Reserved2','<B=0'), 1906 ('SetupLength','_-Setup','SetupCount*2'), 1907 ('Setup',':'), 1908 ) 1909 1910 # TODO: We should merge these both. But this will require fixing 1911 # the instances where this structure is used on the client side 1912 class SMBTransaction_SData(AsciiOrUnicodeStructure): 1913 AsciiStructure = ( 1914 ('Name','z'), 1915 ('Trans_ParametersLength','_-Trans_Parameters'), 1916 ('Trans_Parameters',':'), 1917 ('Trans_DataLength','_-Trans_Data'), 1918 ('Trans_Data',':'), 1919 ) 1920 UnicodeStructure = ( 1921 ('Pad','B'), 1922 ('Name','u'), 1923 ('Trans_ParametersLength','_-Trans_Parameters'), 1924 ('Trans_Parameters',':'), 1925 ('Trans_DataLength','_-Trans_Data'), 1926 ('Trans_Data',':'), 1927 ) 1928 1929 class SMBTransaction_Data(Structure): 1930 structure = ( 1931 ('NameLength','_-Name'), 1932 ('Name',':'), 1933 ('Trans_ParametersLength','_-Trans_Parameters'), 1934 ('Trans_Parameters',':'), 1935 ('Trans_DataLength','_-Trans_Data'), 1936 ('Trans_Data',':'), 1937 ) 1938 1939 class SMBTransactionResponse_Data(Structure): 1940 structure = ( 1941 ('Trans_ParametersLength','_-Trans_Parameters'), 1942 ('Trans_Parameters',':'), 1943 ('Trans_DataLength','_-Trans_Data'), 1944 ('Trans_Data',':'), 1945 ) 1946 1947 ############# SMB_COM_READ_ANDX (0x2E) 1948 class SMBReadAndX_Parameters(SMBAndXCommand_Parameters): 1949 structure = ( 1950 ('Fid','<H'), 1951 ('Offset','<L'), 1952 ('MaxCount','<H'), 1953 ('MinCount','<H=MaxCount'), 1954 ('_reserved','<L=0x0'), 1955 ('Remaining','<H=MaxCount'), 1956 ('HighOffset','<L=0'), 1957 ) 1958 1959 class SMBReadAndX_Parameters2(SMBAndXCommand_Parameters): 1960 structure = ( 1961 ('Fid','<H'), 1962 ('Offset','<L'), 1963 ('MaxCount','<H'), 1964 ('MinCount','<H=MaxCount'), 1965 ('_reserved','<L=0xffffffff'), 1966 ('Remaining','<H=MaxCount'), 1967 ) 1968 1969 class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters): 1970 structure = ( 1971 ('Remaining','<H=0'), 1972 ('DataMode','<H=0'), 1973 ('_reserved','<H=0'), 1974 ('DataCount','<H'), 1975 ('DataOffset','<H'), 1976 ('DataCount_Hi','<L'), 1977 ('_reserved2','6s=""'), 1978 ) 1979 1980 ############# SMB_COM_ECHO (0x2B) 1981 class SMBEcho_Data(Structure): 1982 structure = ( 1983 ('Data',':'), 1984 ) 1985 1986 class SMBEcho_Parameters(Structure): 1987 structure = ( 1988 ('EchoCount','<H'), 1989 ) 1990 1991 class SMBEchoResponse_Data(Structure): 1992 structure = ( 1993 ('Data',':'), 1994 ) 1995 1996 class SMBEchoResponse_Parameters(Structure): 1997 structure = ( 1998 ('SequenceNumber','<H=1'), 1999 ) 2000 2001 ############# SMB_COM_QUERY_INFORMATION_DISK (0x80) 2002 class SMBQueryInformationDiskResponse_Parameters(Structure): 2003 structure = ( 2004 ('TotalUnits','<H'), 2005 ('BlocksPerUnit','<H'), 2006 ('BlockSize','<H'), 2007 ('FreeUnits','<H'), 2008 ('Reserved','<H=0'), 2009 ) 2010 2011 2012 ############# SMB_COM_LOGOFF_ANDX (0x74) 2013 class SMBLogOffAndX(SMBAndXCommand_Parameters): 2014 strucure = () 2015 2016 ############# SMB_COM_CLOSE (0x04) 2017 class SMBClose_Parameters(SMBCommand_Parameters): 2018 structure = ( 2019 ('FID','<H'), 2020 ('Time','<L=0'), 2021 ) 2022 2023 ############# SMB_COM_FLUSH (0x05) 2024 class SMBFlush_Parameters(SMBCommand_Parameters): 2025 structure = ( 2026 ('FID','<H'), 2027 ) 2028 2029 ############# SMB_COM_CREATE_DIRECTORY (0x00) 2030 class SMBCreateDirectory_Data(AsciiOrUnicodeStructure): 2031 AsciiStructure = ( 2032 ('BufferFormat','<B=4'), 2033 ('DirectoryName','z'), 2034 ) 2035 UnicodeStructure = ( 2036 ('BufferFormat','<B=4'), 2037 ('DirectoryName','u'), 2038 ) 2039 2040 ############# SMB_COM_DELETE (0x06) 2041 class SMBDelete_Data(AsciiOrUnicodeStructure): 2042 AsciiStructure = ( 2043 ('BufferFormat','<B=4'), 2044 ('FileName','z'), 2045 ) 2046 UnicodeStructure = ( 2047 ('BufferFormat','<B=4'), 2048 ('FileName','u'), 2049 ) 2050 2051 class SMBDelete_Parameters(Structure): 2052 structure = ( 2053 ('SearchAttributes','<H'), 2054 ) 2055 2056 ############# SMB_COM_DELETE_DIRECTORY (0x01) 2057 class SMBDeleteDirectory_Data(AsciiOrUnicodeStructure): 2058 AsciiStructure = ( 2059 ('BufferFormat','<B=4'), 2060 ('DirectoryName','z'), 2061 ) 2062 UnicodeStructure = ( 2063 ('BufferFormat','<B=4'), 2064 ('DirectoryName','u'), 2065 ) 2066 2067 ############# SMB_COM_CHECK_DIRECTORY (0x10) 2068 class SMBCheckDirectory_Data(AsciiOrUnicodeStructure): 2069 AsciiStructure = ( 2070 ('BufferFormat','<B=4'), 2071 ('DirectoryName','z'), 2072 ) 2073 UnicodeStructure = ( 2074 ('BufferFormat','<B=4'), 2075 ('DirectoryName','u'), 2076 ) 2077 2078 ############# SMB_COM_RENAME (0x07) 2079 class SMBRename_Parameters(SMBCommand_Parameters): 2080 structure = ( 2081 ('SearchAttributes','<H'), 2082 ) 2083 2084 class SMBRename_Data(AsciiOrUnicodeStructure): 2085 AsciiStructure = ( 2086 ('BufferFormat1','<B=4'), 2087 ('OldFileName','z'), 2088 ('BufferFormat2','<B=4'), 2089 ('NewFileName','z'), 2090 ) 2091 UnicodeStructure = ( 2092 ('BufferFormat1','<B=4'), 2093 ('OldFileName','u'), 2094 ('BufferFormat2','<B=4'), 2095 ('Pad','B=0'), 2096 ('NewFileName','u'), 2097 ) 2098 2099 2100 ############# SMB_COM_OPEN (0x02) 2101 class SMBOpen_Parameters(SMBCommand_Parameters): 2102 structure = ( 2103 ('DesiredAccess','<H=0'), 2104 ('SearchAttributes','<H=0'), 2105 ) 2106 2107 class SMBOpen_Data(AsciiOrUnicodeStructure): 2108 AsciiStructure = ( 2109 ('FileNameFormat','"\x04'), 2110 ('FileName','z'), 2111 ) 2112 UnicodeStructure = ( 2113 ('FileNameFormat','"\x04'), 2114 ('FileName','z'), 2115 ) 2116 2117 class SMBOpenResponse_Parameters(SMBCommand_Parameters): 2118 structure = ( 2119 ('Fid','<H=0'), 2120 ('FileAttributes','<H=0'), 2121 ('LastWriten','<L=0'), 2122 ('FileSize','<L=0'), 2123 ('GrantedAccess','<H=0'), 2124 ) 2125 2126 ############# EXTENDED SECURITY CLASSES 2127 class SMBExtended_Security_Parameters(Structure): 2128 structure = ( 2129 ('DialectIndex','<H'), 2130 ('SecurityMode','<B'), 2131 ('MaxMpxCount','<H'), 2132 ('MaxNumberVcs','<H'), 2133 ('MaxBufferSize','<L'), 2134 ('MaxRawSize','<L'), 2135 ('SessionKey','<L'), 2136 ('Capabilities','<L'), 2137 ('LowDateTime','<L'), 2138 ('HighDateTime','<L'), 2139 ('ServerTimeZone','<H'), 2140 ('ChallengeLength','<B'), 2141 ) 2142 2143 class SMBExtended_Security_Data(Structure): 2144 structure = ( 2145 ('ServerGUID','16s'), 2146 ('SecurityBlob',':'), 2147 ) 2148 2149 class SMBNTLMDialect_Parameters(Structure): 2150 structure = ( 2151 ('DialectIndex','<H'), 2152 ('SecurityMode','<B'), 2153 ('MaxMpxCount','<H'), 2154 ('MaxNumberVcs','<H'), 2155 ('MaxBufferSize','<L'), 2156 ('MaxRawSize','<L'), 2157 ('SessionKey','<L'), 2158 ('Capabilities','<L'), 2159 ('LowDateTime','<L'), 2160 ('HighDateTime','<L'), 2161 ('ServerTimeZone','<H'), 2162 ('ChallengeLength','<B'), 2163 ) 2164 2165 class SMBNTLMDialect_Data(Structure): 2166 structure = ( 2167 ('ChallengeLength','_-Challenge','self["ChallengeLength"]'), 2168 ('Challenge',':'), 2169 ('Payload',':'), 2170 # 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. 2171 ('DomainName','_'), 2172 ('ServerName','_'), 2173 ) 2174 def __init__(self,data = None, alignment = 0): 2175 Structure.__init__(self,data,alignment) 2176 #self['ChallengeLength']=8 2177 2178 def fromString(self,data): 2179 Structure.fromString(self,data) 2180 self['DomainName'] = '' 2181 self['ServerName'] = '' 2182 2183 class SMB: 2184 # SMB Command Codes 2185 SMB_COM_CREATE_DIRECTORY = 0x00 2186 SMB_COM_DELETE_DIRECTORY = 0x01 2187 SMB_COM_OPEN = 0x02 2188 SMB_COM_CREATE = 0x03 2189 SMB_COM_CLOSE = 0x04 2190 SMB_COM_FLUSH = 0x05 2191 SMB_COM_DELETE = 0x06 2192 SMB_COM_RENAME = 0x07 2193 SMB_COM_QUERY_INFORMATION = 0x08 2194 SMB_COM_SET_INFORMATION = 0x09 2195 SMB_COM_READ = 0x0A 2196 SMB_COM_WRITE = 0x0B 2197 SMB_COM_LOCK_BYTE_RANGE = 0x0C 2198 SMB_COM_UNLOCK_BYTE_RANGE = 0x0D 2199 SMB_COM_CREATE_TEMPORARY = 0x0E 2200 SMB_COM_CREATE_NEW = 0x0F 2201 SMB_COM_CHECK_DIRECTORY = 0x10 2202 SMB_COM_PROCESS_EXIT = 0x11 2203 SMB_COM_SEEK = 0x12 2204 SMB_COM_LOCK_AND_READ = 0x13 2205 SMB_COM_WRITE_AND_UNLOCK = 0x14 2206 SMB_COM_READ_RAW = 0x1A 2207 SMB_COM_READ_MPX = 0x1B 2208 SMB_COM_READ_MPX_SECONDARY = 0x1C 2209 SMB_COM_WRITE_RAW = 0x1D 2210 SMB_COM_WRITE_MPX = 0x1E 2211 SMB_COM_WRITE_MPX_SECONDARY = 0x1F 2212 SMB_COM_WRITE_COMPLETE = 0x20 2213 SMB_COM_QUERY_SERVER = 0x21 2214 SMB_COM_SET_INFORMATION2 = 0x22 2215 SMB_COM_QUERY_INFORMATION2 = 0x23 2216 SMB_COM_LOCKING_ANDX = 0x24 2217 SMB_COM_TRANSACTION = 0x25 2218 SMB_COM_TRANSACTION_SECONDARY = 0x26 2219 SMB_COM_IOCTL = 0x27 2220 SMB_COM_IOCTL_SECONDARY = 0x28 2221 SMB_COM_COPY = 0x29 2222 SMB_COM_MOVE = 0x2A 2223 SMB_COM_ECHO = 0x2B 2224 SMB_COM_WRITE_AND_CLOSE = 0x2C 2225 SMB_COM_OPEN_ANDX = 0x2D 2226 SMB_COM_READ_ANDX = 0x2E 2227 SMB_COM_WRITE_ANDX = 0x2F 2228 SMB_COM_NEW_FILE_SIZE = 0x30 2229 SMB_COM_CLOSE_AND_TREE_DISC = 0x31 2230 SMB_COM_TRANSACTION2 = 0x32 2231 SMB_COM_TRANSACTION2_SECONDARY = 0x33 2232 SMB_COM_FIND_CLOSE2 = 0x34 2233 SMB_COM_FIND_NOTIFY_CLOSE = 0x35 2234 # Used by Xenix/Unix 0x60 - 0x6E 2235 SMB_COM_TREE_CONNECT = 0x70 2236 SMB_COM_TREE_DISCONNECT = 0x71 2237 SMB_COM_NEGOTIATE = 0x72 2238 SMB_COM_SESSION_SETUP_ANDX = 0x73 2239 SMB_COM_LOGOFF_ANDX = 0x74 2240 SMB_COM_TREE_CONNECT_ANDX = 0x75 2241 SMB_COM_QUERY_INFORMATION_DISK = 0x80 2242 SMB_COM_SEARCH = 0x81 2243 SMB_COM_FIND = 0x82 2244 SMB_COM_FIND_UNIQUE = 0x83 2245 SMB_COM_FIND_CLOSE = 0x84 2246 SMB_COM_NT_TRANSACT = 0xA0 2247 SMB_COM_NT_TRANSACT_SECONDARY = 0xA1 2248 SMB_COM_NT_CREATE_ANDX = 0xA2 2249 SMB_COM_NT_CANCEL = 0xA4 2250 SMB_COM_NT_RENAME = 0xA5 2251 SMB_COM_OPEN_PRINT_FILE = 0xC0 2252 SMB_COM_WRITE_PRINT_FILE = 0xC1 2253 SMB_COM_CLOSE_PRINT_FILE = 0xC2 2254 SMB_COM_GET_PRINT_QUEUE = 0xC3 2255 SMB_COM_READ_BULK = 0xD8 2256 SMB_COM_WRITE_BULK = 0xD9 2257 SMB_COM_WRITE_BULK_DATA = 0xDA 2258 2259 # TRANSACT codes 2260 TRANS_TRANSACT_NMPIPE = 0x26 2261 2262 # TRANSACT2 codes 2263 TRANS2_FIND_FIRST2 = 0x0001 2264 TRANS2_FIND_NEXT2 = 0x0002 2265 TRANS2_QUERY_FS_INFORMATION = 0x0003 2266 TRANS2_QUERY_PATH_INFORMATION = 0x0005 2267 TRANS2_QUERY_FILE_INFORMATION = 0x0007 2268 TRANS2_SET_FILE_INFORMATION = 0x0008 2269 TRANS2_SET_PATH_INFORMATION = 0x0006 2270 2271 # Security Share Mode (Used internally by SMB class) 2272 SECURITY_SHARE_MASK = 0x01 2273 SECURITY_SHARE_SHARE = 0x00 2274 SECURITY_SHARE_USER = 0x01 2275 SECURITY_SIGNATURES_ENABLED = 0X04 2276 SECURITY_SIGNATURES_REQUIRED = 0X08 2277 2278 # Security Auth Mode (Used internally by SMB class) 2279 SECURITY_AUTH_MASK = 0x02 2280 SECURITY_AUTH_ENCRYPTED = 0x02 2281 SECURITY_AUTH_PLAINTEXT = 0x00 2282 2283 # Raw Mode Mask (Used internally by SMB class. Good for dialect up to and including LANMAN2.1) 2284 RAW_READ_MASK = 0x01 2285 RAW_WRITE_MASK = 0x02 2286 2287 # Capabilities Mask (Used internally by SMB class. Good for dialect NT LM 0.12) 2288 CAP_RAW_MODE = 0x00000001 2289 CAP_MPX_MODE = 0x0002 2290 CAP_UNICODE = 0x0004 2291 CAP_LARGE_FILES = 0x0008 2292 CAP_EXTENDED_SECURITY = 0x80000000 2293 CAP_USE_NT_ERRORS = 0x40 2294 CAP_NT_SMBS = 0x10 2295 CAP_LARGE_READX = 0x00004000 2296 CAP_LARGE_WRITEX = 0x00008000 2297 CAP_RPC_REMOTE_APIS = 0x20 2298 2299 # Flags1 Mask 2300 FLAGS1_LOCK_AND_READ_OK = 0x01 2301 FLAGS1_PATHCASELESS = 0x08 2302 FLAGS1_CANONICALIZED_PATHS = 0x10 2303 FLAGS1_REPLY = 0x80 2304 2305 # Flags2 Mask 2306 FLAGS2_LONG_NAMES = 0x0001 2307 FLAGS2_EAS = 0x0002 2308 FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004 2309 FLAGS2_IS_LONG_NAME = 0x0040 2310 FLAGS2_DFS = 0x1000 2311 FLAGS2_PAGING_IO = 0x2000 2312 FLAGS2_NT_STATUS = 0x4000 2313 FLAGS2_UNICODE = 0x8000 2314 FLAGS2_COMPRESSED = 0x0008 2315 FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED = 0x0010 2316 FLAGS2_EXTENDED_SECURITY = 0x0800 2317 2318 # Dialect's Security Mode flags 2319 NEGOTIATE_USER_SECURITY = 0x01 2320 NEGOTIATE_ENCRYPT_PASSWORDS = 0x02 2321 NEGOTIATE_SECURITY_SIGNATURE_ENABLE = 0x04 2322 NEGOTIATE_SECURITY_SIGNATURE_REQUIRED = 0x08 2323 2324 # Tree Connect AndX Response optionalSuppor flags 2325 SMB_SUPPORT_SEARCH_BITS = 0x01 2326 SMB_SHARE_IS_IN_DFS = 0x02 2327 2328 def __init__(self, remote_name, remote_host, my_name = None, host_type = nmb.TYPE_SERVER, sess_port = 445, timeout=None, UDP = 0, session = None, negPacket = None): 2329 # The uid attribute will be set when the client calls the login() method 2330 self._uid = 0 2331 self.__server_name = '' 2332 self.__server_os = '' 2333 self.__server_os_major = None 2334 self.__server_os_minor = None 2335 self.__server_os_build = None 2336 self.__server_lanman = '' 2337 self.__server_domain = '' 2338 self.__server_dns_domain_name = '' 2339 self.__remote_name = string.upper(remote_name) 2340 self.__remote_host = remote_host 2341 self.__isNTLMv2 = True 2342 self._dialects_parameters = None 2343 self._dialects_data = None 2344 # Credentials 2345 self.__userName = '' 2346 self.__password = '' 2347 self.__domain = '' 2348 self.__lmhash = '' 2349 self.__nthash = '' 2350 self.__aesKey = '' 2351 self.__kdc = '' 2352 self.__TGT = None 2353 self.__TGS = None 2354 2355 # Negotiate Protocol Result, used everywhere 2356 # Could be extended or not, flags should be checked before 2357 self._dialect_data = 0 2358 self._dialect_parameters = 0 2359 self._action = 0 2360 self._sess = None 2361 self.encrypt_passwords = True 2362 self.tid = 0 2363 self.fid = 0 2364 2365 # Signing stuff 2366 self._SignSequenceNumber = 0 2367 self._SigningSessionKey = '' 2368 self._SigningChallengeResponse = '' 2369 self._SignatureEnabled = False 2370 self._SignatureVerificationEnabled = False 2371 self._SignatureRequired = False 2372 2373 # Base flags (default flags, can be overriden using set_flags()) 2374 self.__flags1 = SMB.FLAGS1_PATHCASELESS | SMB.FLAGS1_CANONICALIZED_PATHS 2375 self.__flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES 2376 2377 if timeout is None: 2378 self.__timeout = 60 2379 else: 2380 self.__timeout = timeout 2381 2382 # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP. 2383 # This is to help some old applications still believing 2384 # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better 2385 # know about *SMBSERVER's limitations 2386 if sess_port == 445 and remote_name == '*SMBSERVER': 2387 self.__remote_name = remote_host 2388 2389 if session is None: 2390 if not my_name: 2391 my_name = socket.gethostname() 2392 i = string.find(my_name, '.') 2393 if i > -1: 2394 my_name = my_name[:i] 2395 2396 if UDP: 2397 self._sess = nmb.NetBIOSUDPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 2398 else: 2399 self._sess = nmb.NetBIOSTCPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout) 2400 2401 # Initialize session values (_dialect_data and _dialect_parameters) 2402 self.neg_session() 2403 2404 # Call login() without any authentication information to 2405 # setup a session if the remote server 2406 # is in share mode. 2407 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 2408 self.login('', '') 2409 else: 2410 self._sess = session 2411 self.neg_session(negPacket = negPacket) 2412 # Call login() without any authentication information to 2413 # setup a session if the remote server 2414 # is in share mode. 2415 if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE: 2416 self.login('', '') 2417 2418 @staticmethod 2419 def ntlm_supported(): 2420 return False 2421 2422 def get_remote_name(self): 2423 return self.__remote_name 2424 2425 def get_remote_host(self): 2426 return self.__remote_host 2427 2428 def get_flags(self): 2429 return self.__flags1, self.__flags2 2430 2431 def set_flags(self, flags1=None, flags2=None): 2432 if flags1 is not None: 2433 self.__flags1 = flags1 2434 if flags2 is not None: 2435 self.__flags2 = flags2 2436 2437 def set_timeout(self, timeout): 2438 prev_timeout = self.__timeout 2439 self.__timeout = timeout 2440 return prev_timeout 2441 2442 def get_timeout(self): 2443 return self.__timeout 2444 2445 @contextmanager 2446 def use_timeout(self, timeout): 2447 prev_timeout = self.set_timeout(timeout) 2448 try: 2449 yield 2450 finally: 2451 self.set_timeout(prev_timeout) 2452 2453 def get_session(self): 2454 return self._sess 2455 2456 def get_tid(self): 2457 return self.tid 2458 2459 def get_fid(self): 2460 return self.fid 2461 2462 def isGuestSession(self): 2463 return self._action & SMB_SETUP_GUEST 2464 2465 def doesSupportNTLMv2(self): 2466 return self.__isNTLMv2 2467 2468 def __del__(self): 2469 if self._sess: 2470 self._sess.close() 2471 2472 def recvSMB(self): 2473 r = self._sess.recv_packet(self.__timeout) 2474 return NewSMBPacket(data = r.get_trailer()) 2475 2476 @staticmethod 2477 def __decode_trans(params, data): 2478 totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, dataoffset, datads, setupcnt = unpack('<HHHHHHHHHB', params[:19]) 2479 if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt: 2480 has_more = 1 2481 else: 2482 has_more = 0 2483 paramoffset = paramoffset - 55 - setupcnt * 2 2484 dataoffset = dataoffset - 55 - setupcnt * 2 2485 return has_more, params[20:20 + setupcnt * 2], data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt] 2486 2487 # TODO: Move this to NewSMBPacket, it belongs there 2488 def signSMB(self, packet, signingSessionKey, signingChallengeResponse): 2489 # This logic MUST be applied for messages sent in response to any of the higher-layer actions and in 2490 # compliance with the message sequencing rules. 2491 # * The client or server that sends the message MUST provide the 32-bit sequence number for this 2492 # message, as specified in sections 3.2.4.1 and 3.3.4.1. 2493 # * The SMB_FLAGS2_SMB_SECURITY_SIGNATURE flag in the header MUST be set. 2494 # * To generate the signature, a 32-bit sequence number is copied into the 2495 # least significant 32 bits of the SecuritySignature field and the remaining 2496 # 4 bytes are set to 0x00. 2497 # * The MD5 algorithm, as specified in [RFC1321], MUST be used to generate a hash of the SMB 2498 # message from the start of the SMB Header, which is defined as follows. 2499 # CALL MD5Init( md5context ) 2500 # CALL MD5Update( md5context, Connection.SigningSessionKey ) 2501 # CALL MD5Update( md5context, Connection.SigningChallengeResponse ) 2502 # CALL MD5Update( md5context, SMB message ) 2503 # CALL MD5Final( digest, md5context ) 2504 # SET signature TO the first 8 bytes of the digest 2505 # The resulting 8-byte signature MUST be copied into the SecuritySignature field of the SMB Header, 2506 # after which the message can be transmitted. 2507 2508 #print "seq(%d) signingSessionKey %r, signingChallengeResponse %r" % (self._SignSequenceNumber, signingSessionKey, signingChallengeResponse) 2509 packet['SecurityFeatures'] = pack('<q',self._SignSequenceNumber) 2510 # Sign with the sequence 2511 m = hashlib.md5() 2512 m.update( signingSessionKey ) 2513 m.update( signingChallengeResponse ) 2514 m.update( str(packet) ) 2515 # Replace sequence with acual hash 2516 packet['SecurityFeatures'] = m.digest()[:8] 2517 if self._SignatureVerificationEnabled: 2518 self._SignSequenceNumber +=1 2519 else: 2520 self._SignSequenceNumber +=2 2521 2522 def checkSignSMB(self, packet, signingSessionKey, signingChallengeResponse): 2523 # Let's check 2524 signature = packet['SecurityFeatures'] 2525 #print "Signature received: %r " % signature 2526 self.signSMB(packet, signingSessionKey, signingChallengeResponse) 2527 #print "Signature calculated: %r" % packet['SecurityFeatures'] 2528 if self._SignatureVerificationEnabled is not True: 2529 self._SignSequenceNumber -= 1 2530 return packet['SecurityFeatures'] == signature 2531 2532 def sendSMB(self,smb): 2533 smb['Uid'] = self._uid 2534 #At least on AIX, PIDs can exceed 16 bits, so we mask them out 2535 smb['Pid'] = (os.getpid() & 0xFFFF) 2536 # set flags 2537 smb['Flags1'] |= self.__flags1 2538 smb['Flags2'] |= self.__flags2 2539 if self._SignatureEnabled: 2540 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 2541 self.signSMB(smb, self._SigningSessionKey, self._SigningChallengeResponse) 2542 2543 self._sess.send_packet(str(smb)) 2544 2545 @staticmethod 2546 def isValidAnswer(s, cmd): 2547 while 1: 2548 if s.rawData(): 2549 if s.get_command() == cmd: 2550 if s.get_error_class() == 0x00 and s.get_error_code() == 0x00: 2551 return 1 2552 else: 2553 raise SessionError, ( "SMB Library Error", s.get_error_class()+ (s.get_reserved() << 8), s.get_error_code() , s.get_flags2() & SMB.FLAGS2_NT_STATUS ) 2554 else: 2555 break 2556 return 0 2557 2558 def neg_session(self, extended_security = True, negPacket = None): 2559 def parsePacket(smb): 2560 if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE): 2561 sessionResponse = SMBCommand(smb['Data'][0]) 2562 self._dialects_parameters = SMBNTLMDialect_Parameters(sessionResponse['Parameters']) 2563 self._dialects_data = SMBNTLMDialect_Data() 2564 self._dialects_data['ChallengeLength'] = self._dialects_parameters['ChallengeLength'] 2565 self._dialects_data.fromString(sessionResponse['Data']) 2566 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 2567 # Whether we choose it or it is enforced by the server, we go for extended security 2568 self._dialects_parameters = SMBExtended_Security_Parameters(sessionResponse['Parameters']) 2569 self._dialects_data = SMBExtended_Security_Data(sessionResponse['Data']) 2570 # Let's setup some variable for later use 2571 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 2572 self._SignatureRequired = True 2573 2574 # Interestingly, the security Blob might be missing sometimes. 2575 #spnego = SPNEGO_NegTokenInit(self._dialects_data['SecurityBlob']) 2576 #for i in spnego['MechTypes']: 2577 # print "Mech Found: %s" % MechTypes[i] 2578 return 1 2579 2580 # If not, let's try the old way 2581 else: 2582 if self._dialects_data['ServerName'] is not None: 2583 self.__server_name = self._dialects_data['ServerName'] 2584 2585 if self._dialects_parameters['DialectIndex'] == 0xffff: 2586 raise UnsupportedFeature,"Remote server does not know NT LM 0.12" 2587 return 1 2588 else: 2589 return 0 2590 2591 if negPacket is None: 2592 smb = NewSMBPacket() 2593 negSession = SMBCommand(SMB.SMB_COM_NEGOTIATE) 2594 flags2 = self.get_flags()[1] 2595 if extended_security is True: 2596 self.set_flags(flags2=flags2|SMB.FLAGS2_EXTENDED_SECURITY) 2597 else: 2598 self.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY)) 2599 2600 negSession['Data'] = '\x02NT LM 0.12\x00' 2601 smb.addCommand(negSession) 2602 self.sendSMB(smb) 2603 2604 while 1: 2605 smb = self.recvSMB() 2606 return parsePacket(smb) 2607 else: 2608 2609 return parsePacket( NewSMBPacket( data = negPacket)) 2610 2611 def tree_connect(self, path, password = '', service = SERVICE_ANY): 2612 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") 2613 2614 # return 0x800 2615 if password: 2616 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 2617 if self._dialects_parameters['ChallengeLength'] > 0: 2618 # this code is untested 2619 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 2620 2621 if not unicode_support: 2622 if unicode_convert: 2623 path = str(path) 2624 else: 2625 raise Exception('SMB: Can\t conver path from unicode!') 2626 2627 smb = NewSMBPacket() 2628 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT) 2629 treeConnect['Parameters'] = SMBTreeConnect_Parameters() 2630 treeConnect['Data'] = SMBTreeConnect_Data() 2631 treeConnect['Data']['Path'] = path.upper() 2632 treeConnect['Data']['Password'] = password 2633 treeConnect['Data']['Service'] = service 2634 smb.addCommand(treeConnect) 2635 self.sendSMB(smb) 2636 2637 while 1: 2638 smb = self.recvSMB() 2639 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT): 2640 # XXX Here we are ignoring the rest of the response 2641 return smb['Tid'] 2642 return smb['Tid'] 2643 2644 def get_uid(self): 2645 return self._uid 2646 2647 def set_uid(self, uid): 2648 self._uid = uid 2649 2650 def tree_connect_andx(self, path, password = None, service = SERVICE_ANY, smb_packet=None): 2651 if password: 2652 # Password is only encrypted if the server passed us an "encryption" during protocol dialect 2653 if self._dialects_parameters['ChallengeLength'] > 0: 2654 # this code is untested 2655 password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) 2656 else: 2657 password = '\x00' 2658 2659 if not unicode_support: 2660 if unicode_convert: 2661 path = str(path) 2662 else: 2663 raise Exception('SMB: Can\t convert path from unicode!') 2664 2665 if smb_packet is None: 2666 smb = NewSMBPacket() 2667 else: 2668 smb = smb_packet 2669 2670 # Just in case this came with the full path ,let's just leave 2671 # the sharename, we'll take care of the rest 2672 2673 share = path.split('\\')[-1] 2674 try: 2675 _, _, _, _, sockaddr = socket.getaddrinfo(self.get_remote_host(), 80, 0, 0, socket.IPPROTO_TCP)[0] 2676 remote_host = sockaddr[0] 2677 except Exception: 2678 remote_host = self.get_remote_host() 2679 2680 path = '\\\\' + remote_host + '\\' +share 2681 path = path.upper().encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 2682 2683 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX) 2684 treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters() 2685 treeConnect['Data'] = SMBTreeConnectAndX_Data(flags=self.__flags2) 2686 treeConnect['Parameters']['PasswordLength'] = len(password) 2687 treeConnect['Data']['Password'] = password 2688 treeConnect['Data']['Path'] = path 2689 treeConnect['Data']['Service'] = service 2690 2691 if self.__flags2 & SMB.FLAGS2_UNICODE: 2692 treeConnect['Data']['Pad'] = 0x0 2693 2694 smb.addCommand(treeConnect) 2695 2696 # filename = "\PIPE\epmapper" 2697 2698 # ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 2699 # ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 2700 # ntCreate['Data'] = SMBNtCreateAndX_Data() 2701 # ntCreate['Parameters']['FileNameLength'] = len(filename) 2702 # ntCreate['Parameters']['CreateFlags'] = 0 2703 # ntCreate['Parameters']['AccessMask'] = 0x3 2704 # ntCreate['Parameters']['CreateOptions'] = 0x0 2705 # ntCreate['Data']['FileName'] = filename 2706 2707 # smb.addCommand(ntCreate) 2708 self.sendSMB(smb) 2709 2710 while 1: 2711 smb = self.recvSMB() 2712 if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX): 2713 # XXX Here we are ignoring the rest of the response 2714 self.tid = smb['Tid'] 2715 return self.tid 2716 self.tid = smb['Tid'] 2717 return self.tid 2718 2719 # backwars compatibility 2720 connect_tree = tree_connect_andx 2721 2722 @staticmethod 2723 def getDialect(): 2724 return SMB_DIALECT 2725 2726 def get_server_name(self): 2727 #return self._dialects_data['ServerName'] 2728 return self.__server_name 2729 2730 def get_session_key(self): 2731 return self._SigningSessionKey 2732 2733 def set_session_key(self, key): 2734 self._SigningSessionKey = key 2735 2736 def get_encryption_key(self): 2737 if self._dialects_data.fields.has_key('Challenge'): 2738 return self._dialects_data['Challenge'] 2739 else: 2740 return None 2741 2742 def get_server_time(self): 2743 timestamp = self._dialects_parameters['HighDateTime'] 2744 timestamp <<= 32 2745 timestamp |= self._dialects_parameters['LowDateTime'] 2746 timestamp -= 116444736000000000 2747 timestamp /= 10000000 2748 d = datetime.datetime.utcfromtimestamp(timestamp) 2749 return d.strftime("%a, %d %b %Y %H:%M:%S GMT") 2750 2751 def disconnect_tree(self, tid): 2752 smb = NewSMBPacket() 2753 smb['Tid'] = tid 2754 2755 smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT)) 2756 2757 self.sendSMB(smb) 2758 self.recvSMB() 2759 2760 def open(self, tid, filename, open_mode, desired_access): 2761 filename = string.replace(filename,'/', '\\') 2762 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 2763 2764 smb = NewSMBPacket() 2765 smb['Tid'] = tid 2766 2767 openFile = SMBCommand(SMB.SMB_COM_OPEN) 2768 openFile['Parameters'] = SMBOpen_Parameters() 2769 openFile['Parameters']['DesiredAccess'] = desired_access 2770 openFile['Parameters']['OpenMode'] = open_mode 2771 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 2772 openFile['Data'] = SMBOpen_Data(flags=self.__flags2) 2773 openFile['Data']['FileName'] = filename 2774 2775 if self.__flags2 & SMB.FLAGS2_UNICODE: 2776 openFile['Data']['Pad'] = 0x0 2777 2778 smb.addCommand(openFile) 2779 2780 self.sendSMB(smb) 2781 2782 smb = self.recvSMB() 2783 if smb.isValidAnswer(SMB.SMB_COM_OPEN): 2784 # XXX Here we are ignoring the rest of the response 2785 openFileResponse = SMBCommand(smb['Data'][0]) 2786 openFileParameters = SMBOpenResponse_Parameters(openFileResponse['Parameters']) 2787 2788 return ( 2789 openFileParameters['Fid'], 2790 openFileParameters['FileAttributes'], 2791 openFileParameters['LastWriten'], 2792 openFileParameters['FileSize'], 2793 openFileParameters['GrantedAccess'], 2794 ) 2795 2796 def open_andx(self, tid, filename, open_mode, desired_access): 2797 filename = string.replace(filename,'/', '\\') 2798 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 2799 2800 smb = NewSMBPacket() 2801 smb['Tid'] = tid 2802 2803 openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX) 2804 openFile['Parameters'] = SMBOpenAndX_Parameters() 2805 openFile['Parameters']['DesiredAccess'] = desired_access 2806 openFile['Parameters']['OpenMode'] = open_mode 2807 openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE 2808 openFile['Data'] = SMBOpenAndX_Data(flags=self.__flags2) 2809 openFile['Data']['FileName'] = filename 2810 2811 if self.__flags2 & SMB.FLAGS2_UNICODE: 2812 openFile['Data']['Pad'] = 0x0 2813 2814 smb.addCommand(openFile) 2815 2816 self.sendSMB(smb) 2817 2818 smb = self.recvSMB() 2819 if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX): 2820 # XXX Here we are ignoring the rest of the response 2821 openFileResponse = SMBCommand(smb['Data'][0]) 2822 openFileParameters = SMBOpenAndXResponse_Parameters(openFileResponse['Parameters']) 2823 2824 return ( 2825 openFileParameters['Fid'], 2826 openFileParameters['FileAttributes'], 2827 openFileParameters['LastWriten'], 2828 openFileParameters['FileSize'], 2829 openFileParameters['GrantedAccess'], 2830 openFileParameters['FileType'], 2831 openFileParameters['IPCState'], 2832 openFileParameters['Action'], 2833 openFileParameters['ServerFid'], 2834 ) 2835 2836 def close(self, tid, fid): 2837 smb = NewSMBPacket() 2838 smb['Tid'] = tid 2839 2840 closeFile = SMBCommand(SMB.SMB_COM_CLOSE) 2841 closeFile['Parameters'] = SMBClose_Parameters() 2842 closeFile['Parameters']['FID'] = fid 2843 smb.addCommand(closeFile) 2844 2845 self.sendSMB(smb) 2846 smb = self.recvSMB() 2847 if smb.isValidAnswer(SMB.SMB_COM_CLOSE): 2848 return 1 2849 return 0 2850 2851 def send_trans(self, tid, setup, name, param, data, noAnswer = 0): 2852 smb = NewSMBPacket() 2853 smb['Tid'] = tid 2854 2855 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 2856 transCommand['Parameters'] = SMBTransaction_Parameters() 2857 transCommand['Data'] = SMBTransaction_Data() 2858 2859 transCommand['Parameters']['Setup'] = setup 2860 transCommand['Parameters']['TotalParameterCount'] = len(param) 2861 transCommand['Parameters']['TotalDataCount'] = len(data) 2862 2863 transCommand['Parameters']['ParameterCount'] = len(param) 2864 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 2865 2866 transCommand['Parameters']['DataCount'] = len(data) 2867 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) 2868 2869 transCommand['Data']['Name'] = name 2870 transCommand['Data']['Trans_Parameters'] = param 2871 transCommand['Data']['Trans_Data'] = data 2872 2873 if noAnswer: 2874 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 2875 2876 smb.addCommand(transCommand) 2877 2878 self.sendSMB(smb) 2879 2880 def send_trans2(self, tid, setup, name, param, data): 2881 smb = NewSMBPacket() 2882 smb['Tid'] = tid 2883 2884 command = pack('<H', setup) 2885 2886 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION2) 2887 transCommand['Parameters'] = SMBTransaction2_Parameters() 2888 transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize'] 2889 transCommand['Data'] = SMBTransaction2_Data() 2890 2891 transCommand['Parameters']['Setup'] = command 2892 transCommand['Parameters']['TotalParameterCount'] = len(param) 2893 transCommand['Parameters']['TotalDataCount'] = len(data) 2894 2895 if len(param) > 0: 2896 padLen = (4 - (32+2+28 + len(command)) % 4 ) % 4 2897 padBytes = '\xFF' * padLen 2898 transCommand['Data']['Pad1'] = padBytes 2899 else: 2900 transCommand['Data']['Pad1'] = '' 2901 padLen = 0 2902 2903 transCommand['Parameters']['ParameterCount'] = len(param) 2904 transCommand['Parameters']['ParameterOffset'] = 32+2+28+len(command)+len(name) + padLen 2905 2906 if len(data) > 0: 2907 pad2Len = (4 - (32+2+28 + len(command) + padLen + len(param)) % 4) % 4 2908 transCommand['Data']['Pad2'] = '\xFF' * pad2Len 2909 else: 2910 transCommand['Data']['Pad2'] = '' 2911 pad2Len = 0 2912 2913 transCommand['Parameters']['DataCount'] = len(data) 2914 transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len 2915 2916 transCommand['Data']['Name'] = name 2917 transCommand['Data']['Trans_Parameters'] = param 2918 transCommand['Data']['Trans_Data'] = data 2919 smb.addCommand(transCommand) 2920 2921 self.sendSMB(smb) 2922 2923 def query_file_info(self, tid, fid, fileInfoClass = SMB_QUERY_FILE_STANDARD_INFO): 2924 self.send_trans2(tid, SMB.TRANS2_QUERY_FILE_INFORMATION, '\x00', pack('<HH', fid, fileInfoClass), '') 2925 2926 resp = self.recvSMB() 2927 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 2928 trans2Response = SMBCommand(resp['Data'][0]) 2929 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 2930 # Remove Potential Prefix Padding 2931 return trans2Response['Data'][-trans2Parameters['TotalDataCount']:] 2932 2933 def __nonraw_retr_file(self, tid, fid, offset, datasize, callback): 2934 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 2935 max_buf_size = 65000 2936 else: 2937 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Read in multiple KB blocks 2938 2939 read_offset = offset 2940 while read_offset < datasize: 2941 data = self.read_andx(tid, fid, read_offset, max_buf_size) 2942 2943 callback(data) 2944 read_offset += len(data) 2945 2946 def __nonraw_stor_file(self, tid, fid, offset, datasize, callback): 2947 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 2948 max_buf_size = 65000 2949 else: 2950 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 2951 2952 write_offset = offset 2953 while 1: 2954 data = callback(max_buf_size) 2955 if not data: 2956 break 2957 2958 smb = self.write_andx(tid,fid,data, write_offset) 2959 writeResponse = SMBCommand(smb['Data'][0]) 2960 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 2961 write_offset += writeResponseParameters['Count'] 2962 2963 def get_server_domain(self): 2964 return self.__server_domain 2965 2966 def get_server_dns_domain_name(self): 2967 return self.__server_dns_domain_name 2968 2969 def get_server_os(self): 2970 return self.__server_os 2971 2972 def get_server_os_major(self): 2973 return self.__server_os_major 2974 2975 def get_server_os_minor(self): 2976 return self.__server_os_minor 2977 2978 def get_server_os_build(self): 2979 return self.__server_os_build 2980 2981 def set_server_os(self, os): 2982 self.__server_os = os 2983 2984 def get_server_lanman(self): 2985 return self.__server_lanman 2986 2987 def is_login_required(self): 2988 # Login is required if share mode is user. 2989 # Otherwise only public services or services in share mode 2990 # are allowed. 2991 return (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_USER 2992 2993 def is_signing_required(self): 2994 return self._SignatureRequired 2995 2996 def get_ntlmv1_response(self, key): 2997 challenge = self._dialects_data['Challenge'] 2998 return ntlm.get_ntlmv1_response(key, challenge) 2999 3000 def kerberos_login(self, user, password, domain = '', lmhash = '', nthash = '', aesKey = '', kdcHost = '', TGT=None, TGS=None): 3001 # Importing down here so pyasn1 is not required if kerberos is not used. 3002 from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set 3003 from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS 3004 from impacket.krb5 import constants 3005 from impacket.krb5.types import Principal, KerberosTime, Ticket 3006 from pyasn1.codec.der import decoder, encoder 3007 import datetime 3008 3009 # login feature does not support unicode 3010 # disable it if enabled 3011 flags2 = self.__flags2 3012 if flags2 & SMB.FLAGS2_UNICODE: 3013 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 3014 3015 # If TGT or TGS are specified, they are in the form of: 3016 # TGS['KDC_REP'] = the response from the server 3017 # TGS['cipher'] = the cipher used 3018 # TGS['sessionKey'] = the sessionKey 3019 # If we have hashes, normalize them 3020 if lmhash != '' or nthash != '': 3021 if len(lmhash) % 2: lmhash = '0%s' % lmhash 3022 if len(nthash) % 2: nthash = '0%s' % nthash 3023 try: # just in case they were converted already 3024 lmhash = a2b_hex(lmhash) 3025 nthash = a2b_hex(nthash) 3026 except: 3027 pass 3028 3029 self.__userName = user 3030 self.__password = password 3031 self.__domain = domain 3032 self.__lmhash = lmhash 3033 self.__nthash = nthash 3034 self.__aesKey = aesKey 3035 self.__kdc = kdcHost 3036 self.__TGT = TGT 3037 self.__TGS = TGS 3038 3039 # First of all, we need to get a TGT for the user 3040 userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) 3041 if TGT is None: 3042 if TGS is None: 3043 tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost) 3044 else: 3045 tgt = TGT['KDC_REP'] 3046 cipher = TGT['cipher'] 3047 sessionKey = TGT['sessionKey'] 3048 3049 # Now that we have the TGT, we should ask for a TGS for cifs 3050 3051 if TGS is None: 3052 serverName = Principal('cifs/%s' % self.__remote_name, type=constants.PrincipalNameType.NT_SRV_INST.value) 3053 tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey) 3054 else: 3055 tgs = TGS['KDC_REP'] 3056 cipher = TGS['cipher'] 3057 sessionKey = TGS['sessionKey'] 3058 3059 smb = NewSMBPacket() 3060 3061 # Are we required to sign SMB? If so we do it, if not we skip it 3062 if self._SignatureRequired: 3063 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 3064 3065 3066 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 3067 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 3068 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 3069 3070 sessionSetup['Parameters']['MaxBufferSize'] = 61440 3071 sessionSetup['Parameters']['MaxMpxCount'] = 2 3072 sessionSetup['Parameters']['VcNumber'] = 1 3073 sessionSetup['Parameters']['SessionKey'] = 0 3074 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 3075 3076 3077 # Let's build a NegTokenInit with the NTLMSSP 3078 # TODO: In the future we should be able to choose different providers 3079 3080 blob = SPNEGO_NegTokenInit() 3081 3082 # Kerberos v5 mech 3083 blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']] 3084 3085 # Let's extract the ticket from the TGS 3086 tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0] 3087 ticket = Ticket() 3088 ticket.from_asn1(tgs['ticket']) 3089 3090 # Now let's build the AP_REQ 3091 apReq = AP_REQ() 3092 apReq['pvno'] = 5 3093 apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value) 3094 3095 opts = list() 3096 apReq['ap-options'] = constants.encodeFlags(opts) 3097 seq_set(apReq,'ticket', ticket.to_asn1) 3098 3099 authenticator = Authenticator() 3100 authenticator['authenticator-vno'] = 5 3101 authenticator['crealm'] = domain 3102 seq_set(authenticator, 'cname', userName.components_to_asn1) 3103 now = datetime.datetime.utcnow() 3104 3105 authenticator['cusec'] = now.microsecond 3106 authenticator['ctime'] = KerberosTime.to_asn1(now) 3107 3108 encodedAuthenticator = encoder.encode(authenticator) 3109 3110 # Key Usage 11 3111 # AP-REQ Authenticator (includes application authenticator 3112 # subkey), encrypted with the application session key 3113 # (Section 5.5.1) 3114 encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None) 3115 3116 apReq['authenticator'] = None 3117 apReq['authenticator']['etype'] = cipher.enctype 3118 apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator 3119 3120 blob['MechToken'] = encoder.encode(apReq) 3121 3122 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 3123 sessionSetup['Parameters'].getData() 3124 sessionSetup['Data']['SecurityBlob'] = blob.getData() 3125 3126 # Fake Data here, don't want to get us fingerprinted 3127 sessionSetup['Data']['NativeOS'] = 'Unix' 3128 sessionSetup['Data']['NativeLanMan'] = 'Samba' 3129 3130 smb.addCommand(sessionSetup) 3131 self.sendSMB(smb) 3132 3133 smb = self.recvSMB() 3134 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3135 # We will need to use this uid field for all future requests/responses 3136 self._uid = smb['Uid'] 3137 3138 # Now we have to extract the blob to continue the auth process 3139 sessionResponse = SMBCommand(smb['Data'][0]) 3140 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 3141 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 3142 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 3143 sessionData.fromString(sessionResponse['Data']) 3144 3145 self._action = sessionParameters['Action'] 3146 # If smb sign required, let's enable it for the rest of the connection 3147 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3148 self._SigningSessionKey = sessionKey.contents 3149 self._SignSequenceNumber = 2 3150 self._SignatureEnabled = True 3151 3152 # restore unicode flag if needed 3153 if flags2 & SMB.FLAGS2_UNICODE: 3154 self.__flags2 |= SMB.FLAGS2_UNICODE 3155 3156 return 1 3157 else: 3158 raise Exception('Error: Could not login successfully') 3159 3160 def login_extended(self, user, password, domain = '', lmhash = '', nthash = '', use_ntlmv2 = True ): 3161 3162 # login feature does not support unicode 3163 # disable it if enabled 3164 flags2 = self.__flags2 3165 if flags2 & SMB.FLAGS2_UNICODE: 3166 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 3167 3168 # Once everything's working we should join login methods into a single one 3169 smb = NewSMBPacket() 3170 # Are we required to sign SMB? If so we do it, if not we skip it 3171 if self._SignatureRequired: 3172 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 3173 3174 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 3175 sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters() 3176 sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data() 3177 3178 sessionSetup['Parameters']['MaxBufferSize'] = 61440 3179 sessionSetup['Parameters']['MaxMpxCount'] = 2 3180 sessionSetup['Parameters']['VcNumber'] = 1 3181 sessionSetup['Parameters']['SessionKey'] = 0 3182 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 3183 3184 3185 # Let's build a NegTokenInit with the NTLMSSP 3186 # TODO: In the future we should be able to choose different providers 3187 3188 blob = SPNEGO_NegTokenInit() 3189 3190 # NTLMSSP 3191 blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']] 3192 auth = ntlm.getNTLMSSPType1('','',self._SignatureRequired, use_ntlmv2 = use_ntlmv2) 3193 blob['MechToken'] = str(auth) 3194 3195 sessionSetup['Parameters']['SecurityBlobLength'] = len(blob) 3196 sessionSetup['Parameters'].getData() 3197 sessionSetup['Data']['SecurityBlob'] = blob.getData() 3198 3199 # Fake Data here, don't want to get us fingerprinted 3200 sessionSetup['Data']['NativeOS'] = 'Unix' 3201 sessionSetup['Data']['NativeLanMan'] = 'Samba' 3202 3203 smb.addCommand(sessionSetup) 3204 self.sendSMB(smb) 3205 3206 smb = self.recvSMB() 3207 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3208 # We will need to use this uid field for all future requests/responses 3209 self._uid = smb['Uid'] 3210 3211 # Now we have to extract the blob to continue the auth process 3212 sessionResponse = SMBCommand(smb['Data'][0]) 3213 sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters']) 3214 sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2']) 3215 sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength'] 3216 sessionData.fromString(sessionResponse['Data']) 3217 respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob']) 3218 3219 # Let's parse some data and keep it to ourselves in case it is asked 3220 ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken']) 3221 if ntlmChallenge['TargetInfoFields_len'] > 0: 3222 av_pairs = ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']]) 3223 if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None: 3224 try: 3225 self.__server_name = av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le') 3226 except: 3227 # For some reason, we couldn't decode Unicode here.. silently discard the operation 3228 pass 3229 if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None: 3230 try: 3231 if self.__server_name != av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'): 3232 self.__server_domain = av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le') 3233 except: 3234 # For some reason, we couldn't decode Unicode here.. silently discard the operation 3235 pass 3236 if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None: 3237 try: 3238 self.__server_dns_domain_name = av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le') 3239 except: 3240 # For some reason, we couldn't decode Unicode here.. silently discard the operation 3241 pass 3242 3243 # Parse Version to know the target Operating system name. Not provided elsewhere anymore 3244 if ntlmChallenge.fields.has_key('Version'): 3245 version = ntlmChallenge['Version'] 3246 3247 if len(version) >= 4: 3248 self.__server_os_major, self.__server_os_minor, self.__server_os_build = unpack('<BBH',version[:4]) 3249 3250 type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 = use_ntlmv2) 3251 3252 if exportedSessionKey is not None: 3253 self._SigningSessionKey = exportedSessionKey 3254 3255 smb = NewSMBPacket() 3256 3257 # Are we required to sign SMB? If so we do it, if not we skip it 3258 if self._SignatureRequired: 3259 smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE 3260 3261 respToken2 = SPNEGO_NegTokenResp() 3262 respToken2['ResponseToken'] = str(type3) 3263 3264 # Reusing the previous structure 3265 sessionSetup['Parameters']['SecurityBlobLength'] = len(respToken2) 3266 sessionSetup['Data']['SecurityBlob'] = respToken2.getData() 3267 3268 # Storing some info for later use 3269 self.__server_os = sessionData['NativeOS'] 3270 self.__server_lanman = sessionData['NativeLanMan'] 3271 3272 smb.addCommand(sessionSetup) 3273 self.sendSMB(smb) 3274 3275 smb = self.recvSMB() 3276 self._uid = 0 3277 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3278 self._uid = smb['Uid'] 3279 sessionResponse = SMBCommand(smb['Data'][0]) 3280 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 3281 3282 self._action = sessionParameters['Action'] 3283 # If smb sign required, let's enable it for the rest of the connection 3284 if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED: 3285 self._SignSequenceNumber = 2 3286 self._SignatureEnabled = True 3287 3288 # restore unicode flag if needed 3289 if flags2 & SMB.FLAGS2_UNICODE: 3290 self.__flags2 |= SMB.FLAGS2_UNICODE 3291 3292 return 1 3293 else: 3294 raise Exception('Error: Could not login successfully') 3295 3296 def getCredentials(self): 3297 return ( 3298 self.__userName, 3299 self.__password, 3300 self.__domain, 3301 self.__lmhash, 3302 self.__nthash, 3303 self.__aesKey, 3304 self.__TGT, 3305 self.__TGS) 3306 3307 def getIOCapabilities(self): 3308 res = dict() 3309 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 3310 max_size = 65000 3311 else: 3312 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 3313 res['MaxReadSize'] = max_size 3314 res['MaxWriteSize'] = max_size 3315 return res 3316 3317 def login(self, user, password, domain = '', lmhash = '', nthash = '', ntlm_fallback = True): 3318 3319 # If we have hashes, normalize them 3320 if lmhash != '' or nthash != '': 3321 if len(lmhash) % 2: lmhash = '0%s' % lmhash 3322 if len(nthash) % 2: nthash = '0%s' % nthash 3323 try: # just in case they were converted already 3324 lmhash = a2b_hex(lmhash) 3325 nthash = a2b_hex(nthash) 3326 except: 3327 pass 3328 3329 self.__userName = user 3330 self.__password = password 3331 self.__domain = domain 3332 self.__lmhash = lmhash 3333 self.__nthash = nthash 3334 self.__aesKey = '' 3335 self.__TGT = None 3336 self.__TGS = None 3337 3338 if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY: 3339 try: 3340 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = True) 3341 except: 3342 # If the target OS is Windows 5.0 or Samba, let's try using NTLMv1 3343 if ntlm_fallback and ((self.get_server_lanman().find('Windows 2000') != -1) or (self.get_server_lanman().find('Samba') != -1)): 3344 self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = False) 3345 self.__isNTLMv2 = False 3346 else: 3347 raise 3348 elif ntlm_fallback: 3349 self.login_standard(user, password, domain, lmhash, nthash) 3350 self.__isNTLMv2 = False 3351 else: 3352 raise SessionError('Cannot authenticate against target, enable ntlm_fallback') 3353 3354 def login_standard(self, user, password, domain = '', lmhash = '', nthash = ''): 3355 3356 # login feature does not support unicode 3357 # disable it if enabled 3358 flags2 = self.__flags2 3359 if flags2 & SMB.FLAGS2_UNICODE: 3360 self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE) 3361 3362 # Only supports NTLMv1 3363 # Password is only encrypted if the server passed us an "encryption key" during protocol dialect negotiation 3364 if self._dialects_parameters['ChallengeLength'] > 0: 3365 if lmhash != '' or nthash != '': 3366 pwd_ansi = self.get_ntlmv1_response(lmhash) 3367 pwd_unicode = self.get_ntlmv1_response(nthash) 3368 elif password: 3369 lmhash = ntlm.compute_lmhash(password) 3370 nthash = ntlm.compute_nthash(password) 3371 pwd_ansi = self.get_ntlmv1_response(lmhash) 3372 pwd_unicode = self.get_ntlmv1_response(nthash) 3373 else: # NULL SESSION 3374 pwd_ansi = '' 3375 pwd_unicode = '' 3376 else: 3377 pwd_ansi = password 3378 pwd_unicode = '' 3379 3380 smb = NewSMBPacket() 3381 3382 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) 3383 sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters() 3384 sessionSetup['Data'] = SMBSessionSetupAndX_Data() 3385 3386 sessionSetup['Parameters']['MaxBuffer'] = 61440 3387 sessionSetup['Parameters']['MaxMpxCount'] = 2 3388 sessionSetup['Parameters']['VCNumber'] = os.getpid() 3389 sessionSetup['Parameters']['SessionKey'] = self._dialects_parameters['SessionKey'] 3390 sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi) 3391 sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode) 3392 sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE | SMB.CAP_USE_NT_ERRORS | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX 3393 3394 sessionSetup['Data']['AnsiPwd'] = pwd_ansi 3395 sessionSetup['Data']['UnicodePwd'] = pwd_unicode 3396 sessionSetup['Data']['Account'] = str(user) 3397 sessionSetup['Data']['PrimaryDomain'] = str(domain) 3398 sessionSetup['Data']['NativeOS'] = str(os.name) 3399 sessionSetup['Data']['NativeLanMan'] = 'pysmb' 3400 smb.addCommand(sessionSetup) 3401 3402 self.sendSMB(smb) 3403 3404 smb = self.recvSMB() 3405 if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): 3406 # We will need to use this uid field for all future requests/responses 3407 self._uid = smb['Uid'] 3408 sessionResponse = SMBCommand(smb['Data'][0]) 3409 sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) 3410 sessionData = SMBSessionSetupAndXResponse_Data(flags = smb['Flags2'], data = sessionResponse['Data']) 3411 3412 self._action = sessionParameters['Action'] 3413 3414 # Still gotta figure out how to do this with no EXTENDED_SECURITY 3415 if sessionParameters['Action'] & SMB_SETUP_USE_LANMAN_KEY == 0: 3416 self._SigningChallengeResponse = sessionSetup['Data']['UnicodePwd'] 3417 self._SigningSessionKey = nthash 3418 else: 3419 self._SigningChallengeResponse = sessionSetup['Data']['AnsiPwd'] 3420 self._SigningSessionKey = lmhash 3421 3422 #self._SignSequenceNumber = 1 3423 #self.checkSignSMB(smb, self._SigningSessionKey ,self._SigningChallengeResponse) 3424 #self._SignatureEnabled = True 3425 self.__server_os = sessionData['NativeOS'] 3426 self.__server_lanman = sessionData['NativeLanMan'] 3427 self.__server_domain = sessionData['PrimaryDomain'] 3428 3429 # restore unicode flag if needed 3430 if flags2 & SMB.FLAGS2_UNICODE: 3431 self.__flags2 |= SMB.FLAGS2_UNICODE 3432 3433 return 1 3434 else: raise Exception('Error: Could not login successfully') 3435 3436 def waitNamedPipe(self, tid, pipe, timeout = 5, noAnswer = 0): 3437 smb = NewSMBPacket() 3438 smb['Tid'] = tid 3439 3440 transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION) 3441 transCommand['Parameters'] = SMBTransaction_Parameters() 3442 transCommand['Data'] = SMBTransaction_Data() 3443 3444 setup = '\x53\x00\x00\x00' 3445 name = '\\PIPE%s\x00' % pipe 3446 transCommand['Parameters']['Setup'] = setup 3447 transCommand['Parameters']['TotalParameterCount'] = 0 3448 transCommand['Parameters']['TotalDataCount'] = 0 3449 transCommand['Parameters']['MaxParameterCount'] = 0 3450 transCommand['Parameters']['MaxDataCount'] = 0 3451 transCommand['Parameters']['Timeout'] = timeout * 1000 3452 3453 transCommand['Parameters']['ParameterCount'] = 0 3454 transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name) 3455 3456 transCommand['Parameters']['DataCount'] = 0 3457 transCommand['Parameters']['DataOffset'] = 0 3458 3459 transCommand['Data']['Name'] = name 3460 transCommand['Data']['Trans_Parameters'] = '' 3461 transCommand['Data']['Trans_Data'] = '' 3462 3463 if noAnswer: 3464 transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE 3465 3466 smb.addCommand(transCommand) 3467 self.sendSMB(smb) 3468 3469 smb = self.recvSMB() 3470 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 3471 return 1 3472 return 0 3473 3474 def read(self, tid, fid, offset=0, max_size = None, wait_answer=1): 3475 if not max_size: 3476 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 3477 3478 # max_size is not working, because although it would, the server returns an error (More data avail) 3479 3480 smb = NewSMBPacket() 3481 smb['Tid'] = tid 3482 3483 read = SMBCommand(SMB.SMB_COM_READ) 3484 read['Parameters'] = SMBRead_Parameters() 3485 read['Parameters']['Fid'] = fid 3486 read['Parameters']['Offset'] = offset 3487 read['Parameters']['Count'] = max_size 3488 smb.addCommand(read) 3489 3490 if wait_answer: 3491 while 1: 3492 self.sendSMB(smb) 3493 ans = self.recvSMB() 3494 3495 if ans.isValidAnswer(SMB.SMB_COM_READ): 3496 readResponse = SMBCommand(ans['Data'][0]) 3497 readData = SMBReadResponse_Data(readResponse['Data']) 3498 3499 return readData['Data'] 3500 3501 return None 3502 3503 def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, smb_packet=None): 3504 if not max_size: 3505 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False: 3506 max_size = 65000 3507 else: 3508 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 3509 3510 # max_size is not working, because although it would, the server returns an error (More data avail) 3511 3512 if smb_packet is None: 3513 smb = NewSMBPacket() 3514 smb['Tid'] = tid 3515 3516 readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX) 3517 readAndX['Parameters'] = SMBReadAndX_Parameters() 3518 readAndX['Parameters']['Fid'] = fid 3519 readAndX['Parameters']['Offset'] = offset 3520 readAndX['Parameters']['MaxCount'] = max_size 3521 smb.addCommand(readAndX) 3522 else: 3523 smb = smb_packet 3524 3525 if wait_answer: 3526 answer = '' 3527 while 1: 3528 self.sendSMB(smb) 3529 ans = self.recvSMB() 3530 3531 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 3532 # XXX Here we are only using a few fields from the response 3533 readAndXResponse = SMBCommand(ans['Data'][0]) 3534 readAndXParameters = SMBReadAndXResponse_Parameters(readAndXResponse['Parameters']) 3535 3536 offset = readAndXParameters['DataOffset'] 3537 count = readAndXParameters['DataCount']+0x10000*readAndXParameters['DataCount_Hi'] 3538 answer += str(ans)[offset:offset+count] 3539 if not ans.isMoreData(): 3540 return answer 3541 max_size = min(max_size, readAndXParameters['Remaining']) 3542 readAndX['Parameters']['Offset'] += count # XXX Offset is not important (apparently) 3543 else: 3544 self.sendSMB(smb) 3545 ans = self.recvSMB() 3546 3547 try: 3548 if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): 3549 return ans 3550 else: 3551 return None 3552 except: 3553 return ans 3554 3555 return None 3556 3557 def read_raw(self, tid, fid, offset=0, max_size = None, wait_answer=1): 3558 if not max_size: 3559 max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks 3560 3561 # max_size is not working, because although it would, the server returns an error (More data avail) 3562 smb = NewSMBPacket() 3563 smb['Tid'] = tid 3564 3565 readRaw = SMBCommand(SMB.SMB_COM_READ_RAW) 3566 readRaw['Parameters'] = SMBReadRaw_Parameters() 3567 readRaw['Parameters']['Fid'] = fid 3568 readRaw['Parameters']['Offset'] = offset 3569 readRaw['Parameters']['MaxCount'] = max_size 3570 smb.addCommand(readRaw) 3571 3572 self.sendSMB(smb) 3573 if wait_answer: 3574 data = self._sess.recv_packet(self.__timeout).get_trailer() 3575 if not data: 3576 # If there is no data it means there was an error 3577 data = self.read_andx(tid, fid, offset, max_size) 3578 return data 3579 3580 return None 3581 3582 def write(self,tid,fid,data, offset = 0, wait_answer=1): 3583 smb = NewSMBPacket() 3584 smb['Tid'] = tid 3585 3586 write = SMBCommand(SMB.SMB_COM_WRITE) 3587 write['Parameters'] = SMBWrite_Parameters() 3588 write['Data'] = SMBWrite_Data() 3589 write['Parameters']['Fid'] = fid 3590 write['Parameters']['Count'] = len(data) 3591 write['Parameters']['Offset'] = offset 3592 write['Parameters']['Remaining'] = len(data) 3593 write['Data']['Data'] = data 3594 smb.addCommand(write) 3595 3596 self.sendSMB(smb) 3597 3598 if wait_answer: 3599 smb = self.recvSMB() 3600 if smb.isValidAnswer(SMB.SMB_COM_WRITE): 3601 return smb 3602 return None 3603 3604 def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, write_pipe_mode = False, smb_packet=None): 3605 if smb_packet is None: 3606 smb = NewSMBPacket() 3607 smb['Tid'] = tid 3608 3609 writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX) 3610 smb.addCommand(writeAndX) 3611 3612 writeAndX['Parameters'] = SMBWriteAndX_Parameters() 3613 writeAndX['Parameters']['Fid'] = fid 3614 writeAndX['Parameters']['Offset'] = offset 3615 writeAndX['Parameters']['WriteMode'] = 8 3616 writeAndX['Parameters']['Remaining'] = len(data) 3617 writeAndX['Parameters']['DataLength'] = len(data) 3618 writeAndX['Parameters']['DataOffset'] = len(smb) # this length already includes the parameter 3619 writeAndX['Data'] = data 3620 3621 if write_pipe_mode is True: 3622 # First of all we gotta know what the MaxBuffSize is 3623 maxBuffSize = self._dialects_parameters['MaxBufferSize'] 3624 if len(data) > maxBuffSize: 3625 chunks_size = maxBuffSize - 60 3626 writeAndX['Parameters']['WriteMode'] = 0x0c 3627 sendData = '\xff\xff' + data 3628 totalLen = len(sendData) 3629 writeAndX['Parameters']['DataLength'] = chunks_size 3630 writeAndX['Parameters']['Remaining'] = totalLen-2 3631 writeAndX['Data'] = sendData[:chunks_size] 3632 3633 self.sendSMB(smb) 3634 if wait_answer: 3635 smbResp = self.recvSMB() 3636 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 3637 3638 alreadySent = chunks_size 3639 sendData = sendData[chunks_size:] 3640 3641 while alreadySent < totalLen: 3642 writeAndX['Parameters']['WriteMode'] = 0x04 3643 writeAndX['Parameters']['DataLength'] = len(sendData[:chunks_size]) 3644 writeAndX['Data'] = sendData[:chunks_size] 3645 self.sendSMB(smb) 3646 if wait_answer: 3647 smbResp = self.recvSMB() 3648 smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX) 3649 alreadySent += writeAndX['Parameters']['DataLength'] 3650 sendData = sendData[chunks_size:] 3651 3652 return smbResp 3653 3654 else: 3655 smb = smb_packet 3656 3657 self.sendSMB(smb) 3658 3659 if wait_answer: 3660 smb = self.recvSMB() 3661 if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX): 3662 return smb 3663 return None 3664 3665 def write_raw(self,tid,fid,data, offset = 0, wait_answer=1): 3666 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") 3667 smb = NewSMBPacket() 3668 smb['Tid'] = tid 3669 3670 writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW) 3671 writeRaw['Parameters'] = SMBWriteRaw_Parameters() 3672 writeRaw['Parameters']['Fid'] = fid 3673 writeRaw['Parameters']['Offset'] = offset 3674 writeRaw['Parameters']['Count'] = len(data) 3675 writeRaw['Parameters']['DataLength'] = 0 3676 writeRaw['Parameters']['DataOffset'] = 0 3677 smb.addCommand(writeRaw) 3678 3679 self.sendSMB(smb) 3680 self._sess.send_packet(data) 3681 3682 if wait_answer: 3683 smb = self.recvSMB() 3684 if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW): 3685 return smb 3686 return None 3687 3688 def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer = 1, offset = 0): 3689 self.send_trans(tid,pack('<HH', 0x26, fid),'\\PIPE\\\x00','',data, noAnswer = noAnswer) 3690 3691 if noAnswer or not waitAnswer: 3692 return 3693 smb = self.recvSMB() 3694 if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION): 3695 transResponse = SMBCommand(smb['Data'][0]) 3696 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 3697 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 3698 return None 3699 3700 def TransactNamedPipeRecv(self): 3701 s = self.recvSMB() 3702 if s.isValidAnswer(SMB.SMB_COM_TRANSACTION): 3703 transResponse = SMBCommand(s['Data'][0]) 3704 transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters']) 3705 return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding 3706 return None 3707 3708 def nt_create_andx(self,tid,filename, smb_packet=None, cmd = None, shareAccessMode = FILE_SHARE_READ | FILE_SHARE_WRITE, disposition = FILE_OPEN, accessMask = 0x2019f): 3709 filename = filename.replace('/', '\\') 3710 filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename 3711 3712 if smb_packet is None: 3713 smb = NewSMBPacket() 3714 smb['Tid'] = tid 3715 else: 3716 smb = smb_packet 3717 3718 if cmd is None: 3719 ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) 3720 ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() 3721 ntCreate['Data'] = SMBNtCreateAndX_Data(flags=self.__flags2) 3722 ntCreate['Parameters']['FileNameLength'] = len(filename) 3723 ntCreate['Parameters']['CreateFlags'] = 0x16 3724 ntCreate['Parameters']['AccessMask'] = accessMask 3725 ntCreate['Parameters']['CreateOptions'] = 0x40 3726 ntCreate['Parameters']['ShareAccess'] = shareAccessMode 3727 ntCreate['Parameters']['Disposition'] = disposition 3728 ntCreate['Data']['FileName'] = filename 3729 3730 if self.__flags2 & SMB.FLAGS2_UNICODE: 3731 ntCreate['Data']['Pad'] = 0x0 3732 else: 3733 ntCreate = cmd 3734 3735 smb.addCommand(ntCreate) 3736 3737 self.sendSMB(smb) 3738 3739 while 1: 3740 smb = self.recvSMB() 3741 if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX): 3742 # XXX Here we are ignoring the rest of the response 3743 ntCreateResponse = SMBCommand(smb['Data'][0]) 3744 ntCreateParameters = SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters']) 3745 3746 self.fid = ntCreateParameters['Fid'] 3747 return ntCreateParameters['Fid'] 3748 3749 def logoff(self): 3750 smb = NewSMBPacket() 3751 3752 logOff = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX) 3753 logOff['Parameters'] = SMBLogOffAndX() 3754 smb.addCommand(logOff) 3755 3756 self.sendSMB(smb) 3757 self.recvSMB() 3758 # Let's clear some fields so you can login again under the same session 3759 self._uid = 0 3760 3761 def list_path(self, service, path = '*', password = None): 3762 path = path.replace('/', '\\') 3763 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 3764 3765 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3766 try: 3767 findFirstParameter = SMBFindFirst2_Parameters() 3768 findFirstParameter['SearchAttributes'] = SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_HIDDEN | \ 3769 SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_READONLY | \ 3770 SMB_FILE_ATTRIBUTE_ARCHIVE 3771 findFirstParameter['SearchCount'] = 512 3772 findFirstParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 3773 findFirstParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 3774 findFirstParameter['SearchStorageType'] = 0 3775 findFirstParameter['FileName'] = path + ('\x00\x00' if self.__flags2 & SMB.FLAGS2_UNICODE else '\x00') 3776 self.send_trans2(tid, SMB.TRANS2_FIND_FIRST2, '\x00', findFirstParameter, '') 3777 files = [ ] 3778 3779 totalDataCount = 1 3780 findData = '' 3781 findFirst2ParameterBlock = '' 3782 while len(findData) < totalDataCount: 3783 resp = self.recvSMB() 3784 3785 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 3786 trans2Response = SMBCommand(resp['Data'][0]) 3787 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 3788 totalDataCount = trans2Parameters['TotalDataCount'] 3789 findFirst2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 3790 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 3791 3792 findParameterBlock = SMBFindFirst2Response_Parameters(findFirst2ParameterBlock) 3793 # Save the SID for resume operations 3794 sid = findParameterBlock['SID'] 3795 3796 while True: 3797 record = SMBFindFileBothDirectoryInfo(data = findData) 3798 3799 shortname = record['ShortName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else record['ShortName'] 3800 filename = record['FileName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else record['FileName'] 3801 3802 fileRecord = SharedFile(record['CreationTime'], record['LastAccessTime'], record['LastChangeTime'], 3803 record['EndOfFile'], record['AllocationSize'], record['ExtFileAttributes'], 3804 shortname, filename) 3805 files.append(fileRecord) 3806 if record['NextEntryOffset'] > 0 and len(findData[record['NextEntryOffset']:]) > 0: 3807 findData = findData[record['NextEntryOffset']:] 3808 else: 3809 # More data to search? 3810 if findParameterBlock['EndOfSearch'] == 0: 3811 resume_filename = record['FileName'] 3812 findNextParameter = SMBFindNext2_Parameters() 3813 findNextParameter['SID'] = sid 3814 findNextParameter['SearchCount'] = 1024 3815 findNextParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO 3816 findNextParameter['ResumeKey'] = 0 3817 findNextParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS 3818 findNextParameter['FileName'] = resume_filename + ('\x00\x00' if self.__flags2 & SMB.FLAGS2_UNICODE else '\x00') 3819 self.send_trans2(tid, SMB.TRANS2_FIND_NEXT2, '\x00', findNextParameter, '') 3820 findData = '' 3821 findNext2ParameterBlock = '' 3822 totalDataCount = 1 3823 while len(findData) < totalDataCount: 3824 resp = self.recvSMB() 3825 3826 if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2): 3827 trans2Response = SMBCommand(resp['Data'][0]) 3828 trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters']) 3829 totalDataCount = trans2Parameters['TotalDataCount'] 3830 findNext2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']] 3831 findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:] 3832 findParameterBlock = SMBFindNext2Response_Parameters(findNext2ParameterBlock) 3833 else: 3834 break 3835 finally: 3836 self.disconnect_tree(tid) 3837 3838 return files 3839 3840 def retr_file(self, service, filename, callback, mode = FILE_OPEN, offset = 0, password = None, shareAccessMode = SMB_ACCESS_READ): 3841 filename = string.replace(filename, '/', '\\') 3842 3843 fid = -1 3844 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3845 try: 3846 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, accessMask = 0x20089) 3847 3848 res = self.query_file_info(tid, fid) 3849 datasize = SMBQueryFileStandardInfo(res)['EndOfFile'] 3850 3851 self.__nonraw_retr_file(tid, fid, offset, datasize, callback) 3852 finally: 3853 if fid >= 0: 3854 self.close(tid, fid) 3855 self.disconnect_tree(tid) 3856 3857 def stor_file(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE): 3858 filename = string.replace(filename, '/', '\\') 3859 3860 fid = -1 3861 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3862 try: 3863 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode ) 3864 3865 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 3866 finally: 3867 if fid >= 0: 3868 self.close(tid, fid) 3869 self.disconnect_tree(tid) 3870 3871 def stor_file_nonraw(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE ): 3872 filename = string.replace(filename, '/', '\\') 3873 3874 fid = -1 3875 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3876 try: 3877 fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode) 3878 self.__nonraw_stor_file(tid, fid, offset, 0, callback) 3879 finally: 3880 if fid >= 0: 3881 self.close(tid, fid) 3882 self.disconnect_tree(tid) 3883 3884 def check_dir(self, service, path, password = None): 3885 path = string.replace(path,'/', '\\') 3886 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3887 try: 3888 smb = NewSMBPacket() 3889 smb['Tid'] = tid 3890 smb['Mid'] = 0 3891 3892 cmd = SMBCommand(SMB.SMB_COM_CHECK_DIRECTORY) 3893 cmd['Parameters'] = '' 3894 cmd['Data'] = SMBCheckDirectory_Data(flags = self.__flags2) 3895 cmd['Data']['DirectoryName'] = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 3896 smb.addCommand(cmd) 3897 3898 self.sendSMB(smb) 3899 3900 while 1: 3901 s = self.recvSMB() 3902 if s.isValidAnswer(SMB.SMB_COM_CHECK_DIRECTORY): 3903 return 3904 finally: 3905 self.disconnect_tree(tid) 3906 3907 def remove(self, service, path, password = None): 3908 path = string.replace(path,'/', '\\') 3909 # Perform a list to ensure the path exists 3910 self.list_path(service, path, password) 3911 3912 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3913 try: 3914 smb = NewSMBPacket() 3915 smb['Tid'] = tid 3916 smb['Mid'] = 0 3917 3918 cmd = SMBCommand(SMB.SMB_COM_DELETE) 3919 cmd['Parameters'] = SMBDelete_Parameters() 3920 cmd['Parameters']['SearchAttributes'] = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE 3921 cmd['Data'] = SMBDelete_Data(flags = self.__flags2) 3922 cmd['Data']['FileName'] = (path + '\x00').encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else (path + '\x00') 3923 smb.addCommand(cmd) 3924 3925 self.sendSMB(smb) 3926 3927 while 1: 3928 s = self.recvSMB() 3929 if s.isValidAnswer(SMB.SMB_COM_DELETE): 3930 return 3931 finally: 3932 self.disconnect_tree(tid) 3933 3934 def rmdir(self, service, path, password = None): 3935 path = string.replace(path,'/', '\\') 3936 # Check that the directory exists 3937 self.check_dir(service, path, password) 3938 3939 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3940 try: 3941 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 3942 3943 smb = NewSMBPacket() 3944 smb['Tid'] = tid 3945 createDir = SMBCommand(SMB.SMB_COM_DELETE_DIRECTORY) 3946 createDir['Data'] = SMBDeleteDirectory_Data(flags=self.__flags2) 3947 createDir['Data']['DirectoryName'] = path 3948 smb.addCommand(createDir) 3949 3950 self.sendSMB(smb) 3951 3952 while 1: 3953 s = self.recvSMB() 3954 if s.isValidAnswer(SMB.SMB_COM_DELETE_DIRECTORY): 3955 return 3956 finally: 3957 self.disconnect_tree(tid) 3958 3959 def mkdir(self, service, path, password = None): 3960 path = string.replace(path,'/', '\\') 3961 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3962 try: 3963 path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path 3964 3965 smb = NewSMBPacket() 3966 smb['Tid'] = tid 3967 smb['Mid'] = 0 3968 3969 createDir = SMBCommand(SMB.SMB_COM_CREATE_DIRECTORY) 3970 createDir['Data'] = SMBCreateDirectory_Data(flags=self.__flags2) 3971 createDir['Data']['DirectoryName'] = path 3972 smb.addCommand(createDir) 3973 3974 self.sendSMB(smb) 3975 3976 smb = self.recvSMB() 3977 if smb.isValidAnswer(SMB.SMB_COM_CREATE_DIRECTORY): 3978 return 1 3979 return 0 3980 finally: 3981 self.disconnect_tree(tid) 3982 3983 def rename(self, service, old_path, new_path, password = None): 3984 old_path = string.replace(old_path,'/', '\\') 3985 new_path = string.replace(new_path,'/', '\\') 3986 tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password) 3987 try: 3988 smb = NewSMBPacket() 3989 smb['Tid'] = tid 3990 smb['Mid'] = 0 3991 3992 renameCmd = SMBCommand(SMB.SMB_COM_RENAME) 3993 renameCmd['Parameters'] = SMBRename_Parameters() 3994 renameCmd['Parameters']['SearchAttributes'] = ATTR_SYSTEM | ATTR_HIDDEN | ATTR_DIRECTORY 3995 renameCmd['Data'] = SMBRename_Data(flags = self.__flags2) 3996 renameCmd['Data']['OldFileName'] = old_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else old_path 3997 renameCmd['Data']['NewFileName'] = new_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else new_path 3998 smb.addCommand(renameCmd) 3999 4000 self.sendSMB(smb) 4001 4002 smb = self.recvSMB() 4003 if smb.isValidAnswer(SMB.SMB_COM_RENAME): 4004 return 1 4005 return 0 4006 finally: 4007 self.disconnect_tree(tid) 4008 4009 def writeFile(self, treeId, fileId, data, offset = 0): 4010 if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False: 4011 max_buf_size = 65000 4012 else: 4013 max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks 4014 4015 write_offset = offset 4016 while 1: 4017 if len(data) == 0: 4018 break 4019 writeData = data[:max_buf_size] 4020 data = data[max_buf_size:] 4021 4022 smb = self.write_andx(treeId,fileId,writeData, write_offset) 4023 writeResponse = SMBCommand(smb['Data'][0]) 4024 writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters']) 4025 write_offset += writeResponseParameters['Count'] 4026 4027 def get_socket(self): 4028 return self._sess.get_socket() 4029 4030 ERRDOS = { 1: 'Invalid function', 4031 2: 'File not found', 4032 3: 'Invalid directory', 4033 4: 'Too many open files', 4034 5: 'Access denied', 4035 6: 'Invalid file handle. Please file a bug report.', 4036 7: 'Memory control blocks destroyed', 4037 8: 'Out of memory', 4038 9: 'Invalid memory block address', 4039 10: 'Invalid environment', 4040 11: 'Invalid format', 4041 12: 'Invalid open mode', 4042 13: 'Invalid data', 4043 15: 'Invalid drive', 4044 16: 'Attempt to remove server\'s current directory', 4045 17: 'Not the same device', 4046 18: 'No files found', 4047 32: 'Sharing mode conflicts detected', 4048 33: 'Lock request conflicts detected', 4049 80: 'File already exists' 4050 } 4051 4052 ERRSRV = { 1: 'Non-specific error', 4053 2: 'Bad password', 4054 4: 'Access denied', 4055 5: 'Invalid tid. Please file a bug report.', 4056 6: 'Invalid network name', 4057 7: 'Invalid device', 4058 49: 'Print queue full', 4059 50: 'Print queue full', 4060 51: 'EOF on print queue dump', 4061 52: 'Invalid print file handle', 4062 64: 'Command not recognized. Please file a bug report.', 4063 65: 'Internal server error', 4064 67: 'Invalid path', 4065 69: 'Invalid access permissions', 4066 71: 'Invalid attribute mode', 4067 81: 'Server is paused', 4068 82: 'Not receiving messages', 4069 83: 'No room to buffer messages', 4070 87: 'Too many remote user names', 4071 88: 'Operation timeout', 4072 89: 'Out of resources', 4073 91: 'Invalid user handle. Please file a bug report.', 4074 250: 'Temporarily unable to support raw mode for transfer', 4075 251: 'Temporarily unable to support raw mode for transfer', 4076 252: 'Continue in MPX mode', 4077 65535: 'Unsupported function' 4078 } 4079 4080 ERRHRD = { 19: 'Media is write-protected', 4081 20: 'Unknown unit', 4082 21: 'Drive not ready', 4083 22: 'Unknown command', 4084 23: 'CRC error', 4085 24: 'Bad request', 4086 25: 'Seek error', 4087 26: 'Unknown media type', 4088 27: 'Sector not found', 4089 28: 'Printer out of paper', 4090 29: 'Write fault', 4091 30: 'Read fault', 4092 31: 'General failure', 4093 32: 'Open conflicts with an existing open', 4094 33: 'Invalid lock request', 4095 34: 'Wrong disk in drive', 4096 35: 'FCBs not available', 4097 36: 'Sharing buffer exceeded' 4098 } 4099 4100