예제 #1
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);
        }
예제 #5
0
        private void TestValidateNegotiateInfo(Smb2FunctionalClient client, ValidateNegotiateInfoRequestType requestType, DialectRevision[] invalidDialects = null)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO);
            TestConfig.CheckDialectIOCTLCompatibility(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO);
            // Server will terminate connection if Validate Negotiate Info Request is not signed.
            TestConfig.CheckSigning();
            #endregion

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE;  SESSION_SETUP; TREE_CONNECT");

            Guid clientGuid = Guid.NewGuid();
            DialectRevision[]   requestDialects    = TestConfig.RequestDialects;
            Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;
            NEGOTIATE_Response? negotiateResponse  = null;
            status = client.Negotiate(
                requestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                clientSecurityMode,
                clientCapabilities,
                clientGuid,
                (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);

                negotiateResponse = response;
            });


            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint   treeId;
            string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName);
            status = client.TreeConnect(ipcPath, out treeId);

            VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq;
            switch (requestType)
            {
            case ValidateNegotiateInfoRequestType.None:
            case ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidDialects:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)invalidDialects.Length;
                validateNegotiateInfoReq.Dialects     = invalidDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidGuid:
                validateNegotiateInfoReq.Guid         = Guid.NewGuid();
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidSecurityMode:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidCapabilities:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = Capabilities_Values.NONE;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            default:
                throw new InvalidOperationException("Unexpected ValidateNegotiateInfo request type " + requestType);
            }

            byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq);
            byte[] outputBuffer;
            VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResp;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Attempt to validate negotiate info with info Guid: {0}, Capabilities: {1}, SecurityMode: {2}, DialectCount: {3}, Dialects: {4}",
                validateNegotiateInfoReq.Guid, validateNegotiateInfoReq.Capabilities, validateNegotiateInfoReq.SecurityMode, validateNegotiateInfoReq.DialectCount, Smb2Utility.GetArrayString(validateNegotiateInfoReq.Dialects));

            if (requestType == ValidateNegotiateInfoRequestType.None)
            {
                status = client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: (header, response) => { });

                BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status,
                                             "ValidateNegotiateInfo should succeed ");

                validateNegotiateInfoResp = TypeMarshal.ToStruct <VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer);
                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Capabilities returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Capabilities);
                BaseTestSite.Assert.AreEqual(
                    (Capabilities_Values)negotiateResponse.Value.Capabilities,
                    validateNegotiateInfoResp.Capabilities,
                    "Capabilities returned in ValidateNegotiateInfo response should be equal to server capabilities in original Negotiate response");

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Guid returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Guid);
                BaseTestSite.Assert.AreEqual(
                    negotiateResponse.Value.ServerGuid,
                    validateNegotiateInfoResp.Guid,
                    "ServerGuid returned in ValidateNegotiateInfo response should be equal to server ServerGuid in original Negotiate response");

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "SecurityMode returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.SecurityMode);
                BaseTestSite.Assert.AreEqual(
                    (SecurityMode_Values)negotiateResponse.Value.SecurityMode,
                    validateNegotiateInfoResp.SecurityMode,
                    "SecurityMode returned in ValidateNegotiateInfo response should be equal to server SecurityMode in original Negotiate response");

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Dialect returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Dialect);
                BaseTestSite.Assert.AreEqual(
                    negotiateResponse.Value.DialectRevision,
                    validateNegotiateInfoResp.Dialect,
                    "DialectRevision returned in ValidateNegotiateInfo response should be equal to server DialectRevision in original Negotiate response");

                client.TreeDisconnect(treeId);
                client.LogOff();
                return;
            }

            uint maxOutputResponse = (requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse) ? (uint)0: 64 * 1024;

            try
            {
                client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, maxOutputResponse, (header, response) => { });

                client.TreeDisconnect(treeId);
                client.LogOff();
                return;
            }
            catch
            {
            }

            string errCondition = requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse ?
                                  "MaxOutputResponse in the request is less than the size of a VALIDATE_NEGOTIATE_INFO Response" : "there's invalid info in the request";

            BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when {0}", errCondition);
        }
        public void BVT_EnumerateSnapShots()
        {
            #region Check Applicability
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_SRV_ENUMERATE_SNAPSHOTS);
            #endregion

            uint   treeId;
            FILEID fileId;
            OpenFile(out treeId, out fileId);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Enumerate snapshots by sending the first IOCTL request: FSCTL_SRV_ENUMERATE_SNAPSHOTS, with MaxOutputResponse set to 16.");
            SRV_SNAPSHOT_ARRAY snapShotArray;
            client.EnumerateSnapShots(
                treeId,
                fileId,
                SizeOfEmptySnapShotArray,
                out snapShotArray,
                checker: (Packet_Header header, IOCTL_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "FSCTL_SRV_ENUMERATE_SNAPSHOTS should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
            });
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Verify SRV_SNAPSHOT_ARRAY returned in response.");
            BaseTestSite.Assert.AreEqual(
                TestConfig.NumberOfPreviousVersions, snapShotArray.NumberOfSnapShots, "NumberOfSnapShots should be {0}.", TestConfig.NumberOfPreviousVersions);
            BaseTestSite.Assert.AreEqual(
                (uint)0, snapShotArray.NumberOfSnapShotsReturned, "NumberOfSnapShotsReturned should be 0.");

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Enumerate snapshots by sending the second IOCTL request: FSCTL_SRV_ENUMERATE_SNAPSHOTS, with MaxOutputResponse set to 65536.");
            client.EnumerateSnapShots(
                treeId,
                fileId,
                Smb2FunctionalClient.DefaultMaxOutputResponse,
                out snapShotArray,
                checker: (Packet_Header header, IOCTL_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "FSCTL_SRV_ENUMERATE_SNAPSHOTS should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
            });

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Verify SRV_SNAPSHOT_ARRAY returned in response.");
            BaseTestSite.Assert.AreEqual(
                TestConfig.NumberOfPreviousVersions, snapShotArray.NumberOfSnapShots, "NumberOfSnapShots should be {0}.", TestConfig.NumberOfPreviousVersions);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "NumberOfSnapShotsReturned is {0}.", snapShotArray.NumberOfSnapShotsReturned);


            string[] versionArray = System.Text.Encoding.Unicode.GetString(snapShotArray.SnapShots).Split('\0');
            BaseTestSite.Assert.AreEqual(
                snapShotArray.NumberOfSnapShotsReturned + 2,
                (uint)versionArray.Length,
                "The field \"SnapShots\" should be separated by UNICODE null characters and terminated by two UNICODE null characters.");

            DateTime dt;
            for (int i = 0; i < snapShotArray.NumberOfSnapShotsReturned; ++i)
            {
                BaseTestSite.Assert.IsTrue(
                    DateTime.TryParseExact(versionArray[i], "@GMT-yyyy.MM.dd-HH.mm.ss", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out dt),
                    "This SnapShot is {0}. The format of each SnapShot should be \"@GMT-YYYY.MM.DD-HH.MM.SS\". ", versionArray[i]);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client.Close(treeId, fileId);
            client.TreeDisconnect(treeId);
            client.LogOff();
        }
        public void ResilientOpenScavengerTimer_ReconnectBeforeTimeout_Zero()
        {
            /// 1. Open Resilient Handle with timeout = 0. When server receive resilient handle with timeout = 0,
            /// it will set the Open.ResilientTimeout as implementation-specific value.
            /// 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);

            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, 0);
            OpenFileAndResilientRequest(
                prepareClient,
                clientGuid,
                fileName,
                0, // convert second to millisecond
                out fileId);

            /// Open.ResiliencyTimeout SHOULD be set to an implementation-specific value.<294>
            uint timeout = DEFAULT_RESILIENT_TIMEOUT_IN_SECONDS;
            if (TestConfig.Platform == Platform.WindowsServer2012)
            {
                /// <294> Section 3.3.5.15.9: Windows 7 and Windows Server 2008 R2 servers keep the resilient
                /// handle open indefinitely when the requested Timeout value is equal to zero.
                /// Windows 8 and Windows Server 2012 servers set a constant value of 120 seconds.
                timeout = DEFAULT_RESILIENT_TIMEOUT_IN_SECONDS;
            }
            else
            {
                timeout = testConfig.DefaultResiliencyTimeoutInSecond;
            }
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Server should set the timeout of resilient handle to implementation-specific timeout {0} seconds", timeout);

            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.", timeout - 1);

            Thread.Sleep(TimeSpan.FromSeconds(timeout - 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();
        }
예제 #8
0
        public void BVT_ResilientHandle_LockSequence()
        {
            #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; CREATE.");
            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);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends WRITE request.");
            clientBeforeDisconnection.Write(treeId, fileId, "12345678");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends Flush request.");
            clientBeforeDisconnection.Flush(treeId, fileId);
            #endregion

            //The LockSequence field of the SMB2 lock request MUST be set to (BucketNumber<< 4) + BucketSequence.
            int  bucketNum    = 1;
            int  bucketSeq    = 1;
            uint lockSequence = (uint)bucketNum << 4 + bucketSeq;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "The first client sends LOCK request with LockSequence set to (BucketNumber<< 4) + BucketSequence");
            clientBeforeDisconnection.Lock(treeId,
                                           lockSequence,
                                           fileId,
                                           new LOCK_ELEMENT[]
            {
                new LOCK_ELEMENT
                {
                    Flags  = LOCK_ELEMENT_Flags_Values.LOCKFLAG_EXCLUSIVE_LOCK | LOCK_ELEMENT_Flags_Values.LOCKFLAG_FAIL_IMMEDIATELY,
                    Offset = 0,
                    Length = 4
                }
            });

            clientBeforeDisconnection.Disconnect();

            #region clientAfterDisconnection Opens the Previously Created File
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Start the second client to reconnect to the file created by the first client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE (with SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context).");
            clientAfterDisconnection.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid);
            clientAfterDisconnection.ReconnectSessionSetup(clientBeforeDisconnection,
                                                           TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
            clientAfterDisconnection.TreeConnect(sharePath, out treeId);
            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

            //If the sequence numbers are equal, the server MUST complete the lock/unlock request with success.
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The second client sends LOCK request with the same LockSequence with the first client.");
            clientAfterDisconnection.Lock(treeId,
                                          lockSequence, //Using same Lock Sequence
                                          fileId,
                                          new LOCK_ELEMENT[]
            {
                new LOCK_ELEMENT
                {
                    Flags  = LOCK_ELEMENT_Flags_Values.LOCKFLAG_EXCLUSIVE_LOCK | LOCK_ELEMENT_Flags_Values.LOCKFLAG_FAIL_IMMEDIATELY,
                    Offset = 0,
                    Length = 4
                }
            });

            clientAfterDisconnection.Lock(treeId,
                                          lockSequence + 1, //Using different Lock Sequence
                                          fileId,
                                          new LOCK_ELEMENT[]
            {
                new LOCK_ELEMENT
                {
                    Flags  = LOCK_ELEMENT_Flags_Values.LOCKFLAG_EXCLUSIVE_LOCK | LOCK_ELEMENT_Flags_Values.LOCKFLAG_FAIL_IMMEDIATELY,
                    Offset = 0,
                    Length = 4
                }
            },
                                          (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_LOCK_NOT_GRANTED,
                    header.Status,
                    "If the range being locked is already locked by another open in a way that does not allow this open to take a lock on the range, " +
                    "and if SMB2_LOCKFLAG_FAIL_IMMEDIATELY is set, the server MUST fail the request with STATUS_LOCK_NOT_GRANTED. " +
                    "Actually server returns {0}.",
                    Smb2Status.GetStatusCode(header.Status));
            });

            #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
        }
예제 #9
0
        public void BVT_SetGetIntegrityInfo()
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_SET_INTEGRITY_INFORMATION, CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION);
            #endregion

            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client creates a file by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE");
            status = client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });

            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint   treeId;
            string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.FileShareSupportingIntegrityInfo);
            status = client.TreeConnect(uncSharePath, out treeId);

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            status = client.Create(
                treeId,
                GetTestFileName(uncSharePath),
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);

            FSCTL_GET_INTEGRITY_INFO_OUTPUT getIntegrityInfo;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_GET_INTEGRITY_INFORMATION.");
            status = client.GetIntegrityInfo(treeId, fileId, out getIntegrityInfo);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Integrity info returned in FSCTL_GET_INTEGRITY_INFO request: ChecksumAlgorithm {0}, Flags {1}, ChecksumChunkSizeInBytes {2}, ClusterSizeInBytes {3}",
                getIntegrityInfo.ChecksumAlgorithm, getIntegrityInfo.Flags, getIntegrityInfo.ChecksumChunkSizeInBytes, getIntegrityInfo.ClusterSizeInBytes);

            FSCTL_SET_INTEGRIY_INFO_INPUT setIntegrityInfo;
            setIntegrityInfo.ChecksumAlgorithm = FSCTL_SET_INTEGRITY_INFO_INPUT_CHECKSUMALGORITHM.CHECKSUM_TYPE_CRC64;
            setIntegrityInfo.Flags             = FSCTL_SET_INTEGRITY_INFO_INPUT_FLAGS.FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF;
            setIntegrityInfo.Reserved          = FSCTL_SET_INTEGRITY_INFO_INPUT_RESERVED.V1;
            byte[] buffer = TypeMarshal.ToBytes <FSCTL_SET_INTEGRIY_INFO_INPUT>(setIntegrityInfo);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Attempt to set integrity info with ChecksumAlgrithm {0}, Flags {1}",
                setIntegrityInfo.ChecksumAlgorithm, setIntegrityInfo.Flags);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_SET_INTEGRITY_INFORMATION after changed the value of the following fields in FSCTL_SET_INTEGRIY_INFO_INPUT: ChecksumAlgorithm, Flags, Reserved.");
            status = client.SetIntegrityInfo(treeId, fileId, buffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_GET_INTEGRITY_INFORMATION.");
            status = client.GetIntegrityInfo(treeId, fileId, out getIntegrityInfo);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Current ChecksumAlgorithm is " + getIntegrityInfo.ChecksumAlgorithm);
            BaseTestSite.Assert.AreEqual(
                (ushort)setIntegrityInfo.ChecksumAlgorithm,
                (ushort)getIntegrityInfo.ChecksumAlgorithm,
                "ChecksumAlgorithm field after set should be {0}, actual value is {1}", setIntegrityInfo.ChecksumAlgorithm, getIntegrityInfo.ChecksumAlgorithm);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Current Flags is " + getIntegrityInfo.Flags);
            BaseTestSite.Assert.AreEqual(
                (uint)setIntegrityInfo.Flags,
                (uint)getIntegrityInfo.Flags,
                "Flags field after set should be {0}, actual value is {1}", setIntegrityInfo.Flags, getIntegrityInfo.Flags);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF.");
            status = client.Close(treeId, fileId);
            status = client.TreeDisconnect(treeId);
            status = client.LogOff();
        }
예제 #10
0
        public void ResilientOpenScavengerTimer_ReconnectAfterTimeout()
        {
            /// 1. Wait for MaxResiliencyTimeoutInSecond seconds to expire the Resilient Timer and make sure that the Timer is not started.
            /// 2. Open Resilient Handle with specific timeout.
            /// 3. Disconnect to start the Resilient Timer.
            /// 4. Wait for specific timeout + 1 seconds.
            /// 5. Reconnect the resilient handle and expect the handle is terminated.

            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb21);
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Wait {0} seconds to make sure Resilient Timer is not started.", testConfig.MaxResiliencyTimeoutInSecond);
            Thread.Sleep(TimeSpan.FromSeconds((int)testConfig.MaxResiliencyTimeoutInSecond));

            Smb2FunctionalClient prepareClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            uint   timeoutInSecond = testConfig.MaxResiliencyTimeoutInSecond / 2;
            Guid   clientGuid      = Guid.NewGuid();
            string fileName        = GetTestFileName(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare));
            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 + 10);
            Thread.Sleep(TimeSpan.FromSeconds(timeoutInSecond + 10));

            Smb2FunctionalClient reconnectClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Re-establish Resilient Open, verify the returned status is STATUS_OBJECT_NAME_NOT_FOUND.");
            ReconnectResilientHandle(
                reconnectClient,
                clientGuid,
                fileName,
                fileId,
                NtStatus.STATUS_OBJECT_NAME_NOT_FOUND,
                "Resilient handle should be terminated.");

            // clean
            reconnectClient.Disconnect();
        }