1# -*- coding: utf-8 -*- 2# Copyright: (c) 2019, Jordan Borean (@jborean93) <jborean93@gmail.com> 3# MIT License (see LICENSE or https://opensource.org/licenses/MIT) 4 5from collections import ( 6 OrderedDict, 7) 8 9from smbprotocol.header import ( 10 NtStatus, 11) 12 13from smbprotocol.structure import ( 14 BoolField, 15 BytesField, 16 DateTimeField, 17 EnumField, 18 FlagField, 19 IntField, 20 Structure, 21 UuidField, 22) 23 24 25class CreateContextName(object): 26 """ 27 [MS-SMB2] v53.0 2017-09-15 28 29 2.2.13.2 SMB2_CREATE_CONTEXT Request Values 30 Valid names for the name to set on a SMB2_CREATE_CONTEXT Request entry 31 """ 32 SMB2_CREATE_EA_BUFFER = b"\x45\x78\x74\x41" 33 34 # note: the structures for this are located in security_descriptor.py 35 SMB2_CREATE_SD_BUFFER = b"\x53\x65\x63\x44" 36 SMB2_CREATE_DURABLE_HANDLE_REQUEST = b"\x44\x48\x6e\x51" 37 SMB2_CREATE_DURABLE_HANDLE_RECONNECT = b"\x44\x48\x6e\x43" 38 SMB2_CREATE_ALLOCATION_SIZE = b"\x41\x6c\x53\x69" 39 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST = b"\x4d\x78\x41\x63" 40 SMB2_CREATE_TIMEWARP_TOKEN = b"\x54\x57\x72\x70" 41 SMB2_CREATE_QUERY_ON_DISK_ID = b"\x51\x46\x69\x64" 42 SMB2_CREATE_REQUEST_LEASE = b"\x52\x71\x4c\x73" 43 SMB2_CREATE_REQUEST_LEASE_V2 = b"\x52\x71\x4c\x73" 44 SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 = b"\x44\x48\x32\x51" 45 SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 = b"\x44\x48\x32\x43" 46 SMB2_CREATE_APP_INSTANCE_ID = b"\x45\xBC\xA6\x6A\xEF\xA7\xF7\x4A" \ 47 b"\x90\x08\xFA\x46\x2E\x14\x4D\x74" 48 SMB2_CREATE_APP_INSTANCE_VERSION = b"\xB9\x82\xD0\xB7\x3B\x56\x07\x4F" \ 49 b"\xA0\x7B\x52\x4A\x81\x16\xA0\x10" 50 SVHDX_OPEN_DEVICE_CONTEXT = b"\x9C\xCB\xCF\x9E\x04\xC1\xE6\x43" \ 51 b"\x98\x0E\x15\x8D\xA1\xF6\xEC\x83" 52 53 @staticmethod 54 def get_response_structure(name, size=None): 55 """ 56 Returns the response structure for a know list of create context 57 responses. 58 59 :param name: The constant value above 60 :param size: Specify the size of the context buffer, used to differenciate between REQUEST_LEASE and 61 REQUEST_LEASE_V2. 62 :return: The response structure or None if unknown 63 """ 64 # Special handling for request lease here the header name has the same value, use the size to differenciate. 65 if name == CreateContextName.SMB2_CREATE_REQUEST_LEASE: 66 return { 67 32: SMB2CreateResponseLease(), 68 52: SMB2CreateResponseLeaseV2(), 69 }.get(size, None) 70 71 return { 72 CreateContextName.SMB2_CREATE_DURABLE_HANDLE_REQUEST: SMB2CreateDurableHandleResponse(), 73 CreateContextName.SMB2_CREATE_DURABLE_HANDLE_RECONNECT: SMB2CreateDurableHandleReconnect(), 74 CreateContextName.SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST: SMB2CreateQueryMaximalAccessResponse(), 75 CreateContextName.SMB2_CREATE_QUERY_ON_DISK_ID: SMB2CreateQueryOnDiskIDResponse(), 76 CreateContextName.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2: SMB2CreateDurableHandleResponseV2(), 77 CreateContextName.SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2: SMB2CreateDurableHandleReconnectV2, 78 CreateContextName.SMB2_CREATE_APP_INSTANCE_ID: SMB2CreateAppInstanceId(), 79 CreateContextName.SMB2_CREATE_APP_INSTANCE_VERSION: SMB2CreateAppInstanceVersion() 80 }.get(name, None) 81 82 83class EAFlags(object): 84 """ 85 [MS-FSCC] 86 87 2.4.15 FileFullEaInformation Flags 88 Specifies the flag used when setting extended attributes. 89 """ 90 NONE = 0x0000000 91 FILE_NEED_EA = 0x00000080 92 93 94class LeaseState(object): 95 """ 96 [MS-SMB2] 97 98 2.2.13.2.8 SMB2_CREATE_REQUEST_LEASE LeaseState 99 The requested lease state, field is constructed with a combination of the 100 following values. 101 """ 102 SMB2_LEASE_NONE = 0x00 103 SMB2_LEASE_READ_CACHING = 0x01 104 SMB2_LEASE_HANDLE_CACHING = 0x02 105 SMB2_LEASE_WRITE_CACHING = 0x04 106 107 108class LeaseRequestFlags(object): 109 """ 110 [MS-SMB2] 111 112 2.2.13.2.10 SMB2_CREATE_REQUEST_LEASE_V2 113 The flags to use on an SMB2CreateRequestLeaseV2 packet. 114 """ 115 SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET = 0x00000004 116 117 118class LeaseResponseFlags(object): 119 """ 120 [MS-SMB2] 121 122 2.2.14.2.10 SMB2_CREATE_RESPONSE_LEASE 123 """ 124 SMB2_LEASE_FLAG_BREAK_IN_PROGRESS = 0x00000002 125 SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET = 0x00000004 # V2 Response 126 127 128class DurableHandleFlags(object): 129 """ 130 [MS-SMB2] 131 132 2.2.13.2.11 SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 133 Flags used on an SMB2CreateDurableHandleRequestV2 packet. 134 """ 135 SMB2_DHANDLE_FLAG_PERSISTENT = 0x00000002 136 137 138class SVHDXOriginatorFlags(object): 139 """ 140 [MS-RSVD] 2.2.4.12 SVHDX_OPEN_DEVICE_CONTEXT OriginatorFlags 141 Used to indicate which component has originated or issued the operations. 142 """ 143 SVHDX_ORIGINATOR_PVHDPARSER = 0x00000001 144 SVHDX_ORIGINATOR_VHDMP = 0x00000004 145 146 147class SMB2CreateContextRequest(Structure): 148 """ 149 [MS-SMB2] v53.0 2017-09-15 150 151 2.2.13.2 SMB2_CREATE_CONTEXT Request Values 152 Structure used in the SMB2 CREATE Request and SMB2 CREATE Response to 153 encode additional flags and attributes 154 """ 155 156 def __init__(self): 157 self.fields = OrderedDict([ 158 ('next', IntField(size=4)), 159 ('name_offset', IntField( 160 size=2, 161 default=16 162 )), 163 ('name_length', IntField( 164 size=2, 165 default=lambda s: len(s['buffer_name']) 166 )), 167 ('reserved', IntField(size=2)), 168 ('data_offset', IntField( 169 size=2, 170 default=lambda s: self._buffer_data_offset(s) 171 )), 172 ('data_length', IntField( 173 size=4, 174 default=lambda s: len(s['buffer_data']) 175 )), 176 ('buffer_name', BytesField( 177 size=lambda s: s['name_length'].get_value() 178 )), 179 ('padding', BytesField( 180 size=lambda s: self._padding_size(s), 181 default=lambda s: b"\x00" * self._padding_size(s) 182 )), 183 ('buffer_data', BytesField( 184 size=lambda s: s['data_length'].get_value() 185 )), 186 # not actually a field but each list entry must start at the 8 byte 187 # alignment 188 ('padding2', BytesField( 189 size=lambda s: self._padding2_size(s), 190 default=lambda s: b"\x00" * self._padding2_size(s) 191 )) 192 ]) 193 super(SMB2CreateContextRequest, self).__init__() 194 195 def _buffer_data_offset(self, structure): 196 if structure['data_length'].get_value() == 0: 197 return 0 198 else: 199 return structure['name_offset'].get_value() + \ 200 len(structure['buffer_name']) + len(structure['padding']) 201 202 def _padding_size(self, structure): 203 if structure['data_length'].get_value() == 0: 204 return 0 205 206 buffer_name_len = structure['name_length'].get_value() 207 mod = buffer_name_len % 8 208 return mod if mod == 0 else 8 - mod 209 210 def _padding2_size(self, structure): 211 data_length = len(structure['buffer_name']) + \ 212 len(structure['padding']) + len(structure['buffer_data']) 213 mod = data_length % 8 214 return mod if mod == 0 else 8 - mod 215 216 def get_context_data(self): 217 """ 218 Get the buffer_data value of a context response and try to convert it 219 to the relevant structure based on the buffer_name used. If it is an 220 unknown structure then the raw bytes are returned. 221 222 :return: relevant Structure of buffer_data or bytes if unknown name 223 """ 224 buffer_name = self['buffer_name'].get_value() 225 structure = CreateContextName.get_response_structure(buffer_name, size=self['data_length'].get_value()) 226 if structure: 227 structure.unpack(self['buffer_data'].get_value()) 228 return structure 229 else: 230 # unknown structure, just return the raw bytes 231 return self['buffer_data'].get_value() 232 233 @staticmethod 234 def pack_multiple(messages): 235 """ 236 Converts a list of SMB2CreateContextRequest structures and packs them 237 as a bytes object used when setting to the SMB2CreateRequest 238 buffer_contexts field. This should be used as it would calculate the 239 correct next field value for each context entry. 240 241 :param messages: List of SMB2CreateContextRequest structures 242 :return: bytes object that is set on the SMB2CreateRequest 243 buffer_contexts field. 244 """ 245 data = b"" 246 msg_count = len(messages) 247 for i, msg in enumerate(messages): 248 if not isinstance(msg, SMB2CreateContextRequest): 249 buffer = msg 250 buffer_name = getattr(msg, 'NAME', None) 251 if buffer_name is None: 252 raise ValueError("Invalid context message, must be either a SMB2CreateContextRequest or a " 253 "predefined structure object with NAME defined.") 254 msg = SMB2CreateContextRequest() 255 msg['buffer_name'] = buffer_name 256 msg['buffer_data'] = buffer 257 258 if i == msg_count - 1: 259 msg['next'] = 0 260 else: 261 # because the end padding2 val won't be populated if the entry 262 # offset is 0, we set to 1 so the len calc is correct 263 msg['next'] = 1 264 msg['next'] = len(msg) 265 266 data += msg.pack() 267 return data 268 269 270class SMB2CreateEABuffer(Structure): 271 """ 272 [MS-SMB2] 2.2.13.2.1 SMB2_CREATE_EA_BUFFER 273 [MS-FSCC] 2.4.15 FileFullEaInformation 274 275 Used to apply extended attributes as part of creating a new file. 276 """ 277 278 NAME = CreateContextName.SMB2_CREATE_EA_BUFFER 279 280 def __init__(self): 281 self.fields = OrderedDict([ 282 # 0 if no more entries, otherwise offset after ea_value 283 ('next_entry_offset', IntField(size=4)), 284 ('flags', FlagField( 285 size=1, 286 flag_type=EAFlags 287 )), 288 ('ea_name_length', IntField( 289 size=1, 290 default=lambda s: len(s['ea_name']) - 1 # minus \x00 291 )), 292 ('ea_value_length', IntField( 293 size=2, 294 default=lambda s: len(s['ea_value']) 295 )), 296 # ea_name is ASCII byte encoded and needs a null terminator '\x00' 297 ('ea_name', BytesField( 298 size=lambda s: s['ea_name_length'].get_value() + 1 299 )), 300 ('ea_value', BytesField( 301 size=lambda s: s['ea_value_length'].get_value() 302 )), 303 # not actually a field but each list entry must start at the 4 byte 304 # alignment 305 ('padding', BytesField( 306 size=lambda s: self._padding_size(s), 307 default=lambda s: b"\x00" * self._padding_size(s) 308 )) 309 ]) 310 super(SMB2CreateEABuffer, self).__init__() 311 312 def _padding_size(self, structure): 313 if structure['next_entry_offset'].get_value() == 0: 314 return 0 315 316 data_length = len(structure['ea_name']) + len(structure['ea_value']) 317 mod = data_length % 4 318 return mod if mod == 0 else 4 - mod 319 320 @staticmethod 321 def pack_multiple(messages): 322 """ 323 Converts a list of SMB2CreateEABuffer structures and packs them as a 324 bytes object used when setting to the SMB2CreateContextRequest 325 buffer_data field. This should be used as it would calculate the 326 correct next_entry_offset field value for each buffer entry. 327 328 :param messages: List of SMB2CreateEABuffer structures 329 :return: bytes object that is set on the SMB2CreateContextRequest 330 buffer_data field. 331 """ 332 data = b"" 333 msg_count = len(messages) 334 for i, msg in enumerate(messages): 335 if i == msg_count - 1: 336 msg['next_entry_offset'] = 0 337 else: 338 # because the end padding val won't be populated if the entry 339 # offset is 0, we set to 1 so the len calc is correct 340 msg['next_entry_offset'] = 1 341 msg['next_entry_offset'] = len(msg) 342 data += msg.pack() 343 344 return data 345 346 347class SMB2CreateDurableHandleRequest(Structure): 348 """ 349 [MS-SMB2] 2.2.13.2.3 SMB2_CREATE_DURABLE_HANDLE_REQUEST 350 351 Used by the client to mark the open as a durable open. 352 """ 353 354 NAME = CreateContextName.SMB2_CREATE_DURABLE_HANDLE_REQUEST 355 356 def __init__(self): 357 self.fields = OrderedDict([ 358 ('durable_request', BytesField(size=16, default=b"\x00" * 16)) 359 ]) 360 super(SMB2CreateDurableHandleRequest, self).__init__() 361 362 363class SMB2CreateDurableHandleResponse(Structure): 364 """ 365 [MS-SMB2] 2.2.14.2.3 SMB2_CREATE_DURABLE_HANDLE_RESPONSE 366 367 Sent by the server in response to an SMB2CreateDurableHandleRequest packet. 368 """ 369 370 def __init__(self): 371 self.fields = OrderedDict([ 372 ('reserved', IntField(size=8)) 373 ]) 374 super(SMB2CreateDurableHandleResponse, self).__init__() 375 376 377class SMB2CreateDurableHandleReconnect(Structure): 378 """ 379 [MS-SMB2] 2.2.13.2.4 SMB2_CREATE_DURABLE_HANDLE_RECONNECT 380 381 Used by the client when attempting to reestablish a durable open 382 """ 383 384 NAME = CreateContextName.SMB2_CREATE_DURABLE_HANDLE_RECONNECT 385 386 def __init__(self): 387 self.fields = OrderedDict([ 388 ('data', BytesField(size=16)) 389 ]) 390 super(SMB2CreateDurableHandleReconnect, self).__init__() 391 392 393class SMB2CreateQueryMaximalAccessRequest(Structure): 394 """ 395 [MS-SMB2] 2.2.13.2.5 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST 396 397 Used by the client to retrieve maximal access information as part of 398 processing the open. 399 """ 400 401 NAME = CreateContextName.SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST 402 403 def __init__(self): 404 self.fields = OrderedDict([ 405 ('timestamp', DateTimeField()) 406 ]) 407 super(SMB2CreateQueryMaximalAccessRequest, self).__init__() 408 409 410class SMB2CreateQueryMaximalAccessResponse(Structure): 411 """ 412 [MS-SMB2] 2.2.14.2.5 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_RESPONSE 413 414 Used by the server in response to an SMB2CreateQueryMaximalAccessRequest 415 packet. 416 """ 417 418 def __init__(self): 419 self.fields = OrderedDict([ 420 ('query_status', EnumField( 421 size=4, 422 enum_type=NtStatus, 423 enum_strict=False 424 )), 425 # either FilePipePrinterAccessMask or DirectoryAccessMask 426 ('maximal_access', IntField(size=4)) 427 ]) 428 super(SMB2CreateQueryMaximalAccessResponse, self).__init__() 429 430 431class SMB2CreateAllocationSize(Structure): 432 """ 433 [MS-SMB2] 2.2.13.2.6 SMB2_CREATE_ALLOCATION_SIZE 434 435 Used by the client to set the allocation size of a file that is being 436 newly created or overwritten. 437 """ 438 439 NAME = CreateContextName.SMB2_CREATE_ALLOCATION_SIZE 440 441 def __init__(self): 442 self.fields = OrderedDict([ 443 ('allocation_size', IntField(size=8)) 444 ]) 445 super(SMB2CreateAllocationSize, self).__init__() 446 447 448class SMB2CreateTimewarpToken(Structure): 449 """ 450 [MS-SMB2] 2.2.13.2.7 SMB2_CREATE_TIMEWARP_TOKEN 451 452 Used by the client when requesting the server to open a version of the file 453 at a previous point in time. 454 """ 455 456 NAME = CreateContextName.SMB2_CREATE_TIMEWARP_TOKEN 457 458 def __init__(self): 459 self.fields = OrderedDict([ 460 ('timestamp', DateTimeField()) 461 ]) 462 super(SMB2CreateTimewarpToken, self).__init__() 463 464 465class SMB2CreateRequestLease(Structure): 466 """ 467 [MS-SMB2] 2.2.13.2.8 SMB2_CREATE_REQUEST_LEASE 468 469 Used by the cliet when requesting the server to return a lease. 470 """ 471 472 NAME = CreateContextName.SMB2_CREATE_REQUEST_LEASE 473 474 def __init__(self): 475 self.fields = OrderedDict([ 476 ('lease_key', BytesField(size=16)), 477 ('lease_state', FlagField( 478 size=4, 479 flag_type=LeaseState 480 )), 481 ('lease_flags', IntField(size=4)), 482 ('lease_duration', IntField(size=8)) 483 ]) 484 super(SMB2CreateRequestLease, self).__init__() 485 486 487class SMB2CreateResponseLease(Structure): 488 """ 489 [MS-SMB2] 2.2.14.2.10 SMB2_CREATE_RESPONSE_LEASE 490 491 Sent by the server in response to an SMB2CreateRequestLease 492 """ 493 494 def __init__(self): 495 self.fields = OrderedDict([ 496 ('lease_key', BytesField(size=16)), 497 ('lease_state', FlagField( 498 size=4, 499 flag_type=LeaseState 500 )), 501 ('lease_flags', FlagField( 502 size=4, 503 flag_type=LeaseResponseFlags 504 )), 505 ('lease_duration', IntField(size=8)) 506 ]) 507 super(SMB2CreateResponseLease, self).__init__() 508 509 510class SMB2CreateQueryOnDiskIDResponse(Structure): 511 """ 512 [MS-SMB2] 2.2.14.2.9 SMB2_CREATE_QUERY_ON_DISK_ID 513 514 Sent by the server in response to an SMB2CreateQueryOnDiskIDRequest packet. 515 """ 516 517 NAME = CreateContextName.SMB2_CREATE_QUERY_ON_DISK_ID 518 519 def __init__(self): 520 self.fields = OrderedDict([ 521 ('disk_file_id', IntField(size=8)), 522 ('volume_id', IntField(size=8)), 523 ('reserved', BytesField( 524 size=16, 525 default=b"\x00" * 16 526 )) 527 ]) 528 super(SMB2CreateQueryOnDiskIDResponse, self).__init__() 529 530 531class SMB2CreateRequestLeaseV2(Structure): 532 """ 533 [MS-SMB2] 2.2.13.2.10 SMB2_CREATE_REQUEST_LEASE_V2 534 535 Used when the client is requesting the server to return a lease on a file 536 or directory. 537 Valid for the SMB 3.x family only 538 """ 539 540 NAME = CreateContextName.SMB2_CREATE_REQUEST_LEASE_V2 541 542 def __init__(self): 543 self.fields = OrderedDict([ 544 ('lease_key', BytesField(size=16)), 545 ('lease_state', FlagField( 546 size=4, 547 flag_type=LeaseState 548 )), 549 ('lease_flags', FlagField( 550 size=4, 551 flag_type=LeaseRequestFlags 552 )), 553 ('lease_duration', IntField(size=8)), 554 ('parent_lease_key', BytesField(size=16)), 555 ('epoch', BytesField(size=2)), 556 ('reserved', IntField(size=2)) 557 ]) 558 super(SMB2CreateRequestLeaseV2, self).__init__() 559 560 561class SMB2CreateResponseLeaseV2(Structure): 562 """ 563 [MS-SMB2] 2.2.14.2.11 SMB2_CREATE_RESPONSE_LEASE_V2 564 565 Sent by the server in response to an SMB2CreateRequestLeaseV2 packet. 566 """ 567 568 def __init__(self): 569 self.fields = OrderedDict([ 570 ('lease_key', BytesField(size=16)), 571 ('lease_state', FlagField( 572 size=4, 573 flag_type=LeaseState 574 )), 575 ('flags', FlagField( 576 size=4, 577 flag_type=LeaseResponseFlags 578 )), 579 ('lease_duration', IntField(size=8)), 580 ('parent_lease_key', BytesField(size=16)), 581 ('epoch', IntField(size=2)), 582 ('reserved', IntField(size=2)) 583 ]) 584 super(SMB2CreateResponseLeaseV2, self).__init__() 585 586 587class SMB2CreateDurableHandleRequestV2(Structure): 588 """ 589 [MS-SMB2] 2.2.13.2.11 SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 590 591 Used by the client to request the server mark the open as durable or 592 persistent. 593 Valid for the SMB 3.x family only 594 """ 595 596 NAME = CreateContextName.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 597 598 def __init__(self): 599 self.fields = OrderedDict([ 600 # timeout in milliseconds 601 ('timeout', IntField(size=4)), 602 ('flags', FlagField( 603 size=4, 604 flag_type=DurableHandleFlags 605 )), 606 ('reserved', IntField(size=8)), 607 ('create_guid', UuidField(size=16)) 608 ]) 609 super(SMB2CreateDurableHandleRequestV2, self).__init__() 610 611 612class SMB2CreateDurableHandleReconnectV2(Structure): 613 """ 614 [MS-SMB2] 2.2.13.2.12 SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 615 616 Used by the client when reestablishing a durable open. 617 Valid for the SMB 3.x family only 618 """ 619 620 NAME = CreateContextName.SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 621 622 def __init__(self): 623 self.fields = OrderedDict([ 624 ('file_id', BytesField(size=16)), 625 ('create_guid', UuidField(size=16)), 626 ('flags', FlagField( 627 size=4, 628 flag_type=DurableHandleFlags 629 )) 630 ]) 631 super(SMB2CreateDurableHandleReconnectV2, self).__init__() 632 633 634class SMB2CreateDurableHandleResponseV2(Structure): 635 """ 636 [MS-SMB2] 2.2.14.2.12 SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2 637 638 Sent by the server in response to an SMB2CreateDurableHandleRequestV2 639 packet. 640 """ 641 642 def __init__(self): 643 self.fields = OrderedDict([ 644 ('timeout', IntField(size=4)), 645 ('flags', FlagField( 646 size=4, 647 flag_type=DurableHandleFlags 648 )) 649 ]) 650 super(SMB2CreateDurableHandleResponseV2, self).__init__() 651 652 653class SMB2CreateAppInstanceId(Structure): 654 """ 655 [MS-SMB2] 2.2.13.2.13 SMB2_CREATE_APP_INSTANCE_ID 656 657 Used by the client when supplying an identifier provided by an application. 658 Valid for the SMB 3.x family and should also have an durable handle on the 659 create request. 660 """ 661 662 NAME = CreateContextName.SMB2_CREATE_APP_INSTANCE_ID 663 664 def __init__(self): 665 self.fields = OrderedDict([ 666 ('structure_size', IntField( 667 size=2, 668 default=20 669 )), 670 ('reserved', IntField(size=2)), 671 ('app_instance_id', BytesField(size=16)) 672 ]) 673 super(SMB2CreateAppInstanceId, self).__init__() 674 675 676class SMB2SVHDXOpenDeviceContextRequest(Structure): 677 """ 678 [MS-SMB2] 2.2.13.2.14 SVHDX_OPEN_DEVICE_CONTEXT 679 [MS-RSVD] 2.2.4.12 SVHDX_OPEN_DEVICE_CONTEXT 680 681 Used to open the shared virtual disk file. 682 """ 683 684 NAME = CreateContextName.SVHDX_OPEN_DEVICE_CONTEXT 685 686 def __init__(self): 687 self.fields = OrderedDict([ 688 ('version', IntField( 689 size=4, 690 default=1 691 )), 692 ('has_initiator_id', BoolField( 693 size=1, 694 default=lambda s: len(s['initiator_host_name']) > 0 695 )), 696 ('reserved', BytesField( 697 size=3, 698 default=b"\x00\x00\x00" 699 )), 700 ('initiator_id', UuidField(size=16)), 701 ('originator_flags', EnumField( 702 size=4, 703 enum_type=SVHDXOriginatorFlags 704 )), 705 ('open_request_id', IntField(size=8)), 706 ('initiator_host_name_length', IntField( 707 size=2, 708 default=lambda s: len(s['initiator_host_name']) 709 )), 710 # utf-16-le encoded string 711 ('initiator_host_name', BytesField( 712 size=lambda s: s['initiator_host_name_length'].get_value() 713 )) 714 ]) 715 super(SMB2SVHDXOpenDeviceContextRequest, self).__init__() 716 717 718class SMB2SVHDXOpenDeviceContextResponse(Structure): 719 """ 720 [MS-SMB2] 2.2.14.2.14 SVHDX_OPEN_DEVICE_CONTEXT_RESPONSE 721 [MS-RSVD] 2.2.4.31 SVHDX_OPEN_DEVICE_CONTEXT_RESPONSE 722 723 The response packet sent by the server in response to an 724 SMB2VHDXOpenDeviceContextRequest 725 """ 726 727 def __init__(self): 728 self.fields = OrderedDict([ 729 ('version', IntField( 730 size=4, 731 default=1 732 )), 733 ('has_initiator_id', BoolField( 734 size=1, 735 default=lambda s: len(s['initiator_host_name']) > 0 736 )), 737 ('reserved', BytesField( 738 size=3, 739 default=b"\x00\x00\x00" 740 )), 741 ('initiator_id', UuidField(size=16)), 742 ('flags', IntField(size=4)), 743 ('originator_flags', EnumField( 744 size=4, 745 enum_type=SVHDXOriginatorFlags 746 )), 747 ('open_request_id', IntField(size=8)), 748 ('initiator_host_name_length', IntField( 749 size=2, 750 default=lambda s: len(s['initiator_host_name']) 751 )), 752 # utf-16-le encoded string 753 ('initiator_host_name', BytesField( 754 size=lambda s: s['initiator_host_name_length'].get_value() 755 )) 756 ]) 757 super(SMB2SVHDXOpenDeviceContextResponse, self).__init__() 758 759 760class SMB2SVHDXOpenDeviceContextV2Request(Structure): 761 """ 762 [MS-SMB2] 2.2.13.2.14 SVHDX_OPEN_DEVICE_CONTEXT 763 [MS-RSVD] 2.2.4.32 SVHDX_OPEN_DEVICE_CONTEXT_V2 764 765 Used to open the shared virtual disk file on the RSVD Protocol version 2 766 """ 767 768 NAME = CreateContextName.SVHDX_OPEN_DEVICE_CONTEXT 769 770 def __init__(self): 771 self.fields = OrderedDict([ 772 ('version', IntField( 773 size=4, 774 default=2 775 )), 776 ('has_initiator_id', BoolField( 777 size=1, 778 default=lambda s: len(s['initiator_host_name']) > 0 779 )), 780 ('reserved', BytesField( 781 size=3, 782 default=b"\x00\x00\x00" 783 )), 784 ('initiator_id', UuidField(size=16)), 785 ('originator_flags', EnumField( 786 size=4, 787 enum_type=SVHDXOriginatorFlags 788 )), 789 ('open_request_id', IntField(size=8)), 790 ('initiator_host_name_length', IntField( 791 size=2, 792 default=lambda s: len(s['initiator_host_name']) 793 )), 794 # utf-16-le encoded string 795 ('initiator_host_name', BytesField( 796 size=lambda s: s['initiator_host_name_length'].get_value() 797 )), 798 ('virtual_disk_properties_initialized', IntField(size=4)), 799 ('server_service_version', IntField(size=4)), 800 ('virtual_sector_size', IntField(size=4)), 801 ('physical_sector_size', IntField(size=4)), 802 ('virtual_size', IntField(size=8)) 803 ]) 804 super(SMB2SVHDXOpenDeviceContextV2Request, self).__init__() 805 806 807class SMB2SVHDXOpenDeviceContextV2Response(Structure): 808 """ 809 [MS-SMB2] 2.2.14.2.14 SVHDX_OPEN_DEVICE_CONTEXT_RESPONSE 810 [MS-RSVD] 2.2.4.32 SVHDX_OPEN_DEVICE_CONTEXT_V2_RESPONSE 811 812 The response packet sent by the server in response to an 813 SMB2VHDXOpenDeviceContextV2Request 814 """ 815 816 def __init__(self): 817 self.fields = OrderedDict([ 818 ('version', IntField( 819 size=4, 820 default=2 821 )), 822 ('has_initiator_id', BoolField( 823 size=1, 824 default=lambda s: len(s['initiator_host_name']) > 0 825 )), 826 ('reserved', BytesField( 827 size=3, 828 default=b"\x00\x00\x00" 829 )), 830 ('initiator_id', UuidField(size=16)), 831 ('flags', IntField(size=4)), 832 ('originator_flags', EnumField( 833 size=4, 834 enum_type=SVHDXOriginatorFlags 835 )), 836 ('open_request_id', IntField(size=8)), 837 ('initiator_host_name_length', IntField( 838 size=2, 839 default=lambda s: len(s['initiator_host_name']) 840 )), 841 # utf-16-le encoded string 842 ('initiator_host_name', BytesField( 843 size=lambda s: s['initiator_host_name_length'].get_value() 844 )), 845 ('virtual_disk_properties_initialized', IntField(size=4)), 846 ('server_service_version', IntField(size=4)), 847 ('virtual_sector_size', IntField(size=4)), 848 ('physical_sector_size', IntField(size=4)), 849 ('virtual_size', IntField(size=8)) 850 ]) 851 super(SMB2SVHDXOpenDeviceContextV2Response, self).__init__() 852 853 854class SMB2CreateAppInstanceVersion(Structure): 855 """ 856 [MS-SMB2] 2.2.13.2.15 SMB2_CREATE_APP_INSTANCE_VERSION 857 858 Used when the client is supplying a version for the app instance identifier 859 provided by an application. 860 Valid for the SMB 3.1.1+ family 861 """ 862 863 NAME = CreateContextName.SMB2_CREATE_APP_INSTANCE_VERSION 864 865 def __init__(self): 866 self.fields = OrderedDict([ 867 ('structure_size', IntField( 868 size=2, 869 default=24 870 )), 871 ('reserved', IntField(size=2)), 872 ('padding', IntField(size=4)), 873 ('app_instance_version_high', IntField(size=8)), 874 ('app_instance_version_low', IntField(size=8)) 875 ]) 876 super(SMB2CreateAppInstanceVersion, self).__init__() 877