public void FileServerFailover_SMB311_Redirect_To_Owner_SOFS() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); #endregion if (testConfig.IsWindowsPlatform) { // Use GetClusterResourceOwner to get active host node string sofsHostedNode = sutController.GetClusterResourceOwner(TestConfig.ClusteredScaleOutFileServerName).ToLower(); string hostedNode = TestConfig.ClusterNode01.ToLower().Contains(sofsHostedNode) ? TestConfig.ClusterNode01 : TestConfig.ClusterNode02; string nonHostedNode = !TestConfig.ClusterNode01.ToLower().Contains(hostedNode) ? TestConfig.ClusterNode01 : TestConfig.ClusterNode02; TestRedirectToOwner(hostedNode, nonHostedNode); } else { // For non-Windows platform, // since we cannot find which host node is active, node01/node02 is treated as host node for testing respectively. bool isRedirectToOwnerTested = TestRedirectToOwner(TestConfig.ClusterNode01, TestConfig.ClusterNode02); if (isRedirectToOwnerTested == false) { TestRedirectToOwner(TestConfig.ClusterNode02, TestConfig.ClusterNode01); } } }
private void CheckApplicability() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID, CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_VERSION); #endregion }
public void DurableHandleV1_WithLeaseV1_WithoutHandleCaching() { /// 1. Client requests a durable handle with LeaseV1 context, SMB2_LEASE_HANDLE_CACHING bit is not set in LeaseState. /// 2. Durable Handle is not granted. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb21); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST, CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE); #endregion string content = Smb2Utility.CreateRandomString(testConfig.WriteBufferLengthInKb); fileName = "DurableHandleV1_WithLeaseV1_WithoutHandleCaching" + Guid.NewGuid() + ".txt"; durableHandleUncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); BaseTestSite.Log.Add( LogEntryKind.Comment, "Client connects to server and opens file with a durable handle, SMB2_LEASE_HANDLE_CACHING bit is not set in LeaseState."); uint treeIdBeforeDisconnection; Connect(DialectRevision.Smb21, clientBeforeDisconnection, clientGuid, testConfig.AccountCredential, ConnectShareType.BasicShareWithoutAssert, out treeIdBeforeDisconnection, null); Guid leaseKey = Guid.NewGuid(); // SMB2_LEASE_HANDLE_CACHING bit is not set in LeaseState LeaseStateValues leaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_WRITE_CACHING; FILEID fileIdBeforeDisconnection; Smb2CreateContextResponse[] serverCreateContexts = null; clientBeforeDisconnection.Create( treeIdBeforeDisconnection, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdBeforeDisconnection, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequest { DurableRequest = Guid.Empty, }, new Smb2CreateRequestLease { LeaseKey = leaseKey, LeaseState = leaseState, } }, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); // Durable Handle should not be granted. CheckCreateContextResponsesNotExist(serverCreateContexts, new DefaultDurableHandleResponseChecker(BaseTestSite)); }); clientBeforeDisconnection.TreeDisconnect(treeIdBeforeDisconnection); clientBeforeDisconnection.LogOff(); clientBeforeDisconnection.Disconnect(); }
public void AsymmetricShare_OnSmb30() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb302); #endregion TestAsymmetricShare(DialectRevision.Smb30, TestConfig.NonOptimumNodeOfAsymmetricShare, true); }
public void AsymmetricShare_OnNonScaleOutShare() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb302); #endregion TestAsymmetricShare(DialectRevision.Smb302, TestConfig.SutComputerName, false); }
private void NegotiateWithEncryptionCapabilitiesContext(EncryptionAlgorithm cipherId) { if (cipherId == EncryptionAlgorithm.ENCRYPTION_NONE) { throw new ArgumentException("CipherId should be either AES-128-CCM or AES-128-GCM."); } #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION); TestConfig.CheckEncryptionAlgorithm(cipherId); #endregion BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client sends NEGOTIATE request with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context. {0} is as the preferred cipher algorithm. ", cipherId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Server should reply NEGOTIATE response with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context and {0} as cipher algorithm. ", cipherId); PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { cipherId, cipherId == EncryptionAlgorithm.ENCRYPTION_AES128_CCM? EncryptionAlgorithm.ENCRYPTION_AES128_GCM : EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, TestConfig.RequestDialects, capabilityValue: Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs); BaseTestSite.Assert.AreEqual(cipherId, client.SelectedCipherID, "The selected Cipher Id should be {0}", cipherId); }
public void TreeMgmt_SMB311_COMPRESS_DATA() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckPlatform(Platform.WindowsServer2022); if (string.IsNullOrEmpty(testConfig.CompressedFileShare)) { Assert.Inconclusive("This test requires a share with compression enabled"); } #endregion var compressedSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.CompressedFileShare); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP"); client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled); client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request and expects STATUS_SUCCESS with flag SMB2_SHAREFLAG_COMPRESS_DATA."); uint treeId; client.TreeConnect(compressedSharePath, out treeId, (header, response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.IsTrue( response.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_COMPRESS_DATA), "The share should support compress data, actually server returns {0}.", response.ShareFlags.ToString()); }); client.TreeDisconnect(treeId); }
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 AppInstanceId_Smb302() { // Client1 opens a file with create context AppInstanceId, no create context DurableHandleRequestV2 // Client1 writes to that file. // Client2 opens that file with the same AppInstanceId successfully. // Client1 writes to check if the Open is closed. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb302); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID); #endregion // If Open.CreateGuid is NULL, and Open.TreeConnect.Share.IsCA is FALSE, the server // SHOULD < 298 > close the open as specified in section 3.3.4.17. // <298> Section 3.3.5.9.13: Windows Server 2012 and Windows Server 2012 R2 servers do not close the open. var is2012Or2012R2 = TestConfig.Platform == Platform.WindowsServer2012 || TestConfig.Platform == Platform.WindowsServer2012R2; var expectedCreateResponseStatus = is2012Or2012R2 ? Smb2Status.STATUS_SHARING_VIOLATION : Smb2Status.STATUS_SUCCESS; var expectedInitialOpenStatusAfterReopen = is2012Or2012R2 ? Smb2Status.STATUS_SUCCESS : Smb2Status.STATUS_FILE_CLOSED; AppInstanceIdTest( sameAppInstanceId: true, containCreateDurableContext: false, expectedCreateResponseStatus: expectedCreateResponseStatus, expectedInitialOpenStatusAfterReopen: expectedInitialOpenStatusAfterReopen); }
public void DurableHandleV2_NoPersistenceGrantedOnNonCAShare() { /// 1. Client requests a durable handle V2 to a Non-CA share /// 2. Expect the create response contains Smb2CreateDurableHandleResponseV2 context but no persistent flag is set. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2, CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE); #endregion durableHandleUncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); fileName = "DurableHandleV2_NoPersistenceGrantedOnNonCAShare" + Guid.NewGuid() + ".txt"; Guid clientGuid = Guid.NewGuid(); BaseTestSite.Log.Add( LogEntryKind.Comment, "Client connects to server and opens file with a durable handle"); #region client connect to server uint treeIdBeforeDisconnection; Connect(DialectRevision.Smb30, clientBeforeDisconnection, clientGuid, testConfig.AccountCredential, ConnectShareType.BasicShare, out treeIdBeforeDisconnection, null); Smb2CreateContextResponse[] serverCreateContexts = null; FILEID fileIdBeforeDisconnection; Guid createGuid = Guid.NewGuid(); clientBeforeDisconnection.Create( treeIdBeforeDisconnection, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdBeforeDisconnection, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid, Flags = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT, }, }, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); }); BaseTestSite.Assert.AreEqual( null, serverCreateContexts, "The server should ignore the create context when TreeConnect.Share.IsCA is FALSE."); #endregion clientBeforeDisconnection.Close(treeIdBeforeDisconnection, fileIdBeforeDisconnection); clientBeforeDisconnection.TreeDisconnect(treeIdBeforeDisconnection); clientBeforeDisconnection.LogOff(); }
public void BVT_ResilientHandle_Reconnect() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb21); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT); #endregion Guid clientGuid = Guid.NewGuid(); #region clientBeforeDisconnection Create a File BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the first client to create a file by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); clientBeforeDisconnection.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid); clientBeforeDisconnection.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); uint treeId; clientBeforeDisconnection.TreeConnect(sharePath, out treeId); FILEID fileId; Smb2CreateContextResponse[] createContextResponse; clientBeforeDisconnection.Create(treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse); #endregion #region Request Resilient Handle IOCTL_Response IOCTLResponse; byte[] inputInResponse; byte[] outputInResponse; Packet_Header packetHeader; BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends an IOCTL FSCTL_LMR_REQUEST_RESILLIENCY request."); clientBeforeDisconnection.ResiliencyRequest(treeId, fileId, TestConfig.MaxResiliencyTimeoutInSecond * 1000, NETWORK_RESILIENCY_REQUEST_SIZE, out packetHeader, out IOCTLResponse, out inputInResponse, out outputInResponse); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the first client by sending DISCONNECT request."); clientBeforeDisconnection.Disconnect(); #region ClientAfterDisconnection Opens the Previously Created File with DurableHandleReconnect BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a second client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); clientAfterDisconnection.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid); clientAfterDisconnection.ReconnectSessionSetup(clientBeforeDisconnection, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); clientAfterDisconnection.TreeConnect(sharePath, out treeId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "The second client sends CREATE request with SMB2_CREATE_DURABLE_HANDLE_RECONNECT create context to open the same file created by the first client."); clientAfterDisconnection.Create(treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse, RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleReconnect { Data = fileId } }); #endregion #region Tear Down Client BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF"); clientAfterDisconnection.Close(treeId, fileId); clientAfterDisconnection.TreeDisconnect(treeId); clientAfterDisconnection.LogOff(); #endregion }
public void ResilientOpenScavengerTimer_ReconnectBeforeTimeout() { /// 1. Open Resilient Handle with specific timeout. /// 2. Disconnect to start the Resilient Timer. /// 3. Wait for specific timeout - 1 seconds. /// 4. Reconnect the resilient handle and expect the result is success. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb21); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT); #endregion Smb2FunctionalClient prepareClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); uint timeoutInSecond = testConfig.MaxResiliencyTimeoutInSecond / 2; Guid clientGuid = Guid.NewGuid(); string fileName = "ResilientHandle_" + Guid.NewGuid() + ".txt"; FILEID fileId; // Open file & Resiliency request BaseTestSite.Log.Add( LogEntryKind.TestStep, "Create resilient handle to file '{0}' and timeout is {1} seconds", fileName, timeoutInSecond); OpenFileAndResilientRequest( prepareClient, clientGuid, fileName, timeoutInSecond * 1000, // convert second to millisecond out fileId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Disconnect the client to start the Resilient Open Scavenger Timer on server"); prepareClient.Disconnect(); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Wait {0} seconds before Resilient Open Scavenger Timer expired.", timeoutInSecond - 1); Thread.Sleep(TimeSpan.FromSeconds(timeoutInSecond - 1)); Smb2FunctionalClient reconnectClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Re-establish Resilient Open, verify the returned status is STATUS_SUCCESS."); ReconnectResilientHandle( reconnectClient, clientGuid, fileName, fileId, NtStatus.STATUS_SUCCESS, "Reconnect resilient handle should be successful."); // clean reconnectClient.Disconnect(); }
protected override void TestInitialize() { base.TestInitialize(); #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_OFFLOAD_READ, CtlCode_Values.FSCTL_OFFLOAD_WRITE); #endregion client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); }
private void PrepareFileForTrimming(out uint treeId, out FILEID fileId) { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_FILE_LEVEL_TRIM); #endregion string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); string fileName = GetTestFileName(uncSharePath); string contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); uint status = smb2Functionalclient.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); }); status = smb2Functionalclient.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); status = smb2Functionalclient.TreeConnect(uncSharePath, out treeId); Smb2CreateContextResponse[] serverCreateContexts; status = smb2Functionalclient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); status = smb2Functionalclient.Write(treeId, fileId, contentWrite); status = smb2Functionalclient.Close(treeId, fileId); status = smb2Functionalclient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); }
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 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 }
public void BVT_AppInstanceId() { // Client1 opens a file with DurableHandleRequestV2 and AppInstanceId. // Client2 opens that file with DurableHandleRequestV2 and with the same AppInstanceId successfully. // Client1 writes to that file but fails since the first open is closed. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); #endregion AppInstanceIdTest(sameAppInstanceId: true, containCreateDurableContext: true); }
public void AppInstanceId_Negative_DifferentAppInstanceIdInReopen() { // Client1 opens a file with DurableHandleRequestV2 and AppInstanceId. // Client2 opens that file with DurableHandleRequestV2 and with the different AppInstanceId, but fails. // Client1 writes to that file and succeeds since the first open is not closed. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); #endregion AppInstanceIdTest(sameAppInstanceId: false, containCreateDurableContext: true); }
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(); }
private void NegotiateWithEncryptionCapabilitiesContext(EncryptionAlgorithm cipherId, bool sendCipherArray = false) { if (cipherId == EncryptionAlgorithm.ENCRYPTION_NONE) { throw new ArgumentException("CipherId should be either AES-128-CCM or AES-128-GCM."); } #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION); TestConfig.CheckEncryptionAlgorithm(cipherId); #endregion BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client sends NEGOTIATE request with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context. {0} is as the preferred cipher algorithm. ", cipherId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Server should reply NEGOTIATE response with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context and {0} as cipher algorithm. ", cipherId); PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = null; if (sendCipherArray) { encryptionAlgs = new EncryptionAlgorithm[] { cipherId, cipherId == EncryptionAlgorithm.ENCRYPTION_AES128_CCM? EncryptionAlgorithm.ENCRYPTION_AES128_GCM : EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; } else { encryptionAlgs = new EncryptionAlgorithm[] { cipherId }; } client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, TestConfig.RequestDialects, capabilityValue: Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs); if (sendCipherArray) { BaseTestSite.Assert.IsTrue( TestConfig.SupportedEncryptionAlgorithmList.Contains(client.SelectedCipherID), "[MS-SMB2] 3.3.5.4 The server MUST set Connection.CipherId to one of the ciphers in the client's " + "SMB2_ENCRYPTION_CAPABILITIES Ciphers array in an implementation-specific manner."); } else { BaseTestSite.Assert.AreEqual(cipherId, client.SelectedCipherID, "The selected Cipher Id should be {0}", cipherId); } }
public void AppInstanceId_Smb311() { // Client1 opens a file with create context AppInstanceId, no create context DurableHandleRequestV2 // Client1 writes to that file. // Client2 opens that file with the same AppInstanceId successfully. // Client1 writes to that file but fails since the first open is closed. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID); #endregion AppInstanceIdTest(sameAppInstanceId: true, containCreateDurableContext: false); }
private void NegotiateWithoutContext() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends NEGOTIATE with the capability GLOBAL_CAP_ENCRYPTION."); client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION ); }
public void AppInstanceId_DirectoryLeasing_NoLeaseInReOpen() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2, CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2); #endregion AppInstanceIdTestWithLeasing( true, LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_HANDLE_CACHING, AccessMask.GENERIC_READ, AccessMask.DELETE); }
public void BVT_Leasing_FileLeasingV2() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2); #endregion Smb2CreateContextRequest leaseContext = new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_WRITE_CACHING | LeaseStateValues.SMB2_LEASE_HANDLE_CACHING }; TestFileLeasing(leaseContext); }
public void AppInstanceId_Smb311() { // Client1 opens a file with create context AppInstanceId, no create context DurableHandleRequestV2 // Client1 writes to that file. // Client2 opens that file with the same AppInstanceId successfully. // Client1 writes to that file but fails since the first open is closed. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID); #endregion AppInstanceIdTest( sameAppInstanceId: true, containCreateDurableContext: false, expectedCreateResponseStatus: Smb2Status.STATUS_SUCCESS, expectedInitialOpenStatusAfterReopen: Smb2Status.STATUS_FILE_CLOSED); }
public void BVT_Resiliency() { #region Check Applicaility TestConfig.CheckDialect(DialectRevision.Smb30); #endregion Guid clientGuid = Guid.NewGuid(); //Guid createGuid = Guid.NewGuid(); string fileName = "ResilientWithPersistentHandle_" + Guid.NewGuid() + ".txt"; FILEID fileId; uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client opens a file."); //ConnectToShare(smb2Functionalclient, clientGuid, out treeId); OpenFile(smb2Functionalclient, clientGuid, fileName, out treeId, out fileId); Packet_Header ioCtlHeader; IOCTL_Response ioCtlReponse; byte[] inputInResponse; byte[] outputInResponse; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send an IOCTL FFSCTL_LMR_REQUEST_RESILLIENCY request."); smb2Functionalclient.ResiliencyRequest( treeId, fileId, TestConfig.MaxResiliencyTimeoutInSecond, (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)), out ioCtlHeader, out ioCtlReponse, out inputInResponse, out outputInResponse, checker: (Packet_Header header, IOCTL_Response response) => { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check IOCTL FFSCTL_LMR_REQUEST_RESILLIENCY response"); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}", header.Command, Smb2Status.GetStatusCode(header.Status)); }); smb2Functionalclient.Close(treeId, fileId); smb2Functionalclient.TreeDisconnect(treeId); smb2Functionalclient.LogOff(); }
public void BVT_PersistentHandles() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); if (!TestConfig.IsPersistentHandlesSupported) { Site.Assert.Inconclusive("Test case is applicable in servers that support persistent handles"); } #endregion DialectRevision[] requestDialect = Smb2Utility.GetDialects(DialectRevision.Smb311); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION; SecurityMode_Values clientSecuirtyMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with client capabilitites: {0}.", clientCapabilities.ToString()); smb2Functionalclient.Negotiate( Packet_Header_Flags_Values.NONE, requestDialect, clientSecuirtyMode, clientCapabilities, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check negotiate response contains {0} in Capabilities.", Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.IsTrue(response.DialectRevision >= DialectRevision.Smb30, "Select dialect is {0}, And it should be SMB 3.0 or higher dialect.", response.DialectRevision); BaseTestSite.Assert.IsTrue(response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES), "Server Capability should with flag {0} being set.", NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); } ); }
public void TreeMgmt_SMB311_CLUSTER_RECONNECT() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP"); client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled); client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request with flag SMB2_SHAREFLAG_CLUSTER_RECONNECT and expects STATUS_SUCCESS."); uint treeId; client.TreeConnect(sharePath, out treeId, (header, response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); }, TreeConnect_Flags.SMB2_SHAREFLAG_CLUSTER_RECONNECT); client.TreeDisconnect(treeId); }
public void ResilientWithPersistentHandle_OpenFromDiffClient() { /// 1. Open Persistent Handle with lease /// 2. Send Resiliency request /// 3. Disconnect /// 4. Open the same file from different client (different client guid) /// 5. The expected result of OPEN is successful. /// #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); #endregion Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); Guid clientGuid = Guid.NewGuid(); Guid createGuid = Guid.NewGuid(); Guid leaseKey = Guid.NewGuid(); string fileName = "ResilientWithPersistentHandle_" + Guid.NewGuid() + ".txt"; FILEID fileId; uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Open Persistent Handle with lease."); OpenFile( client, clientGuid, fileName, true, out createGuid, out treeId, out fileId); // resiliency request Packet_Header ioCtlHeader; IOCTL_Response ioCtlResponse; byte[] inputInResponse; byte[] outputInResponse; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send resiliency request with timeout {0} milliseconds", testConfig.MaxResiliencyTimeoutInSecond); client.ResiliencyRequest( treeId, fileId, testConfig.MaxResiliencyTimeoutInSecond, (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)), out ioCtlHeader, out ioCtlResponse, out inputInResponse, out outputInResponse ); // Disconnect BaseTestSite.Log.Add( LogEntryKind.TestStep, "Disconnect the resilient handle"); client.Disconnect(); // open from another client Smb2FunctionalClient anotherClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Open the same file from different client (different client guid), the expected result of OPEN is successful"); OpenFile( anotherClient, Guid.NewGuid(), fileName, false, out createGuid, out treeId, out fileId); }
public void DurableHandleV2_Reconnect_WithoutPersistence() { /// 1. Client requests a durable handle V2 without persistent flag /// 2. Lose connection by disabling NIC /// 3. Client reconnects the durable handle V2 without persistent flag. #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2, CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE); #endregion string content = Smb2Utility.CreateRandomString(testConfig.WriteBufferLengthInKb); Guid clientGuid = Guid.NewGuid(); durableHandleUncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); fileName = "DurableHandleV2_Reconnect_WithoutPersistence" + Guid.NewGuid() + ".txt"; #region client connect to server BaseTestSite.Log.Add( LogEntryKind.Comment, "Client connects to server and opens file with a durable handle"); uint treeIdBeforeDisconnection; Connect(DialectRevision.Smb30, clientBeforeDisconnection, clientGuid, testConfig.AccountCredential, ConnectShareType.BasicShareWithoutAssert, out treeIdBeforeDisconnection, null); Guid createGuid = Guid.NewGuid(); Guid leaseKey = Guid.NewGuid(); LeaseStateValues leaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_HANDLE_CACHING | LeaseStateValues.SMB2_LEASE_WRITE_CACHING; FILEID fileIdBeforeDisconnection; Smb2CreateContextResponse[] serverCreateContexts = null; clientBeforeDisconnection.Create( treeIdBeforeDisconnection, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdBeforeDisconnection, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid, }, new Smb2CreateRequestLeaseV2 { LeaseKey = leaseKey, LeaseState = leaseState, } }, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); CheckCreateContextResponses(serverCreateContexts, new DefaultDurableHandleV2ResponseChecker(BaseTestSite, 0, uint.MaxValue)); }); clientBeforeDisconnection.Write(treeIdBeforeDisconnection, fileIdBeforeDisconnection, content); #endregion clientBeforeDisconnection.Disconnect(); #region client reconnect to server BaseTestSite.Log.Add( LogEntryKind.Comment, "Client opens the same file and reconnects the durable handle"); uint treeIdAfterDisconnection; Connect(DialectRevision.Smb30, clientAfterDisconnection, clientGuid, testConfig.AccountCredential, ConnectShareType.BasicShareWithoutAssert, out treeIdAfterDisconnection, clientBeforeDisconnection); FILEID fileIdAfterDisconnection; clientAfterDisconnection.Create( treeIdAfterDisconnection, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdAfterDisconnection, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleReconnectV2 { CreateGuid = createGuid, FileId = new FILEID { Persistent = fileIdBeforeDisconnection.Persistent } }, new Smb2CreateRequestLeaseV2 { LeaseKey = leaseKey, LeaseState = leaseState, } }, shareAccess: ShareAccess_Values.NONE); string readContent; clientAfterDisconnection.Read(treeIdAfterDisconnection, fileIdAfterDisconnection, 0, (uint)content.Length, out readContent); BaseTestSite.Assert.IsTrue( content.Equals(readContent), "The written content is expected to be equal to read content."); #endregion clientAfterDisconnection.Close(treeIdAfterDisconnection, fileIdAfterDisconnection); clientAfterDisconnection.TreeDisconnect(treeIdAfterDisconnection); clientAfterDisconnection.LogOff(); clientAfterDisconnection.Disconnect(); }