private void Compound_RelatedRequests(string fileName, bool isEncrypted) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize the test client."); Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to the SMB2 basic share by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT."); ConnectToShare(client, out treeId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Create packet."); Smb2CreateRequestPacket createPacket = ConstructCreatePacket(client.SessionId, treeId, fileName); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Write packet, flag FLAGS_RELATED_OPERATIONS is set."); Smb2WriteRequestPacket writePacket = ConstructRelatedWritePacket(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Close packet, flag FLAGS_RELATED_OPERATIONS is set."); Smb2CloseRequestPacket closePacket = ConstructRelatedClosePacket(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send {0}compounded Create, Write and Close requests to SUT.", isEncrypted ? "encrypted " : ""); List <Smb2SinglePacket> requestPackets = new List <Smb2SinglePacket>(); requestPackets.Add(createPacket); requestPackets.Add(writePacket); requestPackets.Add(closePacket); if (isEncrypted) { // Enable encryption client.EnableSessionSigningAndEncryption(enableSigning: testConfig.SendSignedRequest, enableEncryption: true); } List <Smb2SinglePacket> responsePackets = client.SendAndReceiveCompoundPacket(requestPackets); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify responses to the compounded request."); foreach (var responsePacket in responsePackets) { if (TestConfig.Platform == Platform.WindowsServer2016 && responsePacket.Header.Status != Smb2Status.STATUS_SUCCESS) { } else { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, responsePacket.Header.Status, "{0} should succeed, actual status is {1}", responsePacket.Header.Command, Smb2Status.GetStatusCode(responsePacket.Header.Status)); } } client.TreeDisconnect(treeId); client.LogOff(); client.Disconnect(); }
private Smb2WriteRequestPacket ConstructRelatedWritePacket() { var writePacket = new Smb2WriteRequestPacket(); writePacket.Header.Command = Smb2Command.WRITE; // For any subsequent requests the client MUST set SMB2_FLAGS_RELATED_OPERATIONS in the Flags field of the SMB2 header to indicate that // it is using the SessionId, TreeId, and FileId supplied in the previous request (or generated by the server in processing that request). // The client SHOULD<93> set SessionId to 0xFFFFFFFFFFFFFFFF and TreeId to 0xFFFFFFFF, // and SHOULD<94> set FileId to { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }. writePacket.Header.Flags = Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS; writePacket.Header.SessionId = 0xFFFFFFFFFFFFFFFF; writePacket.Header.TreeId = 0xFFFFFFFF; byte[] content = Smb2Utility.CreateRandomByteArray(1); // Write 1 byte to the file. writePacket.PayLoad.Length = (uint)content.Length; writePacket.PayLoad.Offset = 0; writePacket.PayLoad.FileId = FILEID.Invalid; writePacket.PayLoad.DataOffset = (ushort)writePacket.BufferOffset; writePacket.Buffer = content; return(writePacket); }
private Smb2WriteRequestPacket ConstructRelatedWritePacket(ulong sessionId, uint treeId) { var writePacket = new Smb2WriteRequestPacket(); writePacket.Header.Command = Smb2Command.WRITE; // The client MUST construct the subsequent request as it would do normally. // For any subsequent requests the client MUST set SMB2_FLAGS_RELATED_OPERATIONS in the Flags field of the SMB2 header to indicate that it is using the SessionId, // TreeId, and FileId supplied in the previous request(or generated by the server in processing that request). // For an operation compounded with an SMB2 CREATE request, the FileId field SHOULD be set to { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }. writePacket.Header.Flags = Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS; writePacket.Header.SessionId = sessionId; writePacket.Header.TreeId = treeId; byte[] content = Smb2Utility.CreateRandomByteArray(1); // Write 1 byte to the file. writePacket.PayLoad.Length = (uint)content.Length; writePacket.PayLoad.Offset = 0; writePacket.PayLoad.FileId = FILEID.Invalid; writePacket.PayLoad.DataOffset = (ushort)writePacket.BufferOffset; writePacket.Buffer = content; return(writePacket); }
private uint Smb2WriteOverRdmaChannel( ushort creditCharge, ushort creditRequest, UInt64 offset, byte[] writeChannelInfo, uint length, out WRITE_Response responsePayload, Channel_Values channel = Channel_Values.CHANNEL_RDMA_V1 ) { var request = new Smb2WriteRequestPacket(); request.Header.CreditCharge = creditCharge; request.Header.Command = Smb2Command.WRITE; request.Header.CreditRequestResponse = creditRequest; request.Header.Flags = Packet_Header_Flags_Values.FLAGS_SIGNED; request.Header.MessageId = messageId; request.Header.TreeId = TreeId; request.Header.SessionId = sessionId; request.PayLoad.Length = 0; request.PayLoad.Offset = offset; request.PayLoad.FileId = FileId; request.PayLoad.Channel = channel; request.PayLoad.RemainingBytes = length; // not described in TD. Get from capture package request.PayLoad.WriteChannelInfoOffset = request.BufferOffset; request.PayLoad.WriteChannelInfoLength = (ushort)writeChannelInfo.Length; request.PayLoad.DataOffset = 0; request.PayLoad.Flags = WRITE_Request_Flags_Values.None; request.Buffer = writeChannelInfo; SendPacket(request); return(WriteResponse(messageId, out this.packetHeader, out responsePayload)); }
private Smb2WriteRequestPacket ConstructRelatedWritePacket() { var writePacket = new Smb2WriteRequestPacket(); writePacket.Header.Command = Smb2Command.WRITE; // For any subsequent requests the client MUST set SMB2_FLAGS_RELATED_OPERATIONS in the Flags field of the SMB2 header to indicate that // it is using the SessionId, TreeId, and FileId supplied in the previous request (or generated by the server in processing that request). // The client SHOULD<93> set SessionId to 0xFFFFFFFFFFFFFFFF and TreeId to 0xFFFFFFFF, // and SHOULD<94> set FileId to { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }. writePacket.Header.Flags = Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS; writePacket.Header.SessionId = 0xFFFFFFFFFFFFFFFF; writePacket.Header.TreeId = 0xFFFFFFFF; byte[] content = Smb2Utility.CreateRandomByteArray(1); // Write 1 byte to the file. writePacket.PayLoad.Length = (uint)content.Length; writePacket.PayLoad.Offset = 0; writePacket.PayLoad.FileId = FILEID.Invalid; writePacket.PayLoad.DataOffset = (ushort)writePacket.BufferOffset; writePacket.Buffer = content; return writePacket; }
public void SMBDWrite(uint treeId, FILEID fileId, Channel_Values channel, byte[] buffer, uint offset, RDMAEndian endian) { NtStatus status; SmbdBufferDescriptorV1 descriptor; status = smbdClient.RegisterBuffer( (uint)buffer.Length, SmbdBufferReadWrite.RDMA_READ_PERMISSION_FOR_WRITE_FILE, endianMap[endian], out descriptor ); if (status != NtStatus.STATUS_SUCCESS) { throw new InvalidOperationException("SMBD register buffer failed!"); } status = smbdClient.WriteRegisteredBuffer(buffer, descriptor); if (status != NtStatus.STATUS_SUCCESS) { throw new InvalidOperationException("SMBD write buffer failed!"); } byte[] channelInfo = TypeMarshal.ToBytes(descriptor); Packet_Header packetHeader; WRITE_Response response; // Pack WRITE request manually since the DataOffset and RemainingBytes need to be fixed. var request = new Smb2WriteRequestPacket(); request.Header.CreditCharge = 0; request.Header.CreditRequestResponse = RequestAndConsumeCredit(); request.Header.Flags = signingRequired ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE; request.Header.MessageId = GetMessageId(); request.Header.SessionId = sessionId; request.Header.TreeId = treeId; request.Header.Command = Smb2Command.WRITE; request.PayLoad.Offset = 0; request.PayLoad.FileId = fileId; request.PayLoad.Channel = channel; request.PayLoad.Flags = WRITE_Request_Flags_Values.None; request.PayLoad.Length = 0; request.PayLoad.RemainingBytes = (uint)buffer.Length; request.PayLoad.DataOffset = 0; request.PayLoad.WriteChannelInfoLength = (ushort)channelInfo.Length; request.PayLoad.WriteChannelInfoOffset = request.BufferOffset; request.Buffer = channelInfo; SendPacket(request); status = (NtStatus)WriteResponse(messageId, out packetHeader, out response); UpdateCredit(packetHeader); if (status != NtStatus.STATUS_SUCCESS) { throw new InvalidOperationException("Write through SMBD failed!"); } }