Esempio n. 1
0
        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);
 }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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();
        }
Esempio n. 11
0
        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);
        }
Esempio n. 19
0
        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);
        }
Esempio n. 22
0
        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);
        }
Esempio n. 24
0
        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);
        }
Esempio n. 26
0
        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);
            }
                );
        }
Esempio n. 28
0
        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);
        }
Esempio n. 29
0
        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();
        }