public void BVT_Signing() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb2002); testConfig.CheckServerEncrypt(); TestConfig.CheckSigning(); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends NEGOTIATE request with NEGOTIATE_SIGNING_REQUIRED flag set."); client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends SESSION_SETUP request with NEGOTIATE_SIGNING_REQUIRED flag set."); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); string uncSharepath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request."); client.TreeConnect( uncSharepath, out treeId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF"); client.TreeDisconnect(treeId); client.LogOff(); }
public void MultipleChannel_MultiChannelOnSameNic() { #region Normal string contentWrite; string contentRead; uint treeId; FILEID fileId; #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL); TestConfig.CheckSigning(); #endregion contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); BaseTestSite.Assert.IsTrue( clientIps.Count > 0, "Client should have at least one IP address"); BaseTestSite.Assert.IsTrue( serverIps.Count > 0, "Server should have more than one IP address"); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start to write content to file from main channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[0].ToString()); WriteFromMainChannel( serverIps[0], clientIps[0], contentWrite, false, out treeId, out fileId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start to read content from file from alternative channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[0].ToString()); ReadFromAlternativeChannel( serverIps[0], clientIps[0], (uint)contentWrite.Length, treeId, fileId, out contentRead); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Verify the contents read from alternative channel are the same as the one written by main channel."); BaseTestSite.Assert.IsTrue( contentWrite.Equals(contentRead), "Content read should be identical to content written."); #endregion }
private void Negative_AlternativeChannel_NicRedundantOnServer(DialectRevision[] requestDialect, DialectRevision expectedDialect) { string contentWrite; string contentRead; uint treeId; FILEID fileId; #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL); // According to TD, server must support signing when it supports multichannel. // 3.3.5.5 Receiving an SMB2 SESSION_SETUP Request // 4. If Connection.Dialect belongs to the SMB 3.x dialect family, IsMultiChannelCapable is TRUE, and the SMB2_SESSION_FLAG_BINDING bit is // set in the Flags field of the request, the server MUST perform the following: // If the SMB2_FLAGS_SIGNED bit is not set in the Flags field in the header, the server MUST fail the request with error STATUS_INVALID_PARAMETER. TestConfig.CheckSigning(); #endregion contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); BaseTestSite.Assert.IsTrue( clientIps.Count > 0, "Client should have at least one IP address"); BaseTestSite.Assert.IsTrue( serverIps.Count > 1, "Server should have more than one IP address"); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start to write content to file from main channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[0].ToString()); WriteFromMainChannel( requestDialect, expectedDialect, serverIps[0], clientIps[0], contentWrite, true, out treeId, out fileId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start to read content from file from alternative channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[1].ToString()); ReadFromAlternativeChannel( requestDialect, expectedDialect, serverIps[1], clientIps[0], (uint)contentWrite.Length, treeId, fileId, out contentRead); }
public void Signing_VerifyAesGmacSigning() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckSigning(); #endregion var signingAlgorithms = new SigningAlgorithm[] { SigningAlgorithm.AES_GMAC }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends NEGOTIATE with the Aes-GMAC signing algorithm and NEGOTIATE_SIGNING_REQUIRED."); client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, Smb2Utility.GetDialects(DialectRevision.Smb311), SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED, preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }, compressionFlags: SMB2_COMPRESSION_CAPABILITIES_Flags.SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE, signingAlgorithms: signingAlgorithms, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "SUT MUST return STATUS_SUCCESS if the negotiation finished successfully."); }); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends SESSION_SETUP request and expects response."); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED); string uncSharepath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT to share: {0}", uncSharepath); client.TreeConnect( uncSharepath, out treeId, (Packet_Header header, TREE_CONNECT_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "TreeConnect should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.AreEqual( Packet_Header_Flags_Values.FLAGS_SIGNED, Packet_Header_Flags_Values.FLAGS_SIGNED & header.Flags, "Server should set SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header"); }); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF"); client.TreeDisconnect(treeId); client.LogOff(); }
public void ValidateNegotiateInfo_Negative_SMB311() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); // Server will terminate connection if Validate Negotiate Info Request is not signed. TestConfig.CheckSigning(); #endregion Smb2FunctionalClient testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); Guid clientGuid = Guid.NewGuid(); DialectRevision[] requestDialects = Smb2Utility.GetDialects(DialectRevision.Smb311); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; NEGOTIATE_Response? negotiateResponse = null; status = client.Negotiate( requestDialects, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid, (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb311, response); negotiateResponse = response; }); status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); uint treeId; string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName); status = client.TreeConnect(ipcPath, out treeId); VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq = new VALIDATE_NEGOTIATE_INFO_Request(); validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq); byte[] outputBuffer; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Attempt to validate negotiate info with info Guid: {0}, Capabilities: {1}, SecurityMode: {2}, DialectCount: {3}, Dialects: {4}", validateNegotiateInfoReq.Guid, validateNegotiateInfoReq.Capabilities, validateNegotiateInfoReq.SecurityMode, validateNegotiateInfoReq.DialectCount, Smb2Utility.GetArrayString(validateNegotiateInfoReq.Dialects)); try { BaseTestSite.Log.Add( LogEntryKind.TestStep, "Attempt to send a request with an SMB2 header with a Command value equal to SMB2 IOCTL, and a CtlCode of FSCTL_VALIDATE_NEGOTIATE_INFO."); client.ValidateNegotiateInfo( treeId, inputBuffer, out outputBuffer ); } catch { } BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when Connection.Dialect is \"3.1.1\"."); }
private void TestValidateNegotiateInfo(Smb2FunctionalClient client, ValidateNegotiateInfoRequestType requestType, DialectRevision[] invalidDialects = null) { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO); TestConfig.CheckDialectIOCTLCompatibility(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO); // Server will terminate connection if Validate Negotiate Info Request is not signed. TestConfig.CheckSigning(); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); Guid clientGuid = Guid.NewGuid(); DialectRevision[] requestDialects = TestConfig.RequestDialects; Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; NEGOTIATE_Response? negotiateResponse = null; status = client.Negotiate( requestDialects, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid, (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); negotiateResponse = response; }); status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); uint treeId; string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName); status = client.TreeConnect(ipcPath, out treeId); VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq; switch (requestType) { case ValidateNegotiateInfoRequestType.None: case ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; case ValidateNegotiateInfoRequestType.InvalidDialects: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)invalidDialects.Length; validateNegotiateInfoReq.Dialects = invalidDialects; break; case ValidateNegotiateInfoRequestType.InvalidGuid: validateNegotiateInfoReq.Guid = Guid.NewGuid(); validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; case ValidateNegotiateInfoRequestType.InvalidSecurityMode: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; case ValidateNegotiateInfoRequestType.InvalidCapabilities: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = Capabilities_Values.NONE; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; default: throw new InvalidOperationException("Unexpected ValidateNegotiateInfo request type " + requestType); } byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq); byte[] outputBuffer; VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResp; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Attempt to validate negotiate info with info Guid: {0}, Capabilities: {1}, SecurityMode: {2}, DialectCount: {3}, Dialects: {4}", validateNegotiateInfoReq.Guid, validateNegotiateInfoReq.Capabilities, validateNegotiateInfoReq.SecurityMode, validateNegotiateInfoReq.DialectCount, Smb2Utility.GetArrayString(validateNegotiateInfoReq.Dialects)); if (requestType == ValidateNegotiateInfoRequestType.None) { status = client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: (header, response) => { }); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "ValidateNegotiateInfo should succeed "); validateNegotiateInfoResp = TypeMarshal.ToStruct <VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer); BaseTestSite.Log.Add( LogEntryKind.Debug, "Capabilities returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Capabilities); BaseTestSite.Assert.AreEqual( (Capabilities_Values)negotiateResponse.Value.Capabilities, validateNegotiateInfoResp.Capabilities, "Capabilities returned in ValidateNegotiateInfo response should be equal to server capabilities in original Negotiate response"); BaseTestSite.Log.Add( LogEntryKind.Debug, "Guid returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Guid); BaseTestSite.Assert.AreEqual( negotiateResponse.Value.ServerGuid, validateNegotiateInfoResp.Guid, "ServerGuid returned in ValidateNegotiateInfo response should be equal to server ServerGuid in original Negotiate response"); BaseTestSite.Log.Add( LogEntryKind.Debug, "SecurityMode returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.SecurityMode); BaseTestSite.Assert.AreEqual( (SecurityMode_Values)negotiateResponse.Value.SecurityMode, validateNegotiateInfoResp.SecurityMode, "SecurityMode returned in ValidateNegotiateInfo response should be equal to server SecurityMode in original Negotiate response"); BaseTestSite.Log.Add( LogEntryKind.Debug, "Dialect returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Dialect); BaseTestSite.Assert.AreEqual( negotiateResponse.Value.DialectRevision, validateNegotiateInfoResp.Dialect, "DialectRevision returned in ValidateNegotiateInfo response should be equal to server DialectRevision in original Negotiate response"); client.TreeDisconnect(treeId); client.LogOff(); return; } uint maxOutputResponse = (requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse) ? (uint)0: 64 * 1024; try { client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, maxOutputResponse, (header, response) => { }); client.TreeDisconnect(treeId); client.LogOff(); return; } catch { } string errCondition = requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse ? "MaxOutputResponse in the request is less than the size of a VALIDATE_NEGOTIATE_INFO Response" : "there's invalid info in the request"; BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when {0}", errCondition); }
public void BVT_Replay_WriteWithInvalidChannelSequence() { ///1. mainChannelClient opens a file and write to it. ///2. mainChannelClient loses connection. ///3. ChannelSequence is set to 0x8000 which exceeds the max value. ///4. alternativeChannelClient opens the same file and try to write to it. ///5. Server should fail the write request with STATUS_FILE_NOT_AVAILABLE. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); // According to TD, server must support signing when it supports multichannel. // 3.3.5.5 Receiving an SMB2 SESSION_SETUP Request // 4. If Connection.Dialect belongs to the SMB 3.x dialect family, IsMultiChannelCapable is TRUE, and the SMB2_SESSION_FLAG_BINDING bit is // set in the Flags field of the request, the server MUST perform the following: // If the SMB2_FLAGS_SIGNED bit is not set in the Flags field in the header, the server MUST fail the request with error STATUS_INVALID_PARAMETER. TestConfig.CheckSigning(); #endregion Guid clientGuid = Guid.NewGuid(); Capabilities_Values capabilityValue = Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL; channelSequence = 0; #region MainChannelClient Create a File BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start a client from main channel by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE."); mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); mainChannelClient.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: capabilityValue, clientGuid: clientGuid, checker: ReplayNegotiateResponseChecker); mainChannelClient.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); mainChannelClient.SessionChannelSequence = channelSequence; uint treeId; mainChannelClient.TreeConnect(sharePath, out treeId); FILEID fileId; Smb2CreateContextResponse[] createContextResponse; mainChannelClient.Create(treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse, RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = Guid.NewGuid() } }); CheckCreateContextResponses(createContextResponse, new DefaultDurableHandleV2ResponseChecker(BaseTestSite, 0, uint.MaxValue)); #endregion #region alternativeChannelClient Opens the Previously Created File BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client from alternative channel by sending NEGOTIATE request."); alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutAlternativeIPAddress); alternativeChannelClient.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: capabilityValue, clientGuid: clientGuid, checker: ReplayNegotiateResponseChecker); BaseTestSite.Log.Add( LogEntryKind.TestStep, "The alternative client sends SESSION_SETUP request binding the previous session created by the main channel client."); alternativeChannelClient.AlternativeChannelSessionSetup(mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); alternativeChannelClient.SessionChannelSequence = channelSequence; #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "The main channel client sends WRITE request to write content to file."); mainChannelClient.Write(treeId, fileId, " "); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the main channel client by sending DISCONNECT request."); mainChannelClient.Disconnect(); //Network Disconnection Increase the Channel Sequence //Server MUST fail SMB2 WRITE, SET_INFO, and IOCTL requests with STATUS_FILE_NOT_AVAILABLE //if the difference between the ChannelSequence in the header and Open.ChannelSequence is greater than 0x7FFF BaseTestSite.Log.Add(LogEntryKind.TestStep, "Set the channel sequence of the alternative channel client to an invalid value."); alternativeChannelClient.SessionChannelSequence = 0x8000; BaseTestSite.Log.Add( LogEntryKind.TestStep, "The alternative client sends WRITE request to write content to the file created by the main channel client."); alternativeChannelClient.Write(treeId, fileId, " ", checker: (header, response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_FILE_NOT_AVAILABLE, header.Status, "Server MUST fail the {0} request with STATUS_FILE_NOT_AVAILABLE if the difference between the ChannelSequence in the header and Open.ChannelSequence is greater than 0x7FFF. " + "Actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); }, isReplay: true); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the alternative channel client by sending TREE_DISCONNECT and LOG_OFF requests."); alternativeChannelClient.TreeDisconnect(treeId); alternativeChannelClient.LogOff(); }
public void BVT_Replay_ReplayCreate() { ///1. mainChannelClient opens a file ///2. mainChannelClient loses connection. ///3. ChannelSequence is increased by 1. ///4. alternativeChannelClient opens the same file with replay flag set. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); // According to TD, server must support signing when it supports multichannel. // 3.3.5.5 Receiving an SMB2 SESSION_SETUP Request // 4. If Connection.Dialect belongs to the SMB 3.x dialect family, IsMultiChannelCapable is TRUE, and the SMB2_SESSION_FLAG_BINDING bit is // set in the Flags field of the request, the server MUST perform the following: // If the SMB2_FLAGS_SIGNED bit is not set in the Flags field in the header, the server MUST fail the request with error STATUS_INVALID_PARAMETER. TestConfig.CheckSigning(); #endregion Guid durableHandleGuid = Guid.NewGuid(); Guid clientGuid = Guid.NewGuid(); Capabilities_Values capabilityValue = Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL; #region MainChannelClient Finish Session Setup and AlternativeChannelClient Establish Another Channel BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start a client from main channel by sending the following requests: NEGOTIATE; SESSION_SETUP"); mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); mainChannelClient.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: capabilityValue, clientGuid: clientGuid, checker: ReplayNegotiateResponseChecker); mainChannelClient.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start another client from alternative channel by sending the following requests: NEGOTIATE SESSION_SETUP"); alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutAlternativeIPAddress); alternativeChannelClient.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: capabilityValue, clientGuid: clientGuid, checker: ReplayNegotiateResponseChecker); alternativeChannelClient.AlternativeChannelSessionSetup(mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); #endregion #region MainChannelClient Create a File with DurableHandleV1 and BatchOpLock uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "The main channel client sends TREE_CONNECT request."); mainChannelClient.TreeConnect(sharePath, out treeId); FILEID fileId; Smb2CreateContextResponse[] createContextResponse; BaseTestSite.Log.Add( LogEntryKind.TestStep, "The main channel client sends CREATE request with SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context."); mainChannelClient.Create(treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse, RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = durableHandleGuid } }); CheckCreateContextResponses(createContextResponse, new DefaultDurableHandleV2ResponseChecker(BaseTestSite, 0, uint.MaxValue)); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the main channel client by sending DISCONNECT request."); mainChannelClient.Disconnect(); alternativeChannelClient.SessionChannelSequence++; #region AlternativeChannelClient Opens the Previously Created File with Replay Flag Set FILEID alternativeFileId; BaseTestSite.Log.Add( LogEntryKind.TestStep, "The alternative client sends CREATE request with replay flag set and SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 to open the same file with the main channel client."); alternativeChannelClient.Create(treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, Packet_Header_Flags_Values.FLAGS_REPLAY_OPERATION | (testConfig.SendSignedRequest ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE), out alternativeFileId, out createContextResponse, RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = durableHandleGuid } }); CheckCreateContextResponses(createContextResponse, new DefaultDurableHandleV2ResponseChecker(BaseTestSite, 0, uint.MaxValue)); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the alternative channel client by sending the following requests: TREE_DISCONNECT; LOG_OFF"); alternativeChannelClient.TreeDisconnect(treeId); alternativeChannelClient.LogOff(); }