コード例 #1
0
        public void NegotiateRequest(ModelDialectRevision maxSmbVersionClientSupported, SigningFlagType signingFlagType, SigningEnabledType signingEnabledType, SigningRequiredType signingRequiredType)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported));
            Packet_Header_Flags_Values headerFlags = (signingFlagType == SigningFlagType.SignedFlagSet) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE;

            SigningEnabledType resSigningEnabledType = SigningEnabledType.SigningEnabledNotSet;
            SigningRequiredType resSigningRequiredType = SigningRequiredType.SigningRequiredNotSet;
            uint status = testClient.Negotiate(
                headerFlags,
                dialects,
                GetNegotiateSecurityMode(signingEnabledType, signingRequiredType),
                checker: (header, response) =>
                {
                    resSigningEnabledType =
                        response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED) ?
                        SigningEnabledType.SigningEnabledSet : SigningEnabledType.SigningEnabledNotSet;
                    resSigningRequiredType =
                        response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED) ?
                        SigningRequiredType.SigningRequiredSet : SigningRequiredType.SigningRequiredNotSet;
                });

            NegotiateResponse((ModelSmb2Status)status, resSigningEnabledType, resSigningRequiredType, signingConfig);
        }
コード例 #2
0
        public void BVT_SMB2Basic_CancelRegisteredChangeNotify()
        {
            uint status;
            string testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Test directory \"{0}\" was created on share \"{1}\"", testDirectory, TestConfig.BasicFileShare);

            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client1.Smb2Client.ChangeNotifyResponseReceived += new Action<FILE_NOTIFY_INFORMATION[],Packet_Header,CHANGE_NOTIFY_Response>(OnChangeNotifyResponseReceived);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client to create a file by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE");
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            status = client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId1;
            status = client1.TreeConnect(uncSharePath, out treeId1);
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId1;
            status = client1.Create(
                treeId1,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts);

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client starts to register CHANGE_NOTIFY on directory \"{0}\"", testDirectory);
            client1.ChangeNotify(treeId1, fileId1, CompletionFilter_Values.FILE_NOTIFY_CHANGE_LAST_ACCESS);

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client starts to cancel the registered CHANGE_NOTIFY on directory \"{0}\"", testDirectory);
            client1.Cancel();

            BaseTestSite.Assert.IsTrue(
                changeNotificationReceived.WaitOne(TestConfig.WaitTimeoutInMilliseconds),
                "Change notification should be received within {0} milliseconds", TestConfig.WaitTimeoutInMilliseconds);

            BaseTestSite.Assert.AreNotEqual(
                Smb2Status.STATUS_SUCCESS,
                receivedChangeNotifyHeader.Status, "CHANGE_NOTIFY is not expected to success after cancel, actually server returns {0}.",
                Smb2Status.GetStatusCode(receivedChangeNotifyHeader.Status));
            BaseTestSite.CaptureRequirementIfAreEqual(
                Smb2Status.STATUS_CANCELLED,
                receivedChangeNotifyHeader.Status,
                RequirementCategory.STATUS_CANCELLED.Id,
                RequirementCategory.STATUS_CANCELLED.Description);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client1.Close(treeId1, fileId1);
            client1.TreeDisconnect(treeId1);
            client1.LogOff();
        }
コード例 #3
0
        public void SetupConnection(ModelSessionSecurityContext securityContext)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

            // SMB2 Negotiate
            // Model cases only test Dialect lower than 3.11
            DialectRevision[] dialects =
                Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302);
            testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled);

            // SMB2 SESSION SETUP
            AccountCredential account = null;
            switch (securityContext)
            {
                case ModelSessionSecurityContext.Admin:
                    account = testConfig.AccountCredential;
                    break;
                case ModelSessionSecurityContext.NonAdmin:
                    account = testConfig.NonAdminAccountCredential;
                    break;
                default:
                    throw new InvalidOperationException(securityContext + " is not supported.");
            }

            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                account,
                testConfig.UseServerGssToken);

            // reset TreeId
            this.treeId = 0;
        }
コード例 #4
0
        public void BVT_SMB2Basic_QueryAndSet_FileInfo()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Starts a client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT.");
            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId1;

            client1.TreeConnect(uncSharePath, out treeId1);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with desired access set to GENERIC_READ and GENERIC_WRITE to create a file.");
            Smb2CreateContextResponse[] serverCreateContexts;
            CREATE_Response?            createResponse = null;
            string fileName = Guid.NewGuid().ToString() + ".txt";
            FILEID fileId1;

            client1.Create(
                treeId1,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts,
                accessMask: AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE,
                checker: (Packet_Header header, CREATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                BaseTestSite.Log.Add(LogEntryKind.TestStep,
                                     "FileBasicInformation in CREATE response: \r\nCreationTime: {0}\r\nLastAccessTime:{1}\r\nLastWriteTime: {2}\r\nChangeTime: {3}\r\nFileAttributes: {4}",
                                     Smb2Utility.ConvertToDateTimeUtc(response.CreationTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                     Smb2Utility.ConvertToDateTimeUtc(response.LastAccessTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                     Smb2Utility.ConvertToDateTimeUtc(response.LastWriteTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                     Smb2Utility.ConvertToDateTimeUtc(response.ChangeTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                     response.FileAttributes);
                createResponse = response;
            });

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends QUERY_INFO request to query file attributes.");
            byte[] outputBuffer;
            client1.QueryFileAttributes(
                treeId1,
                (byte)FileInformationClasses.FileBasicInformation,
                QUERY_INFO_Request_Flags_Values.SL_RESTART_SCAN,
                fileId1,
                new byte[0] {
            },
                out outputBuffer);

            FileBasicInformation fileBasicInfo = TypeMarshal.ToStruct <FileBasicInformation>(outputBuffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "FileBasicInformation in QUERY_INFO response: \r\nCreationTime: {0}\r\nLastAccessTime:{1}\r\nLastWriteTime: {2}\r\nChangeTime: {3}\r\nFileAttributes: {4}",
                                 Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.CreationTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                 Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.LastAccessTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                 Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.LastWriteTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                 Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.ChangeTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                                 fileBasicInfo.FileAttributes);

            BaseTestSite.Assert.AreEqual(createResponse.Value.CreationTime, fileBasicInfo.CreationTime, "CreationTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.LastAccessTime, fileBasicInfo.LastAccessTime, "LastAccessTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.LastWriteTime, fileBasicInfo.LastWriteTime, "LastWriteTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.ChangeTime, fileBasicInfo.ChangeTime, "ChangeTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.FileAttributes, fileBasicInfo.FileAttributes, "FileAttributes received in QUERY_INFO response should be identical with that got in CREATE response");

            FileBasicInformation fileBasicInfoToSet = fileBasicInfo;
            DateTime             dateTimeToSet      = DateTime.UtcNow;

            fileBasicInfoToSet.LastAccessTime = Smb2Utility.ConvertToFileTime(dateTimeToSet);

            byte[] inputBuffer;
            inputBuffer = TypeMarshal.ToBytes <FileBasicInformation>(fileBasicInfoToSet);
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client sends SetFileAttributes request to set LastAccessTime for the file to {0}", dateTimeToSet.ToString("MM/dd/yyy hh:mm:ss.ffffff"));
            client1.SetFileAttributes(
                treeId1,
                (byte)FileInformationClasses.FileBasicInformation,
                fileId1,
                inputBuffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends QUERY request to query file attributes.");
            client1.QueryFileAttributes(
                treeId1,
                (byte)FileInformationClasses.FileBasicInformation,
                QUERY_INFO_Request_Flags_Values.SL_RESTART_SCAN,
                fileId1,
                new byte[0] {
            },
                out outputBuffer);
            fileBasicInfo = TypeMarshal.ToStruct <FileBasicInformation>(outputBuffer);
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "LastAccessTime in QUERY_INFO response after SET_INFO {0}",
                Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.LastAccessTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"));

            BaseTestSite.Assert.AreNotEqual(
                createResponse.Value.LastAccessTime,
                fileBasicInfo.LastAccessTime,
                "LastAccessTime (dwHighDateTime:{0}, dwLowDateTime:{1}) after SET_INFO should not be equal to the value (dwHighDateTime:{2}, dwLowDateTime:{3}) before SET_INFO",
                fileBasicInfo.LastAccessTime.dwHighDateTime, fileBasicInfo.LastAccessTime.dwLowDateTime, createResponse.Value.LastAccessTime.dwHighDateTime, createResponse.Value.LastAccessTime.dwLowDateTime);

            BaseTestSite.Assert.AreEqual(
                fileBasicInfoToSet.LastAccessTime,
                fileBasicInfo.LastAccessTime,
                "LastAccessTime (dwHighDateTime:{0}, dwLowDateTime:{1}) queried after SET_INFO should be equal to the desired value (dwHighDateTime:{2}, dwLowDateTime:{3})",
                fileBasicInfo.LastAccessTime.dwHighDateTime, fileBasicInfo.LastAccessTime.dwLowDateTime, fileBasicInfoToSet.LastAccessTime.dwHighDateTime, fileBasicInfoToSet.LastAccessTime.dwLowDateTime);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client1.Close(treeId1, fileId1);
            client1.TreeDisconnect(treeId1);
            client1.LogOff();
        }
コード例 #5
0
        private void InitializeMainChannel(
            ModelDialectRevision maxSmbVersionClientSupported,
            Guid clientGuid,
            ReplayModelShareType shareType,
            out uint treeId,
            bool isReconnect = false,
            bool isClientSupportPersistent = true)
        {
            Site.Assume.IsNull(smb2ClientMainChannel, "Expect smb2ClientMainChannel is NULL.");

            smb2ClientMainChannel = new Smb2FunctionalClient(testConfig.Timeout, testConfig, Site);
            smb2ClientMainChannel.Smb2Client.LeaseBreakNotificationReceived  += new Action <Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived);
            smb2ClientMainChannel.Smb2Client.OplockBreakNotificationReceived += new Action <Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnOplockBreakNotificationReceived);
            serverIpMainChannel   = (shareType == ReplayModelShareType.CAShare ? testConfig.CAShareServerIP : testConfig.SutIPAddress);
            serverNameMainChannel = (shareType == ReplayModelShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName;
            smb2ClientMainChannel.ConnectToServer(testConfig.UnderlyingTransport, serverNameMainChannel, serverIpMainChannel);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported));
            uint status;

            #region Negotiate

            Capabilities_Values capability = isClientSupportPersistent ?
                                             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 |
                                             Capabilities_Values.GLOBAL_CAP_ENCRYPTION :
                                             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_ENCRYPTION;
            NEGOTIATE_Response?negotiateResponse = null;
            clientCapabilitiesMainChannel = ModelUtility.IsSmb3xFamily(maxSmbVersionClientSupported)? capability : Capabilities_Values.NONE;
            status = smb2ClientMainChannel.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilitiesMainChannel,
                clientGuid: maxSmbVersionClientSupported == ModelDialectRevision.Smb2002 ? Guid.Empty : clientGuid,
                checker: (header, response) =>
            {
                Site.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed", header.Command);

                negotiateResponse = response;
            });

            dialectMainChannel = negotiateResponse.Value.DialectRevision;
            #endregion

            #region SESSION_SETUP
            principleNameMainChannel = (shareType == ReplayModelShareType.CAShare ? testConfig.CAShareServerName : testConfig.SutComputerName);
            if (isReconnect)
            {
                status = smb2ClientMainChannel.ReconnectSessionSetup(
                    sessionIdMainChannel,
                    testConfig.DefaultSecurityPackage,
                    principleNameMainChannel,
                    testConfig.AccountCredential,
                    testConfig.UseServerGssToken);
                sessionIdMainChannel  = smb2ClientMainChannel.SessionId;
                sessionKeyMainChannel = smb2ClientMainChannel.SessionKey;
            }
            else
            {
                status = smb2ClientMainChannel.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    principleNameMainChannel,
                    testConfig.AccountCredential,
                    testConfig.UseServerGssToken);
                sessionIdMainChannel  = smb2ClientMainChannel.SessionId;
                sessionKeyMainChannel = smb2ClientMainChannel.SessionKey;
            }

            Site.Log.Add(
                LogEntryKind.Debug,
                "Global encryption disabled");

            #endregion

            #region TREE_CONNECT to share
            sharePathMainChannel = (shareType == ReplayModelShareType.CAShare ?
                                    Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName) : Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare));
            status = smb2ClientMainChannel.TreeConnect(
                sharePathMainChannel,
                out treeId);
            Site.Log.Add(
                LogEntryKind.Debug,
                "Establish main channel to connect share {0}", sharePathMainChannel);

            smb2ClientMainChannel.SetTreeEncryption(treeId, false);
            #endregion
        }
        /// <summary>
        /// Read and write file within byte lock range when the file is locked or unlocked
        /// </summary>
        /// <param name="isLocked">Set true to indicate that byte lock range is taken on the file</param>
        /// <param name="serverName">Name of file server to access</param>
        /// <param name="targetFileName">Target file name to read and write</param>
        private void ValidateByteLockRangeFromAnotherClient(bool isLocked, string serverName, string targetFileName)
        {
            uint status = 0;

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

            client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, serverName, currentAccessIp);

            status = client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);

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

            uint treeId;
            status = client.TreeConnect(uncSharePath, out treeId);

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

            string data;
            Random random = new Random();
            uint offset = (uint)random.Next(0, TestConfig.WriteBufferLengthInKb * 1024 - 1);
            uint length = (uint)random.Next(0, (int)(TestConfig.WriteBufferLengthInKb * 1024 - offset));
            status = client.Read(treeId, fileId, offset, length, out data);

            status = client.Write(treeId, fileId, contentWrite, checker: (header, response) => { });
            if (isLocked)
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content to locked range of file from different client is not expected to success");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            }
            else
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content in file should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            }
        }
コード例 #7
0
        /// <summary>
        /// The two client connects to the two IP addresses of scaleout file server
        /// Negotiate, SessionSetup, TreeConnect
        /// </summary>
        private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            client.ConnectToServerOverTCP(ip);
            client.Negotiate(
                Smb2Utility.GetDialects(DialectRevision.Smb21),
                testConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.ScaleOutFileServerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId);

            return client;
        }
        private void ConnectToShare(
            Smb2FunctionalClient client,
            Guid clientGuid,
            out uint treeId)
        {
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            // Negotiate
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
                    {
                        BaseTestSite.Assert.AreEqual(
                            Smb2Status.STATUS_SUCCESS,
                            header.Status,
                            "CREATE should succeed.");

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

            // SMB2 SESSION SETUP
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            // SMB2 Tree Connect
            client.TreeConnect(
                Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare),
                out treeId);
        }
コード例 #9
0
        private void FileOperation(OplockFileOperation fileOperation, string fileName)
        {
            Site.Log.Add(LogEntryKind.Debug, "File operation on same file from another client");

            Smb2FunctionalClient clientForAnotherOpen = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            clientForAnotherOpen.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress, testConfig.ClientNic1IPAddress);

            clientForAnotherOpen.Negotiate(new DialectRevision[]{negotiatedDialect}, testConfig.IsSMB1NegotiateEnabled);

            clientForAnotherOpen.SessionSetup(
                testConfig.DefaultSecurityPackage,
                server,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            uint treeIdForAnotherOpen;
            clientForAnotherOpen.TreeConnect(
                uncSharePath,
                out treeIdForAnotherOpen);

            FILEID fileIdForAnotherOpen;
            Smb2CreateContextResponse[] serverCreateContexts;

            clientForAnotherOpen.Create(
                treeIdForAnotherOpen,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdForAnotherOpen,
                out serverCreateContexts);

            if (fileOperation == OplockFileOperation.WriteFromAnotherOpen)
            {
                string writeContent = Smb2Utility.CreateRandomString(1);

                clientForAnotherOpen.Write(treeIdForAnotherOpen, fileIdForAnotherOpen, writeContent);
            }
        }
コード例 #10
0
        private void TestAsymmetricShare(DialectRevision requestMaxDialect, string serverName, bool isAsymmetricShare)
        {
            int  ret        = 0;
            uint callId     = 0;
            Guid clientGuid = Guid.NewGuid();
            WITNESS_INTERFACE_INFO registerInterface;
            string shareName = isAsymmetricShare ? TestConfig.AsymmetricShare : TestConfig.BasicFileShare;

            #region Get the file server to access it through SMB2
            IPAddress currentAccessIp = SWNTestUtility.GetCurrentAccessIP(serverName);
            BaseTestSite.Assert.IsNotNull(currentAccessIp, "IP address of the file server should NOT be empty");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Got the IP {0} to access the file server", currentAccessIp.ToString());
            #endregion

            #region Connect to the asymmetric share
            uncSharePath = Smb2Utility.GetUncPath(serverName, shareName);
            string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
            testDirectory = CreateTestDirectory(uncSharePath);
            string file = Path.Combine(testDirectory, Guid.NewGuid().ToString());

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP");
            smb2Client = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);
            smb2Client.ConnectToServerOverTCP(currentAccessIp);
            smb2Client.Negotiate(
                Smb2Utility.GetDialects(requestMaxDialect),
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: 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,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "Negotiate should succeed.");
                BaseTestSite.Assert.AreEqual(
                    requestMaxDialect,
                    response.DialectRevision,
                    "The server is expected to use dialect {0}. Actual dialect is {1}",
                    requestMaxDialect,
                    response.DialectRevision);
            });
            smb2Client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                serverName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint treeId = 0;
            Share_Capabilities_Values shareCapabilities = Share_Capabilities_Values.NONE;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request to the {0} on the {1}", shareName, serverName);
            DoUntilSucceed(
                () => smb2Client.TreeConnect(uncSharePath, out treeId, (header, response) => { shareCapabilities = response.Capabilities; }),
                TestConfig.FailoverTimeout,
                "Retry TreeConnect until succeed within timeout span");

            if (requestMaxDialect == DialectRevision.Smb302 && isAsymmetricShare)
            {
                BaseTestSite.Assert.IsTrue(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_ASYMMETRIC),
                                           "The capabilities of the share should contain SHARE_CAP_ASYMMETRIC. The actual capabilities is {0}.", shareCapabilities);
            }
            else
            {
                BaseTestSite.Assert.IsFalse(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_ASYMMETRIC),
                                            "The capabilities of the share should not contain SHARE_CAP_ASYMMETRIC. The actual capabilities is {0}.", shareCapabilities);

                #region Disconnect current SMB2 connection
                smb2Client.TreeDisconnect(treeId);
                smb2Client.LogOff();
                smb2Client.Disconnect();
                #endregion
                return;
            }

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            Guid createGuid = Guid.NewGuid();
            Guid leaseKey   = Guid.NewGuid();
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client writes to the file.");
            smb2Client.Create(
                treeId,
                file,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE);
            smb2Client.Write(treeId, fileId, content);

            string readContent;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client reads from the file.");
            smb2Client.Read(treeId, fileId, 0, (uint)content.Length, out readContent);
            BaseTestSite.Assert.IsTrue(
                content.Equals(readContent),
                "Content read should be identical to that written.");
            #endregion

            #region Get register interface
            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIp,
                                                           TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                                                           TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, serverName), TestConfig.FailoverTimeout,
                           "Retry BindServer until succeed within timeout span");

            WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST();
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrGetInterfaceList.");
            DoUntilSucceed(() =>
            {
                ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret);
                return(SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform));
            }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span");

            swnClientForInterface.SwnUnbind(TestConfig.Timeout);

            SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

            #endregion

            #region Get SHARE_MOVE_NOTIFICATION
            DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness,
                                                           (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6),
                                                           TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                                                           TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, serverName), TestConfig.FailoverTimeout,
                           "Retry BindServer until succeed within timeout span");

            string clientName = TestConfig.WitnessClientName;

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", serverName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddress: {0}", currentAccessIp.ToString());
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClient Name: {0}", clientName);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrRegisterEx.");
            ret = swnClientForWitness.WitnessrRegisterEx(SwnVersion.SWN_VERSION_2,
                                                         serverName,
                                                         shareName,
                                                         currentAccessIp.ToString(),
                                                         clientName,
                                                         WitnessrRegisterExFlagsValue.WITNESS_REGISTER_IP_NOTIFICATION,
                                                         120,
                                                         out pContext);
            BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegisterEx returns with result code = 0x{0:x8}", ret);

            BaseTestSite.Assert.IsNotNull(pContext, "Expect pContext is not null.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrAsyncNotify.");
            callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
            BaseTestSite.Assert.AreNotEqual <uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

            // NOTICE
            // This comment is for current Windows Cluster test environment.
            // Current test environment has only two nodes and both they are optimum nodes.
            // So whatever the server name is, SHARE_MOVE_NOTIFICATION notification will be recieved.
            // The configuration items 'OptimumNodeOfAsymmetricShare' and 'NonOptimumNodeOfAsymmetricShare' are assigned the same default value.
            // The code in if block will be executed all the time.
            if (serverName == TestConfig.NonOptimumNodeOfAsymmetricShare)
            {
                #region Expect that SHARE_MOVE_NOTIFICATION notification will be received  when the client connects to the asymmetric share on the non-optimum share
                RESP_ASYNC_NOTIFY respNotify;
                ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);
                SWNTestUtility.PrintNotification(respNotify);
                SWNTestUtility.VerifyClientMoveShareMoveAndIpChange(respNotify, SwnMessageType.SHARE_MOVE_NOTIFICATION, (uint)SwnIPAddrInfoFlags.IPADDR_V4, TestConfig.Platform);

                #region Get the new IpAddr
                IPADDR_INFO_LIST ipAddrInfoList;
                SwnUtility.ParseIPAddrInfoList(respNotify, out ipAddrInfoList);
                currentAccessIp = (ipAddrInfoList.IPAddrList[0].Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(ipAddrInfoList.IPAddrList[0].IPV4) : SWNTestUtility.ConvertIPV6(ipAddrInfoList.IPAddrList[0].IPV6);
                #endregion

                #region Unregister SWN Witness
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrUnRegister.");
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
                #endregion

                #region Disconnect current SMB2 connection
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF; DISCONNECT.");
                smb2Client.TreeDisconnect(treeId);
                smb2Client.LogOff();
                smb2Client.Disconnect();
                #endregion
                #endregion
            }
            else
            {
                #region Expect that no SHARE_MOVE_NOTIFICATION notification will be received when the client connects to the asymmetric share on the optimum share
                bool isNotificationReceived = false;
                try
                {
                    RESP_ASYNC_NOTIFY respNotify;
                    ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                    isNotificationReceived = true;
                }
                catch (TimeoutException)
                {
                    isNotificationReceived = false;
                }

                #region Disconnect current SMB2 connection
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending the following requests: TREE_DISCONNECT; LOG_OFF; DISCONNECT");
                smb2Client.TreeDisconnect(treeId);
                smb2Client.LogOff();
                smb2Client.Disconnect();
                #endregion

                #region Unregister SWN Witness
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrUnRegister.");
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
                #endregion

                BaseTestSite.Assert.IsFalse(isNotificationReceived, "Expect that no notification will be received when the client has connected to asymmetric share on the optimum node.");
                #endregion

                return;
            }
            #endregion

            #region Connect to the share on the optimum node
            smb2Client = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Got the IP {0} to access the file server", currentAccessIp.ToString());

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP");
            smb2Client.ConnectToServerOverTCP(currentAccessIp);
            smb2Client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: 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,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "Negotiate should succeed.");
            });
            smb2Client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                serverName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client sends TREE_CONNECT and wait for a response until timeout.");
            DoUntilSucceed(
                () => smb2Client.TreeConnect(uncSharePath, out treeId, (header, response) => { }),
                TestConfig.FailoverTimeout,
                "Retry TreeConnect until succeed within timeout span");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client writes to the file.");
            smb2Client.Create(
                treeId,
                file,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE);
            smb2Client.Write(treeId, fileId, content);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client reads from the file.");
            smb2Client.Read(treeId, fileId, 0, (uint)content.Length, out readContent);
            BaseTestSite.Assert.IsTrue(
                content.Equals(readContent),
                "Content read should be identical to that written.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF; DISCONNECT.");
            smb2Client.TreeDisconnect(treeId);
            smb2Client.LogOff();
            smb2Client.Disconnect();
            #endregion
        }
コード例 #11
0
        public void TestFileLeasing(Smb2CreateContextRequest leaseContext)
        {
            #region Add Event Handler
            client1.Smb2Client.LeaseBreakNotificationReceived += new Action <Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived);
            clientToAckLeaseBreak = client1;
            #endregion

            #region Client1 Open a File with Lease RWH
            BaseTestSite.Log.Add(LogEntryKind.TestStep,
                                 "Start the first client to create a file by sending the following requests: 1. NEGOTIATE; 2. SESSION_SETUP; 3. TREE_CONNECT; 4. CREATE (with context: {0})",
                                 leaseContext is Smb2CreateRequestLease ? "LeaseV1" : "LeaseV2");
            client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            client1.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
            uint client1TreeId;
            client1.TreeConnect(sharePath, out client1TreeId);
            FILEID client1FileId;
            Smb2CreateContextResponse[] createContextResponse;
            client1.Create(client1TreeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out client1FileId, out createContextResponse, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                           new Smb2CreateContextRequest[]
            {
                leaseContext
            }
                           );
            #endregion

            #region Check Response Contexts

            if (leaseContext is Smb2CreateRequestLease)
            {
                Smb2CreateRequestLease leaseRequest = leaseContext as Smb2CreateRequestLease;
                CheckCreateContextResponses(createContextResponse, new DefaultLeaseResponseChecker(BaseTestSite, leaseRequest.LeaseKey, leaseRequest.LeaseState, LeaseFlagsValues.NONE));
            }
            else if (leaseContext is Smb2CreateRequestLeaseV2)
            {
                Smb2CreateRequestLeaseV2 leaseRequest = leaseContext as Smb2CreateRequestLeaseV2;
                CheckCreateContextResponses(createContextResponse, new DefaultLeaseV2ResponseChecker(BaseTestSite, leaseRequest.LeaseKey, leaseRequest.LeaseState, LeaseFlagsValues.NONE));
            }
            #endregion

            // Create a task to invoke CheckBreakNotification
            var checkBreakNotificationTask = Task.Run(() => CheckBreakNotification(client1TreeId));

            #region Lease Break RWH => RH
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a second client to create the same file with the first client by sending the following requests: 1. NEGOTIATE; 2. SESSION_SETUP; 3. TREE_CONNECT; 4. CREATE");
            expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_HANDLE_CACHING;
            client2.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            client2.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
            uint client2TreeId;
            client2.TreeConnect(sharePath, out client2TreeId);
            FILEID client2FileId;
            client2.Create(client2TreeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out client2FileId, out createContextResponse);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends LEASE_BREAK_ACKNOWLEDGEMENT request to break lease state to RH after receiving LEASE_BREAK_NOTIFICATION response from server.");
            #endregion

            #region Lease BreakRH => NONE
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The second client sends WRITE request.");
            expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_NONE;
            byte[] data = { 0 };
            client2.Write(client2TreeId, client2FileId, data);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends LEASE_BREAK_ACKNOWLEDGEMENT request to break lease state to NONE after receiving LEASE_BREAK_NOTIFICATION response from server.");
            #endregion

            #region Tear Down Clients
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the first client by sending the following requests: 1. CLOSE; 2. TREE_DISCONNECT; 3. LOG_OFF");
            client1.Close(client1TreeId, client1FileId);
            client1.TreeDisconnect(client1TreeId);
            client1.LogOff();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending the following requests: 1. CLOSE; 2. TREE_DISCONNECT; 3. LOG_OFF");
            client2.Close(client2TreeId, client2FileId);
            client2.TreeDisconnect(client2TreeId);
            client2.LogOff();
            #endregion

            checkBreakNotificationTask.Wait(TestConfig.WaitTimeoutInMilliseconds);
        }
コード例 #12
0
        private void CreateFile(string uncShare, string fileName, int lengthInByte)
        {
            Site.Log.Add(
                LogEntryKind.Debug,
                "Create file {0} in share {1}", fileName, uncShare);

            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);

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

            client.CreditGoal = 32;

            client.Negotiate(
                new DialectRevision[] { ModelUtility.GetDialectRevision(config.MaxSmbVersionSupported) },
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_LARGE_MTU);

            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            uint tId;

            client.TreeConnect(
                uncShare,
                out tId);

            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fId;

            client.Create(
                tId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fId,
                out serverCreateContexts);

            string content;

            if (isMultiCreditSupportedOnConnection)
            {
                content = Smb2Utility.CreateRandomStringInByte(lengthInByte);
                client.Write(tId, fId, content);
            }
            else
            {
                // Write several times if server does not support multi credit
                int   writeTimes = lengthInByte / (64 * 1024);
                int   rest       = lengthInByte % (64 * 1024);
                ulong offset     = 0;

                for (int time = 0; time < writeTimes; time++)
                {
                    content = Smb2Utility.CreateRandomString(64);
                    client.Write(tId, fId, content, offset);
                    offset += 64 * 1024;
                }

                if (rest != 0)
                {
                    content = Smb2Utility.CreateRandomStringInByte(rest);
                    client.Write(tId, fId, content, offset);
                }
            }

            client.Close(tId, fId);

            client.TreeDisconnect(tId);

            client.LogOff();

            client.Disconnect();

            Site.Log.Add(
                LogEntryKind.Debug,
                "Create file {0} in share {1}", fileName, uncShare);
        }
コード例 #13
0
        public void SetupConnection(ModelDialectRevision clientMaxDialect)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            testClient.RequestSent += new Action <Packet_Header>(PrintSequenceWindow);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));

            uint status;
            NEGOTIATE_Response?negotiateResponse = null;

            status = testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_LARGE_MTU,
                checker: (header, response) =>
            {
                Site.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed", header.Command);

                // The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE.
                Site.Assert.IsTrue(
                    header.CreditRequestResponse >= 1,
                    "The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE");

                negotiateResponse = response;
            });

            Site.Log.Add(
                LogEntryKind.Debug,
                "The maximum size, in bytes, of Length in READ/WRITE that server will accept on the connection is {0}",
                testClient.MaxBufferSize);

            Site.Assert.AreEqual(
                ModelUtility.GetDialectRevision(clientMaxDialect),
                negotiateResponse.Value.DialectRevision,
                "DialectRevision {0} is expected", ModelUtility.GetDialectRevision(clientMaxDialect));

            negotiateDialect = negotiateResponse.Value.DialectRevision;

            if ((negotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(negotiateDialect))
                // In case server does not support multicredit even implement Smb21 or Smb30
                && testConfig.IsMultiCreditSupported)
            {
                isMultiCreditSupportedOnConnection = true;
            }
            else
            {
                isMultiCreditSupportedOnConnection = false;
            }

            status = testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            status = testClient.TreeConnect(
                uncSharePath,
                out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            fileName = Guid.NewGuid().ToString();
            status   = testClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);
        }
コード例 #14
0
        /// <summary>
        /// Connect share on file server
        /// </summary>
        /// <param name="serverIp">Server IP address used for connection</param>
        /// <param name="clientIp">Client IP address used for connection</param>
        /// <param name="client">Client object to initialize the connection</param>
        /// <param name="treeId">Out param tree id connected</param>
        /// <param name="enableEncryptionPerShare">True indicates encryption enabled per share, otherwise disabled</param>
        private void ConnectShare(IPAddress serverIp, IPAddress clientIp, Smb2FunctionalClient client, out uint treeId, bool enableEncryptionPerShare = false)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Connect to share {0} with following steps.", uncSharePath);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Connect to server via Nic with Ip {0}", clientIp.ToString());
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp);

            #region Negotiate
            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 | Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            status = client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed.");

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

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

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Global encryption disabled");
            #endregion

            #region TREE_CONNECT to share
            status = client.TreeConnect(
                uncSharePath,
                out treeId,
                (Packet_Header header, TREE_CONNECT_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "TreeConnect should succeed.");

                if (enableEncryptionPerShare)
                {
                    BaseTestSite.Assert.AreEqual(
                        ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA,
                        ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA & response.ShareFlags,
                        "Server should set SMB2_SHAREFLAG_ENCRYPT_DATA for ShareFlags field in TREE_CONNECT response");
                }
            });

            client.SetTreeEncryption(treeId, enableEncryptionPerShare);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Finish connecting to share {0}", uncSharePath);
        }
コード例 #15
0
        /// <summary>
        /// Common method used to connect to target server, including the following message sequences:
        /// 1. Negotiate
        /// 2. Session Setup
        /// 3. Tree Connect
        /// </summary>
        /// <param name="smb2Dialect"></param>
        /// <param name="client"></param>
        /// <param name="clientGuid"></param>
        /// <param name="account"></param>
        /// <param name="connectShareType"></param>
        /// <param name="treeId"></param>
        /// <param name="clientBeforeDisconnection"></param>
        protected virtual void Connect(DialectRevision smb2Dialect, Smb2FunctionalClient client, Guid clientGuid, AccountCredential account, ConnectShareType connectShareType, out uint treeId, Smb2FunctionalClient clientBeforeDisconnection)
        {
            DialectRevision[]   requestDialect     = Smb2Utility.GetDialects(smb2Dialect);
            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_PERSISTENT_HANDLES;
            SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;

            IPAddress targetIPAddress = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerIP : testConfig.SutIPAddress;
            string    targetServer    = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName;

            client.ConnectToServer(TestConfig.UnderlyingTransport, targetServer, targetIPAddress);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends NEGOTIATE request.", clientGuid);
            client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                clientSecurityMode,
                clientCapabilities,
                clientGuid);

            if (null != clientBeforeDisconnection)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request to reconnect to the previous session.", clientGuid);
                client.ReconnectSessionSetup(
                    clientBeforeDisconnection,
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    account,
                    testConfig.UseServerGssToken);
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request.", clientGuid);
                client.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    account,
                    testConfig.UseServerGssToken);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends TREE_CONNECT request.", clientGuid);
            client.TreeConnect(
                durableHandleUncSharePath,
                out treeId,
                checker: (header, response) =>
            {
                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Capabilities in TREE_CONNECT response: {0}", response.Capabilities);

                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should be successful", header.Command);

                if (connectShareType == ConnectShareType.CAShare)
                {
                    BaseTestSite.Assert.AreEqual(
                        Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY,
                        Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities,
                        "The share should have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability");
                }

                if (connectShareType == ConnectShareType.BasicShare)
                {
                    BaseTestSite.Assert.AreNotEqual(
                        Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY,
                        Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities,
                        "The share should not have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability");
                }
            });
        }
コード例 #16
0
 private void SetupClientConnection(Smb2FunctionalClient client, out uint clientTreeId)
 {
     client.Negotiate(testConfig.RequestDialects, testConfig.IsSMB1NegotiateEnabled);
     client.SessionSetup(testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, false);
     client.TreeConnect(sharePath, out clientTreeId);
 }
コード例 #17
0
        public void BVT_SMB2Basic_LockAndUnLock()
        {
            uint status;
            string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);

            #region From client1 lock a byte range and try to write content to the file within the range
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "From client1 locks a byte range and try to write content to the file within the range.");

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Start client1 to create a file with sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE.");
            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            status = client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId1;
            status = client1.TreeConnect(uncSharePath, out treeId1);
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId1;
            string fileName = Guid.NewGuid().ToString() + ".txt";
            status = client1.Create(
                treeId1,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client1 writes content to the file created.");
            status = client1.Write(treeId1, fileId1, content);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down client1 by sending CLOSE request.");
            client1.Close(treeId1, fileId1);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client1 sends CREATE request.");
            status = client1.Create(
                treeId1,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts);

            //Construct LOCK_ELEMENT
            LOCK_ELEMENT[] locks = new LOCK_ELEMENT[1];
            uint lockSequence = 0;
            locks[0].Offset = 0;
            locks[0].Length = (ulong)TestConfig.WriteBufferLengthInKb * 1024;
            locks[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_SHARED_LOCK;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client1 starts to lock a byte range for file \"{0}\" with parameters offset:{1}, length:{2}, flags: {3})",
                fileName, locks[0].Offset, locks[0].Length, locks[0].Flags.ToString());
            status = client1.Lock(treeId1, lockSequence++, fileId1, locks);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client1 sends WRITE request to write content to the locking range");
            status = client1.Write(
                treeId1,
                fileId1,
                content,
                checker: (header, response) =>
                {
                    BaseTestSite.Assert.AreNotEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "All opens MUST NOT be allowed to write within the range when SMB2_LOCKFLAG_SHARED_LOCK set, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                    BaseTestSite.CaptureRequirementIfAreEqual(
                        Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                        header.Status,
                        RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                        RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
                });
            #endregion

            #region From client2 to read and write the locking range of the same file after lock
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "From client2 to read and take shared lock on the locking range of the same file after lock");

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Start client2 to create a file with sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE.");
            client2 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client2.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = client2.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            status = client2.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId2;
            status = client2.TreeConnect(uncSharePath, out treeId2);
            FILEID fileId2;
            status = client2.Create(
                treeId2,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId2,
                out serverCreateContexts);

            string data;
            Random random = new Random();
            uint offset = (uint)random.Next(0, TestConfig.WriteBufferLengthInKb * 1024 - 1);
            uint length = (uint)random.Next(0, (int)(TestConfig.WriteBufferLengthInKb * 1024 - offset));
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 sends READ request to read a random area in the locking range of file \"{0}\" with offset: {1}, length: {2}",
                fileName, offset, length);
            status = client2.Read(treeId2, fileId2, offset, length, out data);

            //Construct LOCK_ELEMENT
            LOCK_ELEMENT[] locksFromOtherOpen = new LOCK_ELEMENT[1];
            locksFromOtherOpen[0].Offset = offset;
            locksFromOtherOpen[0].Length = (ulong)length;
            locksFromOtherOpen[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_SHARED_LOCK;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 attempts to take a shared lock on random range of file \"{0}\" with parameters offset:{1}, length:{2}, flags: {3})",
                fileName, locksFromOtherOpen[0].Offset, locksFromOtherOpen[0].Length, locksFromOtherOpen[0].Flags.ToString());
            status = client2.Lock(treeId2, lockSequence++, fileId2, locksFromOtherOpen);

            locksFromOtherOpen[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_UNLOCK;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 attempts to unlock the range");
            status = client2.Lock(treeId2, lockSequence++, fileId2, locksFromOtherOpen);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 sends WRITE request to write a random area in the locking range of file \"{0}\" after lock", fileName);
            status = client2.Write(
                treeId2,
                fileId2,
                content,
                offset,
                checker: (header, response) =>
                {
                    BaseTestSite.Assert.AreNotEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "All opens MUST NOT be allowed to write within the range when SMB2_LOCKFLAG_SHARED_LOCK set, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                    BaseTestSite.CaptureRequirementIfAreEqual(
                        Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                        header.Status,
                        RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                        RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
                });
            #endregion

            #region From client1 unlock the range
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client1 unlocks the range");
            locks[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_UNLOCK;
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Client1 attempts to unlock the range");
            status = client1.Lock(treeId1, lockSequence++, fileId1, locks);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down client1 by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client1.Close(treeId1, fileId1);
            client1.TreeDisconnect(treeId1);
            client1.LogOff();
            #endregion

            #region From client2 write content to the previous locking range after unlock
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 sends WRITE request to write content to the previous locking range after unlock");
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Client2 attempts to write a random area in the locking range of file \"{0}\" after unlock", fileName);
            status = client2.Write(treeId2, fileId2, content, offset);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down client2 by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client2.Close(treeId2, fileId2);
            client2.TreeDisconnect(treeId2);
            client2.LogOff();
            #endregion
        }
コード例 #18
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 | Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            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, checker: (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);
        }
コード例 #19
0
        public void InvalidCreateRequestStructureSize()
        {
            uint status;

            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, this.Site);
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            status = client1.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled);

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

            uint treeId;
            status = client1.TreeConnect(uncSharePath, out treeId);
            string fileName = "BVT_SMB2Basic_InvalidCreateRequestStructureSize" + Guid.NewGuid();

            FILEID fileID;
            Smb2CreateContextResponse[] serverCreateContexts;

            // [MS-SMB2] Section 2.2.13 SMB2 CREATE Request
            // StructureSize (2 bytes):  The client MUST set this field to 57, indicating the size of the request structure, not including the header.
            // The client MUST set it to this value regardless of how long Buffer[] actually is in the request being sent.

            // So set the StuctureSize to 58 here to make "the size of the SMB2 CREATE Request is less than specified in the StructureSize field".
            client1.BeforeSendingPacket(ReplacePacketByStructureSize);
            status = client1.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileID,
                out serverCreateContexts,
                checker: (header, response) => { });

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_INVALID_PARAMETER,
                status,
                "The size of the SMB2 CREATE Request (excluding the SMB2 header) is less than specified in the StructureSize field, then the request MUST be failed with STATUS_ INVALID_PARAMETER");

            client1.TreeDisconnect(treeId);
            client1.LogOff();
        }
コード例 #20
0
        public void ValidateNegotiateInfo_Negative_SMB311()
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb311);
            // Server will terminate connection if Validate Negotiate Info Request is not signed.
            TestConfig.CheckSigning();
            #endregion

            Smb2FunctionalClient testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

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

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

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb311, response);

                negotiateResponse = response;
            });

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

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

            VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq = new VALIDATE_NEGOTIATE_INFO_Request();
            validateNegotiateInfoReq.Guid         = clientGuid;
            validateNegotiateInfoReq.Capabilities = clientCapabilities;
            validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE;
            validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
            validateNegotiateInfoReq.Dialects     = requestDialects;

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

            try
            {
                BaseTestSite.Log.Add(
                    LogEntryKind.TestStep,
                    "Attempt to send a request with an SMB2 header with a Command value equal to SMB2 IOCTL, and a CtlCode of FSCTL_VALIDATE_NEGOTIATE_INFO.");

                client.ValidateNegotiateInfo(
                    treeId,
                    inputBuffer,
                    out outputBuffer
                    );
            }
            catch
            {
            }

            BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when Connection.Dialect is \"3.1.1\".");
        }
        /// <summary>
        /// Connect share on file server
        /// </summary>
        /// <param name="serverIp">Server IP address used for connection</param>
        /// <param name="clientIp">Client IP address used for connection</param>
        /// <param name="client">Client object to initialize the connection</param>
        /// <param name="treeId">Out param tree id connected</param>
        /// <param name="enableEncryptionPerShare">True indicates encryption enabled per share, otherwise disabled</param>
        private void ConnectShare(IPAddress serverIp, IPAddress clientIp, Smb2FunctionalClient client, out uint treeId, bool enableEncryptionPerShare = false)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Connect to share {0} with following steps.", uncSharePath);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Connect to server via Nic with Ip {0}", clientIp.ToString());
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp);

            #region Negotiate
            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 | Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            status = client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                            Smb2Status.STATUS_SUCCESS,
                            header.Status,
                            "CREATE should succeed.");

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

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

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Global encryption disabled");
            #endregion

            #region TREE_CONNECT to share
            status = client.TreeConnect(
                uncSharePath,
                out treeId,
                (Packet_Header header, TREE_CONNECT_Response response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "TreeConnect should succeed.");

                    if (enableEncryptionPerShare)
                    {
                        BaseTestSite.Assert.AreEqual(
                            ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA,
                            ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA & response.ShareFlags,
                            "Server should set SMB2_SHAREFLAG_ENCRYPT_DATA for ShareFlags field in TREE_CONNECT response");
                    }
                });

            client.SetTreeEncryption(treeId, enableEncryptionPerShare);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Finish connecting to share {0}", uncSharePath);
        }
コード例 #22
0
        /// <summary>
        /// Establish main channel, which includes NEGOTIATE, SESSION_SETUP and TREE_CONNECT
        /// </summary>
        /// <param name="requestDialect">Dialects in request</param>
        /// <param name="serverIp">Ip address on server side</param>
        /// <param name="clientIp">Ip address on client side</param>
        /// <param name="treeId">Out param for tree Id that connected</param>
        /// <param name="enableEncryptionPerShare">Set true if enable encryption on share, otherwise set false</param>
        private void EstablishMainChannel(
            DialectRevision[] requestDialect,
            IPAddress serverIp,
            IPAddress clientIp,
            out uint treeId,
            bool enableEncryptionPerShare = false)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Establish main channel to connect share {0} with following steps.", uncSharePath);

            mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp);

            #region Negotiate
            Capabilities_Values mainChannelClientCapabilities = 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 | Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            status = mainChannelClient.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                clientGuid: clientGuid,
                capabilityValue: mainChannelClientCapabilities,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed.");

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response);
            }
                );

            #endregion

            #region SESSION_SETUP
            status = mainChannelClient.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Global encryption disabled");
            #endregion

            #region Retrieve 2nd IP on server for alternative channel if there is
            #region TREE_CONNECT to IPC$
            string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName);
            status = mainChannelClient.TreeConnect(ipcPath, out treeId);
            #endregion

            if (TestConfig.UnderlyingTransport == Smb2TransportType.Tcp)
            {
                #region IOCTL FSCTL_QUERY_NETWORK_INTERFACE_INFO
                NETWORK_INTERFACE_INFO_Response[] networkInfoResponses;
                string interfaceAddress;
                bool   secondAddressQueried = false;
                status = mainChannelClient.QueryNetworkInterfaceInfo(treeId, out networkInfoResponses);

                foreach (NETWORK_INTERFACE_INFO_Response netInfoResp in networkInfoResponses)
                {
                    interfaceAddress = netInfoResp.AddressStorage.Address;
                    if (interfaceAddress != null)
                    {
                        BaseTestSite.Log.Add(
                            LogEntryKind.Debug,
                            "Get NETWORK_INTERFACE_INFO: " + interfaceAddress);
                        if (interfaceAddress == serverIps[1].ToString())
                        {
                            secondAddressQueried = true;
                            BaseTestSite.Log.Add(
                                LogEntryKind.Debug,
                                "Address queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO matches server second address {0}", serverIps[1].ToString());
                            break;
                        }
                    }
                }
                BaseTestSite.Assert.IsTrue(
                    secondAddressQueried,
                    "Second address {0} should be queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO", serverIps[1].ToString());
                #endregion
            }
            #endregion

            #region TREE_CONNECT to share
            status = mainChannelClient.TreeConnect(
                uncSharePath,
                out treeId,
                (Packet_Header header, TREE_CONNECT_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "TreeConnect should succeed.");

                if (enableEncryptionPerShare)
                {
                    BaseTestSite.Assert.AreEqual(
                        ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA,
                        ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA & response.ShareFlags,
                        "Server should set SMB2_SHAREFLAG_ENCRYPT_DATA for ShareFlags field in TREE_CONNECT response");
                }
            });

            mainChannelClient.SetTreeEncryption(treeId, enableEncryptionPerShare);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Finish establishing main channel to connect share {0}", uncSharePath);
        }
コード例 #23
0
        public void SetupConnection(ModelDialectRevision clientMaxDialect)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            testClient.RequestSent += new Action<Packet_Header>(PrintSequenceWindow);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));

            uint status;
            NEGOTIATE_Response? negotiateResponse = null;
            status = testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_LARGE_MTU,
                checker: (header, response) =>
                {
                    Site.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "{0} should succeed", header.Command);

                    // The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE.
                    Site.Assert.IsTrue(
                        header.CreditRequestResponse >= 1,
                        "The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE");

                    negotiateResponse = response;
                });

            Site.Log.Add(
                LogEntryKind.Debug,
                "The maximum size, in bytes, of Length in READ/WRITE that server will accept on the connection is {0}",
                testClient.MaxBufferSize);

            Site.Assert.AreEqual(
                ModelUtility.GetDialectRevision(clientMaxDialect),
                negotiateResponse.Value.DialectRevision,
                "DialectRevision {0} is expected", ModelUtility.GetDialectRevision(clientMaxDialect));

            negotiateDialect = negotiateResponse.Value.DialectRevision;

            if ((negotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(negotiateDialect))
                // In case server does not support multicredit even implement Smb21 or Smb30
                && testConfig.IsMultiCreditSupported)
            {
                isMultiCreditSupportedOnConnection = true;
            }
            else
            {
                isMultiCreditSupportedOnConnection = false;
            }

            status = testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            status = testClient.TreeConnect(
                uncSharePath,
                out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            fileName = Guid.NewGuid().ToString();
            status = testClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);
        }
コード例 #24
0
        public void PrepareOpen(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            ModelHandleType modelHandleType,
            OplockLeaseType oplockLeaseType)
        {
            // Lease V2 cases only apply on the server implements SMB 3.x family.
            if (oplockLeaseType == OplockLeaseType.LeaseV2)
            {
                testConfig.CheckDialect(DialectRevision.Smb30);
            }

            // Lease V1 cases only apply on the server implements SMB 2.1 and 3.x family.
            if (oplockLeaseType == OplockLeaseType.LeaseV1)
            {
                testConfig.CheckDialect(DialectRevision.Smb21);
            }

            if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2) &&
                !testConfig.IsLeasingSupported)
            {
                Site.Assert.Inconclusive("Test case is applicable in servers that support leasing.");
            }

            requestDialect     = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));
            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;
            if (persistentBit == PersistentBitType.PersistentBitSet)
            {
                clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            }

            clientGuid       = Guid.NewGuid();
            requestedContext = oplockLeaseType;
            isCAShare        = (connectToCAShare == CAShareType.CAShare);
            IPAddress targetIPAddress;
            string    targetServer;

            #region Connect to Common Share or CA Share
            if (!isCAShare)
            {
                sharePath       = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
                fileName        = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt";
                targetIPAddress = testConfig.SutIPAddress;
                targetServer    = testConfig.SutComputerName;
            }
            else
            {
                sharePath       = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName);
                fileName        = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt";
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer    = testConfig.CAShareServerName;
            }

            testClientBeforeDisconnection            = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientBeforeDisconnection.CreditGoal = 20;
            testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            testClientBeforeDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
            {
                if (Smb2Utility.IsSmb3xFamily(response.DialectRevision) &&
                    handleConfig.IsPersistentHandleSupported &&
                    persistentBit == PersistentBitType.PersistentBitSet)
                {
                    Site.Assert.IsTrue(
                        response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES),
                        "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " +
                        "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " +
                        "Actual capabilities are {0}", response.Capabilities);
                }
            });

            testClientBeforeDisconnection.SessionSetup(
                testConfig.DefaultSecurityPackage,
                targetServer,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection);

            #endregion

            #region Create operation according to the handle type and context
            Smb2CreateContextRequest[]  prepareRequestContext = null;
            Smb2CreateContextResponse[] serverCreateContexts  = null;
            RequestedOplockLevel_Values requestedOplockLevel  = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;

            switch (oplockLeaseType)
            {
            case OplockLeaseType.LeaseV1:
            {
                testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE);

                prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType);
                requestedOplockLevel  = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
            }
            break;

            case OplockLeaseType.LeaseV2:
            {
                testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2);

                prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType);
                requestedOplockLevel  = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
            }
            break;

            case OplockLeaseType.BatchOplock:
            {
                prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType);
                requestedOplockLevel  = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
            }
            break;

            case OplockLeaseType.NoOplockOrLease:
            {
                prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType);
                requestedOplockLevel  = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            }
            break;
            }

            PrepareOpenCreate(
                testClientBeforeDisconnection,
                treeIdBeforeDisconnection,
                fileName,
                out fileIdBeforDisconnection,
                out serverCreateContexts,
                requestedOplockLevel,
                prepareRequestContext);

            #endregion
        }
        /// <summary>
        /// Create an open from client, this include NEGOTIATE and SESSION_SETUP with server, TREE_CONNECT to the share and CREATE an open to file/directory
        /// </summary>
        /// <param name="client">Client used to take the operation</param>
        /// <param name="clientGuid">Client GUID for negotiation</param>
        /// <param name="targetName">File/directory name for the open</param>
        /// <param name="isDirectory">Set true if create open to a directory, set false if create open to a file</param>
        /// <param name="accessMask">Desired access when create the open</param>
        /// <param name="treeId">Out param for tree id used to connect to the share</param>
        /// <param name="fileId">Out param for file id that is associated with the open</param>
        /// <param name="shareAccess">Optional param for share access when create the open</param>
        /// <returns>Status value returned from CREATE request</returns>
        private uint CreateOpenFromClient(Smb2FunctionalClient client, Guid clientGuid, string targetName, bool isDirectory, LeaseStateValues requestLeaseState, AccessMask accessMask, out uint treeId, out FILEID fileId, ShareAccess_Values shareAccess = ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE)
        {
            #region Negotiate
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client {0} sends NEGOTIATE request with the following capabilities: 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.", clientGuid.ToString());
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: 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,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "Negotiation is expected success, actually server returns {0}", Smb2Status.GetStatusCode(header.Status));

                    TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response);
                });
            #endregion

            #region SESSION_SETUP
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends SESSION_SETUP request.", clientGuid.ToString());
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends TREE_CONNECT request.", clientGuid.ToString());
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            Smb2CreateContextResponse[] serverCreateContexts;
            CreateOptions_Values createOptions;

            if (isDirectory)
            {
                createOptions = CreateOptions_Values.FILE_DIRECTORY_FILE;
            }
            else
            {
                createOptions = CreateOptions_Values.FILE_NON_DIRECTORY_FILE;
            }

            // Include FILE_DELETE_ON_CLOSE if accessMask has DELETE
            if ((accessMask & AccessMask.DELETE) == AccessMask.DELETE)
            {
                createOptions = createOptions | CreateOptions_Values.FILE_DELETE_ON_CLOSE;
            }

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client {0} sends CREATE request with the lease state in SMB2_CREATE_REQUEST_LEASE_V2 set to {1}.", clientGuid.ToString(), requestLeaseState);
            status = client.Create(
                treeId,
                targetName,
                createOptions,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
                {
                    new Smb2CreateRequestLeaseV2
                    {
                        LeaseKey = clientGuid,
                        LeaseState = requestLeaseState
                    }
                },
                accessMask: accessMask,
                shareAccess: shareAccess,
                checker: (header, response) => { });

            return status;
            #endregion
        }
コード例 #26
0
        public void ReconnectOpenRequest(
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext,
            OplockLeaseType oplockLeaseType,
            LeaseKeyDifferentialType leaseKeyDifferentialType,
            ClientIdType clientIdType,
            CreateGuidType createGuidType)
        {
            if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2) &&
                !testConfig.IsLeasingSupported)
            {
                Site.Assert.Inconclusive("Test case is applicable in servers that support leasing.");
            }

            bool isSameLeaseKey   = (leaseKeyDifferentialType == LeaseKeyDifferentialType.SameLeaseKey);
            bool isSameClient     = (clientIdType == ClientIdType.SameClient);
            bool isSameCreateGuid = (createGuidType == CreateGuidType.SameCreateGuid);

            FILEID fileIdAfterDisconnection;

            Smb2CreateContextResponse[] serverCreateContexts;
            IPAddress targetIPAddress;
            string    targetServer;
            string    targetShare;

            #region Construct Create Contexts
            Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext(
                DurableV1RequestContext.DurableV1RequestContextNotExist,
                DurableV2RequestContext.DurableV2RequestContextNotExist,
                durableV1ReconnectContext,
                durableV2ReconnectContext,
                oplockLeaseType,
                isSameLeaseKey,
                isSameCreateGuid);
            #endregion

            #region Client reconnect to server

            Site.Log.Add(LogEntryKind.Debug, "Client reconnect to server");

            #region Reconnect to Common Share or CA Share
            if (!isCAShare)
            {
                targetIPAddress = testConfig.SutIPAddress;
                targetServer    = testConfig.SutComputerName;
                targetShare     = testConfig.BasicFileShare;
            }
            else
            {
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer    = testConfig.CAShareServerName;
                targetShare     = testConfig.CAShareName;
            }

            // Connect to Server
            testClientAfterDisconnection            = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientAfterDisconnection.CreditGoal = 10;
            testClientAfterDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            // Negotiate
            testClientAfterDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                // If the reconnect use the same client guid, then keep client guid the same value, otherwise use a new client guid.
                clientGuid: (isSameClient ? clientGuid : Guid.NewGuid()));

            uint status = testClientAfterDisconnection.SessionSetup(
                testConfig.DefaultSecurityPackage,
                targetServer,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Reconnect Session Setup should be successful, actual status is {0}", Smb2Status.GetStatusCode(status));

            // TreeConnect
            testClientAfterDisconnection.TreeConnect(sharePath, out treeIdAfterDisconnection);

            #endregion

            #region Send Create request according to different context combination

            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            switch (oplockLeaseType)
            {
            case OplockLeaseType.NoOplockOrLease:
            {
                requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            }
            break;

            case OplockLeaseType.BatchOplock:
            {
                requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
            }
            break;

            case OplockLeaseType.LeaseV1:
            case OplockLeaseType.LeaseV2:
            {
                requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
            }
            break;
            }

            status = OpenCreate(
                testClientAfterDisconnection,
                treeIdAfterDisconnection,
                fileName,
                out fileIdAfterDisconnection,
                out serverCreateContexts,
                requestedOplockLevel,
                smb2CreateContextRequest);

            #endregion

            DurableHandleResponseContext durableHandleResponse;
            LeaseResponseContext         leaseResponse;
            CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse);
            OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig);

            testClientAfterDisconnection.TreeDisconnect(treeIdAfterDisconnection);
            testClientAfterDisconnection.LogOff();

            #endregion
        }
コード例 #27
0
        public void ReconnectOpenRequest(
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext,
            OplockLeaseType oplockLeaseType,
            LeaseKeyDifferentialType leaseKeyDifferentialType,
            ClientIdType clientIdType,
            CreateGuidType createGuidType)
        {
            if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2)
                && !testConfig.IsLeasingSupported)
                Site.Assert.Inconclusive("Test case is applicable in servers that support leasing.");

            bool isSameLeaseKey = (leaseKeyDifferentialType == LeaseKeyDifferentialType.SameLeaseKey);
            bool isSameClient = (clientIdType == ClientIdType.SameClient);
            bool isSameCreateGuid = (createGuidType == CreateGuidType.SameCreateGuid);

            FILEID fileIdAfterDisconnection;
            Smb2CreateContextResponse[] serverCreateContexts;
            IPAddress targetIPAddress;
            string targetServer;
            string targetShare;

            #region Construct Create Contexts
            Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext(
                DurableV1RequestContext.DurableV1RequestContextNotExist,
                DurableV2RequestContext.DurableV2RequestContextNotExist,
                durableV1ReconnectContext,
                durableV2ReconnectContext,
                oplockLeaseType,
                isSameLeaseKey,
                isSameCreateGuid);
            #endregion

            #region Client reconnect to server

            Site.Log.Add(LogEntryKind.Debug, "Client reconnect to server");

            #region Reconnect to Common Share or CA Share
            if (!isCAShare)
            {
                targetIPAddress = testConfig.SutIPAddress;
                targetServer = testConfig.SutComputerName;
                targetShare = testConfig.BasicFileShare;
            }
            else
            {
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer = testConfig.CAShareServerName;
                targetShare = testConfig.CAShareName;
            }

            // Connect to Server
            testClientAfterDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientAfterDisconnection.CreditGoal = 10;
            testClientAfterDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            // Negotiate
            testClientAfterDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                // If the reconnect use the same client guid, then keep client guid the same value, otherwise use a new client guid.
                clientGuid: (isSameClient ? clientGuid : Guid.NewGuid()));

            uint status = testClientAfterDisconnection.SessionSetup(
                testConfig.DefaultSecurityPackage,
                targetServer,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Reconnect Session Setup should be successful, actual status is {0}", Smb2Status.GetStatusCode(status));

            // TreeConnect
            testClientAfterDisconnection.TreeConnect(sharePath, out treeIdAfterDisconnection);

            #endregion

            #region Send Create request according to different context combination

            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            switch (oplockLeaseType)
            {
                case OplockLeaseType.NoOplockOrLease:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
                    }
                    break;

                case OplockLeaseType.BatchOplock:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
                    }
                    break;

                case OplockLeaseType.LeaseV1:
                case OplockLeaseType.LeaseV2:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;
            }

            status = OpenCreate(
                testClientAfterDisconnection,
                treeIdAfterDisconnection,
                fileName,
                out fileIdAfterDisconnection,
                out serverCreateContexts,
                requestedOplockLevel,
                smb2CreateContextRequest);

            #endregion

            DurableHandleResponseContext durableHandleResponse;
            LeaseResponseContext leaseResponse;
            CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse);
            OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig);

            testClientAfterDisconnection.TreeDisconnect(treeIdAfterDisconnection);
            testClientAfterDisconnection.LogOff();

            #endregion
        }
コード例 #28
0
        public void OpenRequest(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            OplockLeaseType oplockLeaseType,
            DurableV1RequestContext durableV1RequestContext,
            DurableV2RequestContext durableV2RequestContext,
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext)
        {
            requestDialect     = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));
            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;
            if (persistentBit == PersistentBitType.PersistentBitSet)
            {
                clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            }

            clientGuid       = Guid.NewGuid();
            requestedContext = oplockLeaseType;
            isCAShare        = (connectToCAShare == CAShareType.CAShare);
            IPAddress targetIPAddress;
            string    targetServer;

            #region Connect to Common Share or CA Share
            if (!isCAShare)
            {
                sharePath       = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
                fileName        = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt";
                targetIPAddress = testConfig.SutIPAddress;
                targetServer    = testConfig.SutComputerName;
            }
            else
            {
                sharePath       = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName);
                fileName        = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt";
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer    = testConfig.CAShareServerName;
            }


            testClientBeforeDisconnection            = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientBeforeDisconnection.CreditGoal = 20;
            testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            testClientBeforeDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
            {
                if (Smb2Utility.IsSmb3xFamily(response.DialectRevision) &&
                    handleConfig.IsPersistentHandleSupported &&
                    persistentBit == PersistentBitType.PersistentBitSet)
                {
                    Site.Assert.IsTrue(
                        response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES),
                        "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " +
                        "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " +
                        "Actual capabilities are {0}", response.Capabilities);
                }
            });

            testClientBeforeDisconnection.SessionSetup(
                testConfig.DefaultSecurityPackage,
                targetServer,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection);

            #endregion

            #region Construct Create Contexts
            Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext(
                durableV1RequestContext,
                durableV2RequestContext,
                durableV1ReconnectContext,
                durableV2ReconnectContext,
                oplockLeaseType,
                false,
                false);
            #endregion

            #region Send Create request according to different context combination
            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            switch (oplockLeaseType)
            {
            case OplockLeaseType.NoOplockOrLease:
            {
                requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            }
            break;

            case OplockLeaseType.BatchOplock:
            {
                requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
            }
            break;

            case OplockLeaseType.LeaseV1:
            case OplockLeaseType.LeaseV2:
            {
                requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
            }
            break;
            }

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            uint status = OpenCreate(
                testClientBeforeDisconnection,
                treeIdBeforeDisconnection,
                fileName,
                out fileId,
                out serverCreateContexts,
                requestedOplockLevel,
                smb2CreateContextRequest);

            #endregion

            DurableHandleResponseContext durableHandleResponse;
            LeaseResponseContext         leaseResponse;
            CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse);
            OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig);

            testClientBeforeDisconnection.TreeDisconnect(treeIdAfterDisconnection, (header, response) => { });
            testClientBeforeDisconnection.LogOff();
        }
        /// <summary>
        /// Common method used to connect to target server, including the following message sequences:
        /// 1. Negotiate
        /// 2. Session Setup
        /// 3. Tree Connect
        /// </summary>
        /// <param name="smb2Dialect"></param>
        /// <param name="client"></param>
        /// <param name="clientGuid"></param>
        /// <param name="account"></param>
        /// <param name="connectShareType"></param>
        /// <param name="treeId"></param>
        /// <param name="clientBeforeDisconnection"></param>
        protected virtual void Connect(DialectRevision smb2Dialect, Smb2FunctionalClient client, Guid clientGuid, AccountCredential account, ConnectShareType connectShareType, out uint treeId, Smb2FunctionalClient clientBeforeDisconnection)
        {
            DialectRevision[] requestDialect = Smb2Utility.GetDialects(smb2Dialect);
            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_PERSISTENT_HANDLES;
            SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;

            IPAddress targetIPAddress = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerIP : testConfig.SutIPAddress;
            string targetServer = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName;

            client.ConnectToServer(TestConfig.UnderlyingTransport, targetServer, targetIPAddress);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends NEGOTIATE request.", clientGuid);
            client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                clientSecurityMode,
                clientCapabilities,
                clientGuid);

            if (null != clientBeforeDisconnection)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request to reconnect to the previous session.", clientGuid);
                client.ReconnectSessionSetup(
                    clientBeforeDisconnection,
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    account,
                    testConfig.UseServerGssToken);
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request.", clientGuid);
                client.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    account,
                    testConfig.UseServerGssToken);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends TREE_CONNECT request.", clientGuid);
            client.TreeConnect(
                durableHandleUncSharePath,
                out treeId,
                checker: (header, response) =>
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Capabilities in TREE_CONNECT response: {0}", response.Capabilities);

                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "{0} should be successful", header.Command);

                    if (connectShareType == ConnectShareType.CAShare)
                    {
                        BaseTestSite.Assert.AreEqual(
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY,
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities,
                            "The share should have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability");
                    }

                    if (connectShareType == ConnectShareType.BasicShare)
                    {
                        BaseTestSite.Assert.AreNotEqual(
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY,
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities,
                            "The share should not have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability");
                    }
                });
        }
コード例 #30
0
        public void SharePermission_CreateClose_DeleteFile_MaximalAccessNotIncludeDeleteOrGenericAll()
        {
            _SID sid = DtypUtility.GetSidFromAccount(TestConfig.DomainName, azUser01Name);

            if (!dynamicallyConfigurableShareExist)
            {
                BaseTestSite.Assert.Inconclusive("Required share: {0} does not exist!", dynamicallyConfigurableShareName);
            }
            object ace = DtypUtility.CreateAccessAllowedAce(sid, (DtypUtility.ACCESS_MASK_STANDARD_RIGHTS_ALL | DtypUtility.ACCESS_MASK_SPECIFIC_RIGHTS_ALL) & ~DtypUtility.ACCESS_MASK_DELETE, ACE_FLAGS.None);

            SetSecurityDescriptorOnDynamicallyConfigurableShare(ace);
            string shareName    = dynamicallyConfigurableShareName;
            string shareUncPath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, shareName);

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

            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            AccountCredential user = new AccountCredential(TestConfig.DomainName, azUser01Name, TestConfig.UserPassword);

            try
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message.");
                client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", user.AccountName, user.DomainName);
                client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, user, false);

                uint treeId;
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", shareUncPath);
                client.TreeConnect(shareUncPath, out treeId, checker: (header, response) =>
                {
                    BaseTestSite.Assert.IsTrue((response.MaximalAccess.ACCESS_MASK & (DtypUtility.ACCESS_MASK_DELETE | DtypUtility.ACCESS_MASK_GENERIC_ALL)) == 0,
                                               "Treeconnect.MaximalAccess does not include DELETE or GENERIC_ALL.");
                });

                string fileName = GetTestFileName(shareUncPath);
                FILEID fileId;
                Smb2CreateContextResponse[] createContexResponse;
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create the file: {0}", fileName);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends CREATE request.");
                uint status = client.Create(
                    treeId,
                    fileName,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    out fileId,
                    out createContexResponse,
                    accessMask: AccessMask.FILE_READ_DATA | AccessMask.FILE_WRITE_DATA | AccessMask.FILE_APPEND_DATA |
                    AccessMask.FILE_READ_ATTRIBUTES | AccessMask.FILE_READ_EA | AccessMask.FILE_WRITE_ATTRIBUTES |
                    AccessMask.FILE_WRITE_EA | AccessMask.READ_CONTROL | AccessMask.WRITE_DAC | AccessMask.SYNCHRONIZE, // Windows client behavior
                    shareAccess: ShareAccess_Values.NONE,
                    createDisposition: CreateDisposition_Values.FILE_CREATE);
                client.Close(treeId, fileId);

                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Delete the file: {0}", fileName);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends CREATE request with FILE_DELETE_ON_CLOSE flag set in CreateOptions .");
                status = client.Create(
                    treeId,
                    fileName,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                    out fileId,
                    out createContexResponse,
                    accessMask: AccessMask.DELETE | AccessMask.FILE_READ_ATTRIBUTES | AccessMask.SYNCHRONIZE, // Windows client behavior
                    shareAccess: ShareAccess_Values.FILE_SHARE_DELETE,
                    createDisposition: CreateDisposition_Values.FILE_OPEN,
                    checker: (header, response) =>
                {
                    if (TestConfig.Platform == Platform.NonWindows)
                    {
                        BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, header.Status,
                                                        "If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and " +
                                                        "Treeconnect.MaximalAccess does not include DELETE or GENERIC_ALL, " +
                                                        "the server SHOULD fail the request with STATUS_ACCESS_DENIED");
                    }
                    else
                    {
                        BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_ACCESS_DENIED, header.Status,
                                                     "If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and " +
                                                     "Treeconnect.MaximalAccess does not include DELETE or GENERIC_ALL, " +
                                                     "the server SHOULD fail the request with STATUS_ACCESS_DENIED");
                    }
                });

                client.TreeDisconnect(treeId);
                client.LogOff();
            }
            catch (Exception e)
            {
                BaseTestSite.Assert.Fail("Case failed due to: {0}", e.Message);
            }
            finally
            {
                client.Disconnect();
            }
        }
コード例 #31
0
        public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ModelShareFlag shareFlag, ModelShareType shareType)
        {
            IPAddress ip;

            if (shareType == ModelShareType.STYPE_CLUSTER_SOFS)
            {
                server = testConfig.ScaleOutFileServerName;
                ip     = Dns.GetHostEntry(server).AddressList[0];

                if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK)
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithForceLevel2AndSOFS);
                }
                else
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithoutForceLevel2WithSOFS);
                }
            }
            else
            {
                server = testConfig.SutComputerName;
                ip     = testConfig.SutIPAddress;
                if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK)
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithForceLevel2WithoutSOFS);
                }
                else
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithoutForceLevel2OrSOFS);
                }
            }

            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.Smb2Client.OplockBreakNotificationReceived += new Action <Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnOplockBreakNotificationReceived);

            testClient.ConnectToServer(testConfig.UnderlyingTransport, server, ip, testConfig.ClientNic1IPAddress);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported));

            NEGOTIATE_Response?negotiateResponse = null;

            testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                checker: (header, response) =>
            {
                Site.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed", header.Command);

                negotiateResponse = response;
            });

            negotiatedDialect = negotiateResponse.Value.DialectRevision;

            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                server,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            testClient.TreeConnect(
                uncSharePath,
                out treeId,
                checker: (header, response) =>
            {
                Site.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed", header.Command);

                Site.Assert.AreEqual(
                    shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK,
                    response.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK),
                    "SHAREFLAG_FORCE_LEVELII_OPLOCK is{0}expected to be set",
                    shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK ? " " : " not ");

                if (ModelUtility.IsSmb3xFamily(negotiateResponse.Value.DialectRevision))
                {
                    Site.Assert.AreEqual(
                        shareType == ModelShareType.STYPE_CLUSTER_SOFS,
                        response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT),
                        "SHARE_CAP_SCALEOUT is{0}expected to be set",
                        shareType == ModelShareType.STYPE_CLUSTER_SOFS ? " " : " not ");
                }
            });
        }
コード例 #32
0
        private void SendCreateRequestWithSpecificAppInstanceversion(
            Smb2FunctionalClient client,
            Guid appInstanceId,
            ulong?appInstanceVersionHigh,
            ulong?appInstanceVersionLow,
            DialectRevision dialect,
            uint expectedCreateResponseStatus,
            out uint treeId,
            out FILEID fileId
            )
        {
            #region Client connects to Server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client connects to the file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress);
            client.Negotiate(Smb2Utility.GetDialects(dialect), TestConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            client.TreeConnect(uncSharePath, out treeId);

            Smb2CreateContextResponse[]  serverCreateContexts;
            Smb2CreateAppInstanceVersion appInstanceVersion = new Smb2CreateAppInstanceVersion();
            Smb2CreateContextRequest[]   clientCreateContexts;

            if (appInstanceVersionHigh.HasValue && appInstanceVersionLow.HasValue)
            {
                appInstanceVersion.AppInstanceVersionHigh = appInstanceVersionHigh.Value;
                appInstanceVersion.AppInstanceVersionLow  = appInstanceVersionLow.Value;
                clientCreateContexts =
                    new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    },
                    appInstanceVersion
                };
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with AppInstanceVersionHigh = {0}, AppInstanceVersionLow = {1}.", appInstanceVersion.AppInstanceVersionHigh, appInstanceVersion.AppInstanceVersionLow);
            }
            else
            {
                clientCreateContexts =
                    new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    }
                };
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request without AppInstanceVersion.");
            }

            client.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                clientCreateContexts,
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    expectedCreateResponseStatus,
                    header.Status,
                    (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS ?
                     "The open will be closed. Create should succeed. Actually server returns with {0}."
                        : "The open cannot be closed. Create should not succeed. Actually server returns with {0}."),
                    Smb2Status.GetStatusCode(header.Status));
            });

            #endregion
        }
コード例 #33
0
 private void ConnectToShare(Smb2FunctionalClient client, Guid clientGuid, string uncShareName, out uint treeId)
 {
     client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.FileServerNameContainingSharedVHD, TestConfig.FileServerIPContainingSharedVHD);
     client.Negotiate(
         TestConfig.RequestDialects,
         TestConfig.IsSMB1NegotiateEnabled,
         SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
         Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
         clientGuid);
     client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
     client.TreeConnect(uncShareName, out treeId);
 }
        /// <summary>
        /// Attempt to trigger LeaseBreakNotification from a separate client
        /// </summary>
        /// <param name="client">Client to trigger LeaseBreakNotification</param>
        /// <param name="requestDialect">Negotiate dialects</param>
        /// <param name="isDirectory">True value indicating to open a directory, false for a file</param>
        /// <param name="requestedLeaseState">LeaseState when open the directory or file</param>
        /// <param name="accessMask">AccessMask when open the directory or file</param>
        private void TriggerBreakFromClient(
            Smb2FunctionalClient client,
            DialectRevision[] requestDialect,
            bool isDirectory,
            LeaseStateValues requestedLeaseState,
            AccessMask accessMask)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Trigger a lease break notification by accessing same file/directory from a separate client with LeaseState {0} and AccessMask {1}", requestedLeaseState, accessMask);
            #region Negotiate
            status = client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: 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);
            #endregion

            #region SESSION_SETUP
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            uint treeId;
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            status = client.Create(
                treeId,
                isDirectory ? testDirectory : fileName,
                isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
                {
                    new Smb2CreateRequestLeaseV2
                    {
                        LeaseKey = Guid.NewGuid(),
                        LeaseState = requestedLeaseState
                    }
                },
                accessMask: accessMask);
            #endregion
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Finish triggering lease break notification");
        }
コード例 #35
0
        public void BVT_SMB2Basic_QueryAndSet_FileInfo()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Starts a client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT.");
            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId1;
            client1.TreeConnect(uncSharePath, out treeId1);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with desired access set to GENERIC_READ and GENERIC_WRITE to create a file.");
            Smb2CreateContextResponse[] serverCreateContexts;
            CREATE_Response? createResponse = null;
            string fileName = Guid.NewGuid().ToString() + ".txt";
            FILEID fileId1;
            client1.Create(
                treeId1,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts,
                accessMask: AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE,
                checker: (Packet_Header header, CREATE_Response response) =>
                    {
                        BaseTestSite.Assert.AreEqual(
                            Smb2Status.STATUS_SUCCESS,
                            header.Status,
                            "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                        BaseTestSite.Log.Add(LogEntryKind.TestStep,
                            "FileBasicInformation in CREATE response: \r\nCreationTime: {0}\r\nLastAccessTime:{1}\r\nLastWriteTime: {2}\r\nChangeTime: {3}\r\nFileAttributes: {4}",
                            Smb2Utility.ConvertToDateTimeUtc(response.CreationTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                            Smb2Utility.ConvertToDateTimeUtc(response.LastAccessTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                            Smb2Utility.ConvertToDateTimeUtc(response.LastWriteTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                            Smb2Utility.ConvertToDateTimeUtc(response.ChangeTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                            response.FileAttributes);
                        createResponse = response;
                    });

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends QUERY_INFO request to query file attributes.");
            byte[] outputBuffer;
            client1.QueryFileAttributes(
                treeId1,
                (byte)FileInformationClasses.FileBasicInformation,
                QUERY_INFO_Request_Flags_Values.SL_RESTART_SCAN,
                fileId1,
                new byte[0] { },
                out outputBuffer);

            FileBasicInformation fileBasicInfo = TypeMarshal.ToStruct<FileBasicInformation>(outputBuffer);
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "FileBasicInformation in QUERY_INFO response: \r\nCreationTime: {0}\r\nLastAccessTime:{1}\r\nLastWriteTime: {2}\r\nChangeTime: {3}\r\nFileAttributes: {4}",
                Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.CreationTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.LastAccessTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.LastWriteTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.ChangeTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"),
                fileBasicInfo.FileAttributes);

            BaseTestSite.Assert.AreEqual(createResponse.Value.CreationTime, fileBasicInfo.CreationTime, "CreationTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.LastAccessTime, fileBasicInfo.LastAccessTime, "LastAccessTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.LastWriteTime, fileBasicInfo.LastWriteTime, "LastWriteTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.ChangeTime, fileBasicInfo.ChangeTime, "ChangeTime received in QUERY_INFO response should be identical with that got in CREATE response");
            BaseTestSite.Assert.AreEqual(createResponse.Value.FileAttributes, fileBasicInfo.FileAttributes, "FileAttributes received in QUERY_INFO response should be identical with that got in CREATE response");

            FileBasicInformation fileBasicInfoToSet = fileBasicInfo;
            DateTime dateTimeToSet = DateTime.UtcNow;
            fileBasicInfoToSet.LastAccessTime = Smb2Utility.ConvertToFileTime(dateTimeToSet);

            byte[] inputBuffer;
            inputBuffer = TypeMarshal.ToBytes<FileBasicInformation>(fileBasicInfoToSet);
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client sends SetFileAttributes request to set LastAccessTime for the file to {0}", dateTimeToSet.ToString("MM/dd/yyy hh:mm:ss.ffffff"));
            client1.SetFileAttributes(
                treeId1,
                (byte)FileInformationClasses.FileBasicInformation,
                fileId1,
                inputBuffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends QUERY request to query file attributes.");
            client1.QueryFileAttributes(
                treeId1,
                (byte)FileInformationClasses.FileBasicInformation,
                QUERY_INFO_Request_Flags_Values.SL_RESTART_SCAN,
                fileId1,
                new byte[0] { },
                out outputBuffer);
            fileBasicInfo = TypeMarshal.ToStruct<FileBasicInformation>(outputBuffer);
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "LastAccessTime in QUERY_INFO response after SET_INFO {0}",
                Smb2Utility.ConvertToDateTimeUtc(fileBasicInfo.LastAccessTime).ToString("MM/dd/yyy hh:mm:ss.ffffff"));

            BaseTestSite.Assert.AreNotEqual(
                createResponse.Value.LastAccessTime,
                fileBasicInfo.LastAccessTime,
                "LastAccessTime (dwHighDateTime:{0}, dwLowDateTime:{1}) after SET_INFO should not be equal to the value (dwHighDateTime:{2}, dwLowDateTime:{3}) before SET_INFO",
                fileBasicInfo.LastAccessTime.dwHighDateTime, fileBasicInfo.LastAccessTime.dwLowDateTime, createResponse.Value.LastAccessTime.dwHighDateTime, createResponse.Value.LastAccessTime.dwLowDateTime);

            BaseTestSite.Assert.AreEqual(
                fileBasicInfoToSet.LastAccessTime,
                fileBasicInfo.LastAccessTime,
                "LastAccessTime (dwHighDateTime:{0}, dwLowDateTime:{1}) queried after SET_INFO should be equal to the desired value (dwHighDateTime:{2}, dwLowDateTime:{3})",
                fileBasicInfo.LastAccessTime.dwHighDateTime, fileBasicInfo.LastAccessTime.dwLowDateTime, fileBasicInfoToSet.LastAccessTime.dwHighDateTime, fileBasicInfoToSet.LastAccessTime.dwLowDateTime);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client1.Close(treeId1, fileId1);
            client1.TreeDisconnect(treeId1);
            client1.LogOff();
        }
コード例 #36
0
        /// <summary>
        /// Write content before failover
        /// </summary>
        /// <param name="fsType">FileServerType</param>
        /// <param name="server">File Server name.</param>
        /// <param name="serverAccessIp">File Server Access IP.</param>
        /// <param name="uncSharePath">The share path to write the file.</param>
        /// <param name="file">The file name for writing content.</param>
        /// <param name="content">The content to write.</param>
        /// <param name="clientGuid">Smb2 client Guid.</param>
        /// <param name="createGuid">The Guid for smb2 create request.</param>
        /// <returns></returns>
        protected bool WriteContentBeforeFailover(
            FileServerType fsType,
            string server,
            IPAddress serverAccessIp,
            string uncSharePath,
            string file,
            string content,
            Guid clientGuid,
            Guid createGuid)
        {
            uint status = 0;
            beforeFailover = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

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

            beforeFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, serverAccessIp);

            Capabilities_Values requestCapabilities = 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;
            status = beforeFailover.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: requestCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
                {
                    TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                });
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Negotiate failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            status = beforeFailover.SessionSetup(
                    TestConfig.DefaultSecurityPackage,
                    server,
                    TestConfig.AccountCredential,
                    TestConfig.UseServerGssToken);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "SessionSetup failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            uint treeId = 0;
            Share_Capabilities_Values shareCapabilities = Share_Capabilities_Values.NONE;
            status = DoUntilSucceed(
                () => beforeFailover.TreeConnect(uncSharePath, out treeId, (header, response) =>
                {
                    shareCapabilities = response.Capabilities;
                }),
                TestConfig.FailoverTimeout,
                "Retry TreeConnect until succeed within timeout span");

            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "TreeConnect failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            BaseTestSite.Assert.IsTrue(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY),
                "CA Share should have SHARE_CAP_CONTINUOUS_AVAILABILITY bit set for Capabilities in TreeConnect response.");

            if (fsType == FileServerType.ScaleOutFileServer)
            {
                BaseTestSite.Assert.IsTrue(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT),
                    "ScaleOut FS should have SHARE_CAP_SCALEOUT bit set for Capabilities in TreeConnect response.");
            }

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 with PERSISTENT flag set.");
            status = beforeFailover.Create(
                treeId,
                file,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleRequestV2
                    {
                         CreateGuid = createGuid,
                         Flags = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT,
                         Timeout = 3600000,
                    },
                });
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Create failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends WRITE request to write content to the file.");
            status = beforeFailover.Write(treeId, fileId, content);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Write content failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends FLUSH request.");
            status = beforeFailover.Flush(treeId, fileId);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Flush failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            return true;
        }
コード例 #37
0
ファイル: Replay.cs プロジェクト: pirenga/CVE-2020-1206-POC
        public void BVT_Replay_WriteWithInvalidChannelSequence()
        {
            ///1. mainChannelClient opens a file and write to it.
            ///2. mainChannelClient loses connection.
            ///3. ChannelSequence is set to 0x8000 which exceeds the max value.
            ///4. alternativeChannelClient opens the same file and try to write to it.
            ///5. Server should fail the write request with STATUS_FILE_NOT_AVAILABLE.

            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2);
            // According to TD, server must support signing when it supports multichannel.
            // 3.3.5.5   Receiving an SMB2 SESSION_SETUP Request
            // 4. If Connection.Dialect belongs to the SMB 3.x dialect family, IsMultiChannelCapable is TRUE, and the SMB2_SESSION_FLAG_BINDING bit is
            //    set in the Flags field of the request, the server MUST perform the following:
            //    If the SMB2_FLAGS_SIGNED bit is not set in the Flags field in the header, the server MUST fail the request with error STATUS_INVALID_PARAMETER.
            TestConfig.CheckSigning();
            #endregion

            Guid clientGuid = Guid.NewGuid();
            Capabilities_Values capabilityValue = Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL;
            channelSequence = 0;

            #region MainChannelClient Create a File
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Start a client from main channel by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE.");
            mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            mainChannelClient.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: capabilityValue,
                clientGuid: clientGuid,
                checker: ReplayNegotiateResponseChecker);
            mainChannelClient.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
            mainChannelClient.SessionChannelSequence = channelSequence;
            uint treeId;
            mainChannelClient.TreeConnect(sharePath, out treeId);
            FILEID fileId;
            Smb2CreateContextResponse[] createContextResponse;
            mainChannelClient.Create(treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse,
                                     RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH,
                                     new Smb2CreateContextRequest[]
            {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = Guid.NewGuid()
                }
            });
            CheckCreateContextResponses(createContextResponse, new DefaultDurableHandleV2ResponseChecker(BaseTestSite, 0, uint.MaxValue));
            #endregion

            #region alternativeChannelClient Opens the Previously Created File
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client from alternative channel by sending NEGOTIATE request.");
            alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutAlternativeIPAddress);
            alternativeChannelClient.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: capabilityValue,
                clientGuid: clientGuid,
                checker: ReplayNegotiateResponseChecker);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "The alternative client sends SESSION_SETUP request binding the previous session created by the main channel client.");
            alternativeChannelClient.AlternativeChannelSessionSetup(mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
            alternativeChannelClient.SessionChannelSequence = channelSequence;
            #endregion

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The main channel client sends WRITE request to write content to file.");
            mainChannelClient.Write(treeId, fileId, " ");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the main channel client by sending DISCONNECT request.");
            mainChannelClient.Disconnect();

            //Network Disconnection Increase the Channel Sequence
            //Server MUST fail SMB2 WRITE, SET_INFO, and IOCTL requests with STATUS_FILE_NOT_AVAILABLE
            //if the difference between the ChannelSequence in the header and Open.ChannelSequence is greater than 0x7FFF
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Set the channel sequence of the alternative channel client to an invalid value.");
            alternativeChannelClient.SessionChannelSequence = 0x8000;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "The alternative client sends WRITE request to write content to the file created by the main channel client.");
            alternativeChannelClient.Write(treeId,
                                           fileId,
                                           " ",
                                           checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_FILE_NOT_AVAILABLE,
                    header.Status,
                    "Server MUST fail the {0} request with STATUS_FILE_NOT_AVAILABLE if the difference between the ChannelSequence in the header and Open.ChannelSequence is greater than 0x7FFF. " +
                    "Actually server returns {1}.",
                    header.Command,
                    Smb2Status.GetStatusCode(header.Status));
            },
                                           isReplay: true);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the alternative channel client by sending TREE_DISCONNECT and LOG_OFF requests.");
            alternativeChannelClient.TreeDisconnect(treeId);
            alternativeChannelClient.LogOff();
        }
コード例 #38
0
        public void TreeMgmt_SMB311_TREE_CONNECT_EXTENSION_PRESENT()
        {
            #region Check Applicability
            TestConfig.CheckPlatform(Platform.WindowsServer2019);
            TestConfig.CheckDialect(DialectRevision.Smb311);
            #endregion

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

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: CONNECT; NEGOTIATE; SESSION_SETUP");
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            //Use domain credential to do session setup (e.g. contoso.com\administrator)
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            string infraSharePath = string.Format(@"\\{0}\{1}", TestConfig.ClusteredInfrastructureFileServerName, TestConfig.InfrastructureRootShare);
            uint   treeId;

            string domainName          = TestConfig.DomainName;
            string domainAdmin         = TestConfig.UserName;
            string domainAdminPassword = TestConfig.UserPassword;
            string anotherUserName     = TestConfig.NonAdminUserName;

            _WindowsIdentity identity = _WindowsIdentity.GetFromDomain(domainName, domainAdmin, domainAdminPassword, anotherUserName);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request with extension context and expects success");
            //Use another domain account(e.g. contoso\nonadmin) as an idenity passed in tree connect extension
            client.TreeConnect(
                infraSharePath,
                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_IDENTITY_REMOTING),
                    "The share should support identity remoting, actually server returns {0}.", response.ShareFlags.ToString());
            },
                TreeConnect_Flags.SMB2_SHAREFLAG_EXTENSION_PRESENT,
                identity);

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client impersonates another log in user to send CREATE request and expects success.");
            client.Create(
                treeId,
                GetTestFileName(infraSharePath),
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                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.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client.Close(treeId, fileId);

            client.TreeDisconnect(treeId);
            client.LogOff();
        }
コード例 #39
0
        /// <summary>
        /// Read content after failover
        /// </summary>
        /// <param name="server">File server name.</param>
        /// <param name="serverAccessIp">File server access IP.</param>
        /// <param name="uncSharePath">The share path to read the file.</param>
        /// <param name="file">The file name for reading content.</param>
        /// <param name="content">The content to read.</param>
        /// <param name="clientGuid">Smb2 client Guid.</param>
        /// <param name="createGuid">The Guid for smb2 create request.</param>
        /// <returns></returns>
        protected bool ReadContentAfterFailover(string server,
            IPAddress serverAccessIp,
            string uncSharePath,
            string file,
            string content,
            Guid clientGuid,
            Guid createGuid)
        {
            uint status;

            BaseTestSite.Assert.AreNotEqual(
                null,
                serverAccessIp,
                "Access IP to the file server should not be empty");
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Got IP {0} to access the file server", serverAccessIp.ToString());

            Smb2FunctionalClient afterFailover = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);
            DoUntilSucceed(() => afterFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, serverAccessIp), TestConfig.FailoverTimeout,
                "Retry to connect to server until succeed within timeout span");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends NEGOTIATE request with the same clientguid of previous client.");
            status = afterFailover.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: 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,
                clientGuid: clientGuid);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Negotiate failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends SESSION_SETUP request with the same SESSION_ID of previous client.");
            status = afterFailover.ReconnectSessionSetup(
                        beforeFailover,
                        TestConfig.DefaultSecurityPackage,
                        server,
                        TestConfig.AccountCredential,
                        TestConfig.UseServerGssToken);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "ReconnectSessionSetup failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            // Retry TreeConnect because network path may not be available immediately
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client retries TREE_CONNECT to {0} until succeed or timeout in {1} because network path may not be available immediately.", uncSharePath, TestConfig.FailoverTimeout);
            uint treeId = 0;
            status = afterFailover.TreeConnect(uncSharePath, out treeId, (header, response) => { });
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "TreeConnect failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            // Retry Create because file may not be available immediately
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client retries to send CREATE request with SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 context with PERSISTENT flag set until succeed or timeout in {0}.", TestConfig.FailoverTimeout);
            FILEID fileId = new FILEID();
            Smb2CreateContextResponse[] serverCreateContexts;
            status = DoUntilSucceed(
                () => afterFailover.Create(
                        treeId,
                        file,
                        CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        out fileId,
                        out serverCreateContexts,
                        RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                        new Smb2CreateContextRequest[] {
                            new Smb2CreateDurableHandleReconnectV2
                            {
                                FileId = new FILEID { Persistent = fileId.Persistent },
                                CreateGuid = createGuid,
                                Flags = CREATE_DURABLE_HANDLE_RECONNECT_V2_Flags.DHANDLE_FLAG_PERSISTENT
                            },
                        },
                        checker: (header, response) => { }),
                TestConfig.FailoverTimeout,
                "Retry Create until succeed within timeout span");
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Create failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            string readContent;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends READ request to read content.");
            status = afterFailover.Read(treeId, fileId, 0, (uint)content.Length, out readContent);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Read failed with {0}.", Smb2Status.GetStatusCode(status));
                return false;
            }

            BaseTestSite.Assert.IsTrue(
                content.Equals(readContent),
                "Content read after failover should be identical to that written before failover");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            status = afterFailover.Close(treeId, fileId);
            status = afterFailover.TreeDisconnect(treeId);
            status = afterFailover.LogOff();
            afterFailover.Disconnect();
            return true;
        }
コード例 #40
0
        public void BVT_MultiCredit_OneRequestWithMultiCredit()
        {
            TestConfig.CheckDialect(DialectRevision.Smb21);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LARGE_MTU);

            Guid clientGuid = Guid.NewGuid();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: 1. NEGOTIATE; 2. SESSION_SETUP; 3. TREE_CONNECT");
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            client.ConnectToServerOverTCP(TestConfig.SutIPAddress);
            Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_LARGE_MTU;

            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities);
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId;

            client.TreeConnect(uncSharePath, out treeId);

            int    bufferSize = (int)client.MaxBufferSize;
            FILEID fileId;

            Smb2CreateContextResponse[] serverCreateContexts;
            ushort grantedCredit = 0;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with {0} credits", client.Credits);
            client.Create(
                treeId,
                GetTestFileName(uncSharePath),
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));

                BaseTestSite.Log.Add(LogEntryKind.Debug,
                                     "The MaxBufferSize of the server is {0}.",
                                     client.MaxBufferSize);
                BaseTestSite.Log.Add(LogEntryKind.Debug,
                                     "Server has granted {0} credits to the client.",
                                     client.Credits);

                // Make sure client hold enough credits for test
                ushort maxBufferSizeInCredit = (ushort)((client.MaxBufferSize - 1) / 65536 + 1);
                if (client.Credits < maxBufferSizeInCredit)
                {
                    if (client.Credits < 2)
                    {
                        BaseTestSite.Assert.Inconclusive(
                            "This test case is not applicable when the server only grants {0} credits",
                            client.Credits);
                    }
                    // Test max buffer according to granted credits.
                    bufferSize = (client.Credits - 1) * 65536;
                }

                grantedCredit = header.CreditRequestResponse;
            });

            contentWrite = Smb2Utility.CreateRandomStringInByte(bufferSize);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client attempts to write {0} bytes content to file when server grants {1} credits",
                client.MaxBufferSize, client.Credits);

            client.Write(
                treeId,
                fileId,
                contentWrite,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));

                grantedCredit = header.CreditRequestResponse;
            });

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client attempts to read {0} bytes content from file when server grants {1} credit",
                bufferSize, client.Credits);
            client.Read(treeId, fileId, 0, (uint)contentWrite.Length, out contentRead);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: 1. CLOSE; 2. TREE_DISCONNECT; 3. LOG_OFF; 4. DISCONNECT");
            client.Close(treeId, fileId);
            client.TreeDisconnect(treeId);
            client.LogOff();
            client.Disconnect();
        }
コード例 #41
0
        public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            testClient.Smb2Client.Disconnected += new Action(OnServerDisconnected);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported));

            //Set capabilities according to isClientSupportsEncryption
            Capabilities_Values commonCapability = 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;
            Capabilities_Values encryptionCapability = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? (commonCapability | Capabilities_Values.GLOBAL_CAP_ENCRYPTION) : commonCapability;

            uint status;
            DialectRevision selectedDialect;
            NEGOTIATE_Response? negotiateResponse = null;
            status = testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: encryptionCapability,
                checker: (header, response) =>
                {
                    Site.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "{0} should succeed", header.Command);

                    negotiateResponse = response;
                });

            selectedDialect = negotiateResponse.Value.DialectRevision;
            if (Smb2Utility.IsSmb3xFamily(selectedDialect) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption)
            {
                /// TD section 3.3.5.4
                /// SMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect belongs to the SMB 3.x dialect, the server supports encryption,
                /// and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request
                Site.Assert.IsTrue(
                            negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION),
                            "SMB2_GLOBAL_CAP_ENCRYPTION should be set in the negotiate response.");
            }
            else
            {
                Site.Assert.IsFalse(
                            negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION),
                            "SMB2_GLOBAL_CAP_ENCRYPTION should not be set in the negotiate response.");
            }
        }
コード例 #42
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();
        }
コード例 #43
0
        public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ModelShareFlag shareFlag, ModelShareType shareType)
        {
            IPAddress ip;
            if (shareType == ModelShareType.STYPE_CLUSTER_SOFS)
            {
                server = testConfig.ScaleOutFileServerName;
                ip = Dns.GetHostEntry(server).AddressList[0];

                if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK)
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithForceLevel2AndSOFS);
                }
                else
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithoutForceLevel2WithSOFS);
                }
            }
            else
            {
                server = testConfig.SutComputerName;
                ip = testConfig.SutIPAddress;
                if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK)
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithForceLevel2WithoutSOFS);
                }
                else
                {
                    uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithoutForceLevel2OrSOFS);
                }
            }

            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.Smb2Client.OplockBreakNotificationReceived += new Action<Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnOplockBreakNotificationReceived);

            testClient.ConnectToServer(testConfig.UnderlyingTransport, server, ip, testConfig.ClientNic1IPAddress);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported));

            NEGOTIATE_Response? negotiateResponse = null;
            testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                checker: (header, response) =>
                    {
                        Site.Assert.AreEqual(
                            Smb2Status.STATUS_SUCCESS,
                            header.Status,
                            "{0} should succeed", header.Command);

                        negotiateResponse = response;
                    });

            negotiatedDialect = negotiateResponse.Value.DialectRevision;

            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                server,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            testClient.TreeConnect(
                uncSharePath,
                out treeId,
                checker: (header, response) =>
                {
                    Site.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "{0} should succeed", header.Command);

                    Site.Assert.AreEqual(
                        shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK,
                        response.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK),
                        "SHAREFLAG_FORCE_LEVELII_OPLOCK is{0}expected to be set",
                        shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK ? " " : " not ");

                    if (ModelUtility.IsSmb3xFamily(negotiateResponse.Value.DialectRevision))
                    {
                        Site.Assert.AreEqual(
                            shareType == ModelShareType.STYPE_CLUSTER_SOFS,
                            response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT),
                            "SHARE_CAP_SCALEOUT is{0}expected to be set",
                            shareType == ModelShareType.STYPE_CLUSTER_SOFS ? " " : " not ");
                    }
                });
        }
コード例 #44
0
        protected bool AccessShare(AccountCredential user, string sharePath)
        {
            bool accessSucceed          = true;
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            try
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message.");
                client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", user.AccountName, user.DomainName);
                client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, user, false);

                uint treeId;
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", sharePath);
                client.TreeConnect(sharePath, out treeId, checker: (header, response) =>
                {
                    if (header.Status == Smb2Status.STATUS_SUCCESS)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Access succeeded in TREE_CONNECT phase.");
                        accessSucceed = true;
                    }
                    else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Access denied in TREE_CONNECT phase.");
                        accessSucceed = false;
                    }
                    else
                    {
                        BaseTestSite.Assert.Fail("Unexpected error code in TREE_CONNECT response: {0}", Smb2Status.GetStatusCode(header.Status));
                    }
                });

                if (!accessSucceed)
                {
                    client.LogOff();
                    return(false);
                }

                FILEID fileId;
                Smb2CreateContextResponse[] createContexResponse;

                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends CREATE request.");
                uint status = client.Create(
                    treeId,
                    null,
                    CreateOptions_Values.FILE_DIRECTORY_FILE,
                    out fileId,
                    out createContexResponse,
                    accessMask: AccessMask.FILE_READ_DATA | AccessMask.FILE_READ_ATTRIBUTES,
                    createDisposition: CreateDisposition_Values.FILE_OPEN,
                    checker: (header, response) =>
                {
                    if (header.Status == Smb2Status.STATUS_SUCCESS)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Access succeeded in CREATE phase.");
                        accessSucceed = true;
                    }
                    else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Access denied in CREATE phase.");
                        accessSucceed = false;
                    }
                    else
                    {
                        BaseTestSite.Assert.Fail("Unexpected error code in CREATE response: {0}", Smb2Status.GetStatusCode(header.Status));
                    }
                });

                if (status == Smb2Status.STATUS_SUCCESS)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF.");
                    client.Close(treeId, fileId);
                }
                client.TreeDisconnect(treeId);
                client.LogOff();
            }
            finally
            {
                client.Disconnect();
            }
            return(accessSucceed);
        }
コード例 #45
0
        /// <summary>
        /// Determine if a share has shi*_type set to STYPE_CLUSTER_SOFS
        /// </summary>
        /// <param name="server">Server of the share</param>
        /// <param name="sharePath">Path of the share</param>
        /// <returns>Return true if share has shi*_type set to STYPE_CLUSTER_SOFS, otherwise return false</returns>
        private bool ShareContainsSofs(string server, string sharePath)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            client.ConnectToServerOverTCP(SWNTestUtility.GetCurrentAccessIP(server));

            client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);

            client.SessionSetup(TestConfig.DefaultSecurityPackage, server, TestConfig.AccountCredential, false);

            uint treeId;
            bool ret = false;
            client.TreeConnect(sharePath, out treeId,
                (header, response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "{0} should be successful.", header.Command);

                    ret = response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT);
                });

            client.TreeDisconnect(treeId);

            client.LogOff();

            client.Disconnect();

            return ret;
        }
コード例 #46
0
        private void DirecotryLeasing(
            DialectRevision[] requestDialect,
            DialectRevision expectedDialect,
            LeaseStateValues leaseState,
            LeaseBreakAckType leaseBreakAckType = LeaseBreakAckType.None)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                @"Start to create a directory on share \\{0}\{1} with lease state {2}",
                TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState);

            string testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            #region Negotiate
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            Capabilities_Values capabilities = 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;
            status = client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: capabilities,
                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(expectedDialect, response);
                if (expectedDialect >= DialectRevision.Smb30)
                {
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response);
                }
            });
            #endregion

            #region SESSION_SETUP
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            uint   treeId;
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client sends CREATE request for the directory with the LeaseState set to {0} in SMB2_CREATE_REQUEST_LEASE_V2.", leaseState);
            status = client.Create(
                treeId,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
            {
                new Smb2CreateRequestLeaseV2
                {
                    LeaseKey   = Guid.NewGuid(),
                    LeaseState = leaseState
                }
            },
                checker: (Packet_Header header, CREATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                if (expectedDialect == DialectRevision.Smb2002 || expectedDialect == DialectRevision.Smb21)
                {
                    BaseTestSite.Assert.AreEqual(
                        OplockLevel_Values.OPLOCK_LEVEL_NONE,
                        response.OplockLevel,
                        "The expected oplock level is OPLOCK_LEVEL_NONE.");
                }
            });

            #endregion

            if (expectedDialect >= DialectRevision.Smb30)
            {
                // Break the lease with creating another file in the directory
                sutProtocolController.CreateFile(Path.Combine(Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare), testDirectory), CurrentTestCaseName, string.Empty);

                // Wait until LEASE_BREAK_Notification is received
                BaseTestSite.Assert.IsTrue(
                    // Wait 5 seconds for notification arrival
                    notificationReceived.WaitOne(SMB2TestConfig.WAIT_TIMEOUT_IN_MILLISECONDS),
                    "LeaseBreakNotification should be raised.");

                if (receivedLeaseBreakNotify.Flags == LEASE_BREAK_Notification_Packet_Flags_Values.SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED)
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Server requires an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");

                    #region LEASE_BREAK_ACK
                    switch (leaseBreakAckType)
                    {
                    case LeaseBreakAckType.None:
                        status = client.LeaseBreakAcknowledgment(treeId, receivedLeaseBreakNotify.LeaseKey, receivedLeaseBreakNotify.NewLeaseState);
                        break;

                    case LeaseBreakAckType.InvalidLeaseState:
                        LeaseStateValues newLeaseState = LeaseStateValues.SMB2_LEASE_WRITE_CACHING;
                        BaseTestSite.Log.Add(
                            LogEntryKind.Comment,
                            "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseState {0} on this LEASE_BREAK_NOTIFY", newLeaseState);
                        status = client.LeaseBreakAcknowledgment(
                            treeId,
                            receivedLeaseBreakNotify.LeaseKey,
                            newLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK with invalid LeaseState is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_REQUEST_NOT_ACCEPTED,
                                header.Status,
                                RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Id,
                                RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Description);
                        });
                        break;

                    case LeaseBreakAckType.InvalidLeaseKey:
                        Guid invalidLeaseKey = Guid.NewGuid();
                        BaseTestSite.Log.Add(
                            LogEntryKind.Debug,
                            "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseKey {0} on this LEASE_BREAK_NOTIFY", invalidLeaseKey);
                        status = client.LeaseBreakAcknowledgment(
                            treeId,
                            invalidLeaseKey,
                            receivedLeaseBreakNotify.NewLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK with invalid LeaseKey is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                                header.Status,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                        });
                        break;

                    case LeaseBreakAckType.InvalidClientGuid:
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Initialize a new different client to attempts to send LEASE_BREAK_ACK");
                        Smb2FunctionalClient newClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

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

                        #region Negotiate
                        status = newClient.Negotiate(
                            requestDialect,
                            TestConfig.IsSMB1NegotiateEnabled,
                            capabilityValue: 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);
                        #endregion

                        #region SESSION_SETUP
                        status = newClient.SessionSetup(
                            TestConfig.DefaultSecurityPackage,
                            TestConfig.SutComputerName,
                            TestConfig.AccountCredential,
                            TestConfig.UseServerGssToken);
                        #endregion

                        #region TREE_CONNECT to share
                        uint newTreeId;
                        status = newClient.TreeConnect(uncSharePath, out newTreeId);
                        #endregion

                        status = newClient.LeaseBreakAcknowledgment(
                            newTreeId,
                            receivedLeaseBreakNotify.LeaseKey,
                            receivedLeaseBreakNotify.NewLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK is not expected to SUCCESS when the open is closed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                                header.Status,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                        });

                        status = newClient.TreeDisconnect(newTreeId);

                        status = newClient.LogOff();

                        BaseTestSite.Log.Add(
                            LogEntryKind.Comment,
                            "Initialize a new different client to attempts to send LEASE_BREAK_ACK");
                        break;

                    default:
                        throw new InvalidOperationException("Unexpected LeaseBreakAckType " + leaseBreakAckType);
                    }

                    #endregion
                }
                else
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Server does not require an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");
                }
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF");
            #region TREE_DISCONNECT
            status = client.TreeDisconnect(treeId);
            #endregion

            #region LOGOFF
            status = client.LogOff();
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                @"Complete creating a directory on share \\{0}\{1} with lease state {2}",
                TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState);
        }
コード例 #47
0
        private void CreateFile(string uncShare, string fileName, int lengthInByte)
        {
            Site.Log.Add(
                LogEntryKind.Debug,
                "Create file {0} in share {1}", fileName, uncShare);

            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

            client.CreditGoal = 32;

            client.Negotiate(
                new DialectRevision[] { ModelUtility.GetDialectRevision(config.MaxSmbVersionSupported) },
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_LARGE_MTU);

            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            uint tId;
            client.TreeConnect(
                uncShare,
                out tId);

            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fId;
            client.Create(
                tId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fId,
                out serverCreateContexts);

            string content;
            if (isMultiCreditSupportedOnConnection)
            {
                content = Smb2Utility.CreateRandomStringInByte(lengthInByte);
                client.Write(tId, fId, content);
            }
            else
            {
                // Write several times if server does not support multi credit
                int writeTimes = lengthInByte / (64 * 1024);
                int rest = lengthInByte % (64 * 1024);
                ulong offset = 0;

                for (int time = 0; time < writeTimes; time++)
                {
                    content = Smb2Utility.CreateRandomString(64);
                    client.Write(tId, fId, content, offset);
                    offset += 64 * 1024;
                }

                if (rest != 0)
                {
                    content = Smb2Utility.CreateRandomStringInByte(rest);
                    client.Write(tId, fId, content, offset);
                }
            }

            client.Close(tId, fId);

            client.TreeDisconnect(tId);

            client.LogOff();

            client.Disconnect();

            Site.Log.Add(
                LogEntryKind.Debug,
                "Create file {0} in share {1}", fileName, uncShare);
        }
コード例 #48
0
        public void BVT_OpLockBreak()
        {
            #region Add Event Handler
            client1.Smb2Client.OplockBreakNotificationReceived += new Action <Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnOpLockBreakNotificationReceived);
            #endregion

            #region Client1 Open a File with BatchOpLock
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the first client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT.");
            client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            client1.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
            client1.TreeConnect(sharePath, out treeId);

            Smb2CreateContextResponse[] createContextResponse;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends CREATE request with BatchOplock.");
            client1.Create(treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse, RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH,
                           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));

                if (response.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_NONE)
                {
                    BaseTestSite.Assert.Inconclusive("OpLock request not succeeded.");
                }
            });
            #endregion

            #region Oplock Break
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the second client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT.");
            client2.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            client2.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
            uint client2TreeId;
            client2.TreeConnect(sharePath, out client2TreeId);

            FILEID client2FileId;
            ulong  createRequestId;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The second client sends CREATE request on the same file with the first client.");
            client2.CreateRequest(client2TreeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out createRequestId);

            BaseTestSite.Assert.IsTrue(OpLockNotificationReceived.WaitOne(TestConfig.WaitTimeoutInMilliseconds),
                                       "The expected OPLOCK_BREAK_NOTIFY should be received within {0} milliseconds", TestConfig.WaitTimeoutInMilliseconds);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends OPLOCK_ACKNOWLEDGEMENT request after received OPLOCK_BREAK_NOTIFICATION response from server.");
            OplockBreakAcknowledgment(client1);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The second client sends CREATE response");
            client2.CreateResponse(createRequestId, out client2FileId, out createContextResponse);
            #endregion

            #region Tear Down Clients
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the first client by sending CLOSE, TREE_DISCONNECT, and LOG_OFF.");
            client1.Close(treeId, fileId);
            client1.TreeDisconnect(treeId);
            client1.LogOff();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending CLOSE, TREE_DISCONNECT, and LOG_OFF.");
            client2.Close(client2TreeId, client2FileId);
            client2.TreeDisconnect(client2TreeId);
            client2.LogOff();
            #endregion
        }
コード例 #49
0
        /// <summary>
        /// Verify behavior of redirect to owner specified in MS-SMB2 section 3.3.5.7
        /// </summary>
        /// <param name="sofsHostedNode">ScaleOutFS hosted node</param>
        /// <param name="nonSofsHostedNode">Non ScaleOutFS hosted node</param>
        /// <returns>Redirect to owner is tested or not</returns>
        private bool TestRedirectToOwner(string sofsHostedNode, string nonSofsHostedNode)
        {
            bool isRedirectToOwnerTested = false;

            #region Get IP address list from ScaleOutFS
            string      server       = TestConfig.ClusteredScaleOutFileServerName;
            IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList;
            #endregion

            #region Get IP address from nonSofsHostedNode
            IPAddress   currentAccessIpAddr       = null;
            IPAddress[] accessIpListNonSoftHosted = Dns.GetHostEntry(nonSofsHostedNode).AddressList;
            for (int i = 0; i < accessIpList.Length; i++)
            {
                for (int j = 0; j < accessIpListNonSoftHosted.Length; j++)
                {
                    // Make sure to get IP address from nonSofsHostedNode
                    if (accessIpList[i].Address.Equals(accessIpListNonSoftHosted[j].Address))
                    {
                        currentAccessIpAddr = accessIpList[i];
                        break;
                    }
                }
            }
            BaseTestSite.Assert.IsNotNull(
                currentAccessIpAddr,
                "currentAccessIpAddr should be set as IP of nonSofsHostedNode {0}", nonSofsHostedNode);
            #endregion

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP");
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, server, currentAccessIpAddr);
            client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(TestConfig.DefaultSecurityPackage, server, TestConfig.AccountCredential, false);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request with flag SMB2_SHAREFLAG_REDIRECT_TO_OWNER.");
            string uncSharePath = Smb2Utility.GetUncPath(server, testConfig.CAShareName);
            uint   treeId;
            Share_Capabilities_Values shareCap = Share_Capabilities_Values.NONE;
            uint status = client.TreeConnect(
                uncSharePath,
                out treeId,
                (header, response) =>
            {
                if (header.Status == Smb2Status.STATUS_SUCCESS)
                {
                    shareCap = response.Capabilities;
                }
            },
                TreeConnect_Flags.SMB2_SHAREFLAG_REDIRECT_TO_OWNER);

            if (status != Smb2Status.STATUS_SUCCESS &&
                client.Smb2Client.Error != null)
            {
                ERROR_Response_packet error = client.Smb2Client.Error.PayLoad;
                if (error.ErrorContextCount > 0)
                {
                    for (int i = 0; i < error.ErrorContextCount; i++)
                    {
                        Error_Context ctx = error.ErrorContextErrorData[i];
                        if (ctx.ErrorId == Error_Id.ERROR_ID_SHARE_REDIRECT)
                        {
                            Share_Capabilities_Values shareCaps = GetShareCapabilities(sofsHostedNode, uncSharePath, TreeConnect_Flags.SMB2_SHAREFLAG_REDIRECT_TO_OWNER);
                            if (!shareCaps.HasFlag(Share_Capabilities_Values.SHARE_CAP_REDIRECT_TO_OWNER))
                            {
                                BaseTestSite.Assert.Inconclusive(
                                    "The share {0} does not have the capability SHARE_CAP_REDIRECT_TO_OWNER",
                                    Smb2Utility.GetUncPath(TestConfig.ClusteredScaleOutFileServerName, testConfig.CAShareName)
                                    );
                            }

                            BaseTestSite.Assert.AreEqual(
                                Smb2Status.STATUS_BAD_NETWORK_NAME,
                                status,
                                "If TreeConnect.Share.Type includes STYPE_CLUSTER_SOFS," +
                                "Connection.Dialect is \"3.1.1\" and" +
                                "the SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER bit is set" +
                                "in the Flags field of the SMB2 TREE_CONNECT request," +
                                "the server MUST query the underlying object store in an implementation-specific manner " +
                                "to determine whether the share is hosted on this node." +
                                "If not, the server MUST return error data as specified in section 2.2.2" +
                                "with ErrorData set to SMB2 ERROR Context response formatted as ErrorId" +
                                "set to SMB2_ERROR_ID_SHARE_REDIRECT, and ErrorContextData set to the Share Redirect error context data" +
                                "as specified in section 2.2.2.2.2 with IPAddrMoveList set to" +
                                "the list of IP addresses obtained in an implementation-specific manner." +
                                "Actually server returns {0}.", Smb2Status.GetStatusCode(status)
                                );
                            verifyErrorContext(ctx, uncSharePath, sofsHostedNode);
                            isRedirectToOwnerTested = true;
                        }
                    }
                }
            }

            if (status == Smb2Status.STATUS_SUCCESS)
            {
                if (!shareCap.HasFlag(Share_Capabilities_Values.SHARE_CAP_REDIRECT_TO_OWNER))
                {
                    BaseTestSite.Assert.Inconclusive(
                        "The share {0} does not have the capability SHARE_CAP_REDIRECT_TO_OWNER",
                        Smb2Utility.GetUncPath(TestConfig.ClusteredScaleOutFileServerName, testConfig.CAShareName)
                        );
                }
                client.TreeDisconnect(treeId);
            }
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: LOG_OFF; DISCONNECT.");
            client.LogOff();
            client.Disconnect();
            return(isRedirectToOwnerTested);
        }
コード例 #50
0
        private void AppInstanceIdTest(
            bool sameAppInstanceId,
            bool containCreateDurableContext,
            uint expectedCreateResponseStatus,
            uint expectedInitialOpenStatusAfterReopen)
        {
            string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);

            #region Client 1 Connect to Server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the first client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            clientForInitialOpen = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientForInitialOpen.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress);
            clientForInitialOpen.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            clientForInitialOpen.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeIdForInitialOpen;
            clientForInitialOpen.TreeConnect(sharePath, out treeIdForInitialOpen);

            Guid   appInstanceId = Guid.NewGuid();
            FILEID fileIdForInitialOpen;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "The first client sends CREATE request for exclusive open with SMB2_CREATE_APP_INSTANCE_ID create context.");
            Smb2CreateContextResponse[] serverCreateContexts;
            Smb2CreateContextRequest[]  createContextsRequestForInitialOpen = null;
            if (containCreateDurableContext)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is also included in the CREATE request.");
                createContextsRequestForInitialOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleRequestV2
                    {
                        CreateGuid = Guid.NewGuid()
                    },
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    }
                };
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is not included in the CREATE request.");
                createContextsRequestForInitialOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    }
                };
            }

            clientForInitialOpen.Create(
                treeIdForInitialOpen,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdForInitialOpen,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                createContextsRequestForInitialOpen,
                shareAccess: ShareAccess_Values.NONE);
            #endregion

            #region Client 2 Connect to Server

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the second client by sending the following requests: NEGOTIATE; SESSION-SETUP; TREE_CONNECT");
            clientForReOpen = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientForReOpen.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic2IPAddress);
            clientForReOpen.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            clientForReOpen.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeIdForReOpen;
            clientForReOpen.TreeConnect(sharePath, out treeIdForReOpen);

            FILEID fileIdForReOpen;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "The second client sends CREATE request for exclusive open with the {0} SMB2_CREATE_APP_INSTANCE_ID of the first client.", sameAppInstanceId ? "same" : "different");
            Smb2CreateContextRequest[] createContextsRequestForReOpen = null;
            if (containCreateDurableContext)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is also included in the CREATE request.");
                createContextsRequestForReOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleRequestV2
                    {
                        CreateGuid = Guid.NewGuid()
                    },
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = sameAppInstanceId ? appInstanceId : Guid.NewGuid()
                    }
                };
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is not included in the CREATE request.");
                createContextsRequestForReOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = sameAppInstanceId ? appInstanceId : Guid.NewGuid()
                    }
                };
            }

            clientForReOpen.Create(
                treeIdForReOpen,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdForReOpen,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                createContextsRequestForReOpen,
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    expectedCreateResponseStatus,
                    header.Status,
                    (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS ?
                     "The open will be closed. Create should succeed. Actually server returns with {0}."
                        : "The open cannot be closed. Create should not succeed. Actually server returns with {0}."),
                    Smb2Status.GetStatusCode(header.Status));
            });

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends another WRITE request.");

            clientForInitialOpen.Write(treeIdForInitialOpen, fileIdForInitialOpen, content,
                                       checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    expectedInitialOpenStatusAfterReopen,
                    header.Status,
                    (expectedInitialOpenStatusAfterReopen == Smb2Status.STATUS_SUCCESS ?
                     "The initial open is not closed. Write should succeed. Actually server returns with {0}."
                        : "The initial open is closed. Write should not succeed. Actually server returns with {0}."),
                    Smb2Status.GetStatusCode(header.Status));

                if (sameAppInstanceId && expectedCreateResponseStatus != Smb2Status.STATUS_SHARING_VIOLATION)
                {
                    BaseTestSite.CaptureRequirementIfAreEqual(
                        Smb2Status.STATUS_FILE_CLOSED,
                        header.Status,
                        RequirementCategory.STATUS_FILE_CLOSED.Id,
                        RequirementCategory.STATUS_FILE_CLOSED.Description);
                }
            });


            if (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF; DISCONNECT");
                clientForReOpen.Close(treeIdForReOpen, fileIdForReOpen);
            }
            clientForReOpen.TreeDisconnect(treeIdForReOpen);
            clientForReOpen.LogOff();
            clientForReOpen.Disconnect();

            if (expectedInitialOpenStatusAfterReopen == Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the first client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
                clientForInitialOpen.Close(treeIdForInitialOpen, fileIdForInitialOpen);
            }

            clientForInitialOpen.TreeDisconnect(treeIdForInitialOpen);
            clientForInitialOpen.LogOff();
            #endregion
        }
        /// <summary>
        /// Verify if server grant lease state as expected
        /// </summary>
        /// <param name="requestedLeaseState">Requested lease state from client</param>
        /// <param name="expectedGrantedLeaseState">Expected lease state that server granted</param>
        private void VerifyGrantedLeaseState(LeaseStateValues requestedLeaseState, LeaseStateValues expectedGrantedLeaseState)
        {
            Guid clientGuid = Guid.NewGuid();
            string testDirectory = "DirectoryLeasing_GrantedLeaseState_" + clientGuid.ToString();

            #region Connect to share
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to share {0}.", uncSharePath);

            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            #region Negotiate
            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;
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                clientCapabilities,
                clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "NEGOTIATE should succeed.");

                    TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response);
                });

            #endregion

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

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "SessionSetup should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion

            #region TreeConnect
            uint treeId;
            status = client.TreeConnect(uncSharePath, out treeId);

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "TreeConnect should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion
            #endregion

            #region CREATE open to directory with lease
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "CREATE open to directory with lease.");
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId;
            status = client.Create(
                treeId,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
                {
                    new Smb2CreateRequestLeaseV2
                    {
                        LeaseKey = clientGuid,
                        LeaseState = requestedLeaseState
                    }
                },
                accessMask: AccessMask.GENERIC_ALL,
                shareAccess: ShareAccess_Values.FILE_SHARE_READ,
                checker: (header, response) => { });

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open on directory should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion

            #region Verify server granted lease state
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server granted lease state.");

            BaseTestSite.Assert.AreNotEqual(
                null,
                serverCreateContexts,
                "Server should return granted lease state");
            foreach (Smb2CreateContextResponse serverCreateContext in serverCreateContexts)
            {
                Smb2CreateResponseLeaseV2 createResponseLeaseV2 = serverCreateContext as Smb2CreateResponseLeaseV2;
                if (createResponseLeaseV2 != null)
                {
                    BaseTestSite.Assert.AreEqual(
                        expectedGrantedLeaseState,
                        createResponseLeaseV2.LeaseState,
                        "Server granted lease state {0} should be the same as {1}", createResponseLeaseV2.LeaseState, expectedGrantedLeaseState);
                    break;
                }
            }
            #endregion
        }
コード例 #52
0
        protected bool ConnectToShare(Smb2FunctionalClient client, AccountCredential user, string sharePath, out uint treeId)
        {
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message.");
            client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            AccountCredential accountCredential = user;
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", accountCredential.AccountName, accountCredential.DomainName);
            client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, accountCredential, false);

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", sharePath);
            uint status = client.TreeConnect(sharePath, out treeId, checker: (header, response) => { });
            if (status == Smb2Status.STATUS_SUCCESS)
            {
                return true;
            }
            if (status == Smb2Status.STATUS_BAD_NETWORK_NAME)
            {
                return false;
            }
            throw new Exception(string.Format("Share detection failed with unexpected error: {0}", Smb2Status.GetStatusCode(status)));
        }
コード例 #53
0
        public void PrepareOpen(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            ModelHandleType modelHandleType,
            OplockLeaseType oplockLeaseType)
        {
            // Lease V2 cases only apply on the server implements SMB 3.x family.
            if (oplockLeaseType == OplockLeaseType.LeaseV2)
                testConfig.CheckDialect(DialectRevision.Smb30);

            // Lease V1 cases only apply on the server implements SMB 2.1 and 3.x family.
            if (oplockLeaseType == OplockLeaseType.LeaseV1)
                testConfig.CheckDialect(DialectRevision.Smb21);

            if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2)
                && !testConfig.IsLeasingSupported)
                Site.Assert.Inconclusive("Test case is applicable in servers that support leasing.");

            requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));
            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;
            if (persistentBit == PersistentBitType.PersistentBitSet)
            {
                clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            }

            clientGuid = Guid.NewGuid();
            requestedContext = oplockLeaseType;
            isCAShare = (connectToCAShare == CAShareType.CAShare);
            IPAddress targetIPAddress;
            string targetServer;

            #region Connect to Common Share or CA Share
            if (!isCAShare)
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
                fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt";
                targetIPAddress = testConfig.SutIPAddress;
                targetServer = testConfig.SutComputerName;
            }
            else
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName);
                fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt";
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer = testConfig.CAShareServerName;
            }

            testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientBeforeDisconnection.CreditGoal = 20;
            testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            testClientBeforeDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
                {
                    if (Smb2Utility.IsSmb3xFamily(response.DialectRevision)
                        && handleConfig.IsPersistentHandleSupported
                        && persistentBit == PersistentBitType.PersistentBitSet)
                    {
                        Site.Assert.IsTrue(
                            response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES),
                            "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " +
                            "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " +
                            "Actual capabilities are {0}", response.Capabilities);
                    }
                });

            testClientBeforeDisconnection.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    testConfig.AccountCredential,
                    testConfig.UseServerGssToken);

            testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection);

            #endregion

            #region Create operation according to the handle type and context
            Smb2CreateContextRequest[] prepareRequestContext = null;
            Smb2CreateContextResponse[] serverCreateContexts = null;
            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;

            switch (oplockLeaseType)
            {
                case OplockLeaseType.LeaseV1:
                    {
                        testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE);

                        prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;
                case OplockLeaseType.LeaseV2:
                    {
                        testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2);

                        prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;

                case OplockLeaseType.BatchOplock:
                    {
                        prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
                    }
                    break;

                case OplockLeaseType.NoOplockOrLease:
                    {
                        prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
                    }
                    break;
            }

            PrepareOpenCreate(
                testClientBeforeDisconnection,
                treeIdBeforeDisconnection,
                fileName,
                out fileIdBeforDisconnection,
                out serverCreateContexts,
                requestedOplockLevel,
                prepareRequestContext);

            #endregion
        }
コード例 #54
0
        protected bool AccessShare(AccountCredential user, string sharePath)
        {
            bool accessSucceed = true;
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            try
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message.");
                client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", user.AccountName, user.DomainName);
                client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, user, false);

                uint treeId;
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", sharePath);
                client.TreeConnect(sharePath, out treeId, checker: (header, response) =>
                {
                    if (header.Status == Smb2Status.STATUS_SUCCESS)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Access succeeded in TREE_CONNECT phase.");
                        accessSucceed = true;
                    }
                    else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Access denied in TREE_CONNECT phase.");
                        accessSucceed = false;
                    }
                    else
                    {
                        BaseTestSite.Assert.Fail("Unexpected error code in TREE_CONNECT response: {0}", Smb2Status.GetStatusCode(header.Status));
                    }
                });

                if (!accessSucceed)
                {
                    client.LogOff();
                    return false;
                }

                FILEID fileId;
                Smb2CreateContextResponse[] createContexResponse;

                BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends CREATE request.");
                uint status = client.Create(
                    treeId,
                    null,
                    CreateOptions_Values.FILE_DIRECTORY_FILE,
                    out fileId,
                    out createContexResponse,
                    accessMask: AccessMask.FILE_READ_DATA | AccessMask.FILE_READ_ATTRIBUTES,
                    createDisposition: CreateDisposition_Values.FILE_OPEN,
                    checker: (header, response) =>
                    {
                        if (header.Status == Smb2Status.STATUS_SUCCESS)
                        {
                            BaseTestSite.Log.Add(LogEntryKind.Debug, "Access succeeded in CREATE phase.");
                            accessSucceed = true;
                        }
                        else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED)
                        {
                            BaseTestSite.Log.Add(LogEntryKind.Debug, "Access denied in CREATE phase.");
                            accessSucceed = false;
                        }
                        else
                        {
                            BaseTestSite.Assert.Fail("Unexpected error code in CREATE response: {0}", Smb2Status.GetStatusCode(header.Status));
                        }
                    });

                if (status == Smb2Status.STATUS_SUCCESS)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF.");
                    client.Close(treeId, fileId);
                }
                client.TreeDisconnect(treeId);
                client.LogOff();
            }
            finally
            {
                client.Disconnect();
            }
            return accessSucceed;
        }
コード例 #55
0
        public void OpenRequest(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            OplockLeaseType oplockLeaseType,
            DurableV1RequestContext durableV1RequestContext,
            DurableV2RequestContext durableV2RequestContext,
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext)
        {
            requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));
            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;
            if (persistentBit == PersistentBitType.PersistentBitSet)
            {
                clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            }

            clientGuid = Guid.NewGuid();
            requestedContext = oplockLeaseType;
            isCAShare = (connectToCAShare == CAShareType.CAShare);
            IPAddress targetIPAddress;
            string targetServer;

            #region Connect to Common Share or CA Share
            if (!isCAShare)
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
                fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt";
                targetIPAddress = testConfig.SutIPAddress;
                targetServer = testConfig.SutComputerName;
            }
            else
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName);
                fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt";
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer = testConfig.CAShareServerName;
            }

            testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientBeforeDisconnection.CreditGoal = 20;
            testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            testClientBeforeDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
                {
                    if (Smb2Utility.IsSmb3xFamily(response.DialectRevision)
                        && handleConfig.IsPersistentHandleSupported
                        && persistentBit == PersistentBitType.PersistentBitSet)
                    {
                        Site.Assert.IsTrue(
                            response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES),
                            "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " +
                            "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " +
                            "Actual capabilities are {0}", response.Capabilities);
                    }
                });

            testClientBeforeDisconnection.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    testConfig.AccountCredential,
                    testConfig.UseServerGssToken);

            testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection);

            #endregion

            #region Construct Create Contexts
            Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext(
                durableV1RequestContext,
                durableV2RequestContext,
                durableV1ReconnectContext,
                durableV2ReconnectContext,
                oplockLeaseType,
                false,
                false);
            #endregion

            #region Send Create request according to different context combination
            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            switch (oplockLeaseType)
            {
                case OplockLeaseType.NoOplockOrLease:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
                    }
                    break;

                case OplockLeaseType.BatchOplock:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
                    }
                    break;

                case OplockLeaseType.LeaseV1:
                case OplockLeaseType.LeaseV2:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;
            }

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            uint status = OpenCreate(
                testClientBeforeDisconnection,
                treeIdBeforeDisconnection,
                fileName,
                out fileId,
                out serverCreateContexts,
                requestedOplockLevel,
                smb2CreateContextRequest);

            #endregion

            DurableHandleResponseContext durableHandleResponse;
            LeaseResponseContext leaseResponse;
            CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse);
            OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig);

            testClientBeforeDisconnection.TreeDisconnect(treeIdAfterDisconnection, (header, response) => { });
            testClientBeforeDisconnection.LogOff();
        }
コード例 #56
0
        /// <summary>
        /// Write content before failover
        /// </summary>
        /// <param name="fsType">FileServerType</param>
        /// <param name="server">File Server name.</param>
        /// <param name="serverAccessIp">File Server Access IP.</param>
        /// <param name="uncSharePath">The share path to write the file.</param>
        /// <param name="file">The file name for writing content.</param>
        /// <param name="content">The content to write.</param>
        /// <param name="clientGuid">Smb2 client Guid.</param>
        /// <param name="createGuid">The Guid for smb2 create request.</param>
        /// <param name="fileId">File id returned by server</param>
        /// <returns></returns>
        protected bool WriteContentBeforeFailover(
            FileServerType fsType,
            string server,
            IPAddress serverAccessIp,
            string uncSharePath,
            string file,
            string content,
            Guid clientGuid,
            Guid createGuid,
            out FILEID fileId)
        {
            uint status = 0;

            fileId         = FILEID.Zero;
            beforeFailover = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

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

            beforeFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, serverAccessIp);

            Capabilities_Values requestCapabilities = 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;

            status = beforeFailover.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: requestCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
            {
                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Negotiate failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            status = beforeFailover.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                server,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "SessionSetup failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            uint treeId = 0;
            Share_Capabilities_Values shareCapabilities = Share_Capabilities_Values.NONE;

            status = beforeFailover.TreeConnect(uncSharePath, out treeId, (header, response) =>
            {
                shareCapabilities = response.Capabilities;
            });

            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "TreeConnect failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            BaseTestSite.Assert.IsTrue(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY),
                                       "CA Share should have SHARE_CAP_CONTINUOUS_AVAILABILITY bit set for Capabilities in TreeConnect response.");

            if (fsType == FileServerType.ScaleOutFileServer)
            {
                BaseTestSite.Assert.IsTrue(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT),
                                           "ScaleOut FS should have SHARE_CAP_SCALEOUT bit set for Capabilities in TreeConnect response.");
            }

            Smb2CreateContextResponse[] serverCreateContexts;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 with PERSISTENT flag set.");
            status = beforeFailover.Create(
                treeId,
                file,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = createGuid,
                    Flags      = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT,
                    Timeout    = 3600000,
                },
            });
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Create failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends WRITE request to write content to the file.");
            status = beforeFailover.Write(treeId, fileId, content);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Write content failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends FLUSH request.");
            status = beforeFailover.Flush(treeId, fileId);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Flush failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Initialize the test client by 
        /// ConnectToServer, Negotiate, SessionSetup and TreeConnect
        /// </summary>
        private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, ip);

            client.Negotiate(
                // Model cases only test Dialect lower than 3.11
                Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302),
                testConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId);
            return client;
        }
コード例 #58
0
        /// <summary>
        /// Read content after failover
        /// </summary>
        /// <param name="server">File server name.</param>
        /// <param name="serverAccessIp">File server access IP.</param>
        /// <param name="uncSharePath">The share path to read the file.</param>
        /// <param name="file">The file name for reading content.</param>
        /// <param name="content">The content to read.</param>
        /// <param name="clientGuid">Smb2 client Guid.</param>
        /// <param name="createGuid">The Guid for smb2 create request.</param>
        /// <param name="fileId">FileId used in DH2C create context</param>
        /// <returns></returns>
        protected bool ReadContentAfterFailover(string server,
                                                IPAddress serverAccessIp,
                                                string uncSharePath,
                                                string file,
                                                string content,
                                                Guid clientGuid,
                                                Guid createGuid,
                                                FILEID fileId)
        {
            uint status;

            BaseTestSite.Assert.AreNotEqual(
                null,
                serverAccessIp,
                "Access IP to the file server should not be empty");
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Got IP {0} to access the file server", serverAccessIp.ToString());

            Smb2FunctionalClient afterFailover = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

            DoUntilSucceed(() => afterFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, serverAccessIp), TestConfig.FailoverTimeout,
                           "Retry to connect to server until succeed within timeout span");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends NEGOTIATE request with the same clientguid of previous client.");
            status = afterFailover.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: 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,
                clientGuid: clientGuid);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Negotiate failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends SESSION_SETUP request with the same SESSION_ID of previous client.");
            status = afterFailover.ReconnectSessionSetup(
                beforeFailover,
                TestConfig.DefaultSecurityPackage,
                server,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "ReconnectSessionSetup failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            // Retry TreeConnect because network path may not be available immediately
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client retries TREE_CONNECT to {0} until succeed or timeout in {1} because network path may not be available immediately.", uncSharePath, TestConfig.FailoverTimeout);
            uint treeId = 0;

            status = afterFailover.TreeConnect(uncSharePath, out treeId, (header, response) => { });
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "TreeConnect failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            // Retry Create because file may not be available immediately
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client retries to send CREATE request with SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 context with PERSISTENT flag set until succeed or timeout in {0}.", TestConfig.FailoverTimeout);
            Smb2CreateContextResponse[] serverCreateContexts;
            status = DoUntilSucceed(
                () => afterFailover.Create(
                    treeId,
                    file,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    out fileId,
                    out serverCreateContexts,
                    RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                    new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleReconnectV2
                {
                    FileId = new FILEID {
                        Persistent = fileId.Persistent
                    },
                    CreateGuid = createGuid,
                    Flags      = CREATE_DURABLE_HANDLE_RECONNECT_V2_Flags.DHANDLE_FLAG_PERSISTENT
                },
            },
                    checker: (header, response) => { }),
                TestConfig.FailoverTimeout,
                "Retry Create until succeed within timeout span");
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Create failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            string readContent;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends READ request to read content.");
            status = afterFailover.Read(treeId, fileId, 0, (uint)content.Length, out readContent);
            if (status != Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "Read failed with {0}.", Smb2Status.GetStatusCode(status));
                return(false);
            }

            BaseTestSite.Assert.IsTrue(
                content.Equals(readContent),
                "Content read after failover should be identical to that written before failover");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            status = afterFailover.Close(treeId, fileId);
            status = afterFailover.TreeDisconnect(treeId);
            status = afterFailover.LogOff();
            afterFailover.Disconnect();
            return(true);
        }
コード例 #59
0
        private void SendCreateRequestWithSpecificAppInstanceversion(
            Smb2FunctionalClient client,
            Guid appInstanceId,
            ulong? appInstanceVersionHigh,
            ulong? appInstanceVersionLow,
            DialectRevision dialect,
            uint expectedCreateResponseStatus,
            out uint treeId,
            out FILEID fileId
            )
        {
            #region Client connects to Server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client connects to the file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress);
            client.Negotiate(Smb2Utility.GetDialects(dialect), TestConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            client.TreeConnect(uncSharePath, out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            Smb2CreateAppInstanceVersion appInstanceVersion = new Smb2CreateAppInstanceVersion();
            Smb2CreateContextRequest[] clientCreateContexts;

            if (appInstanceVersionHigh.HasValue && appInstanceVersionLow.HasValue)
            {
                appInstanceVersion.AppInstanceVersionHigh = appInstanceVersionHigh.Value;
                appInstanceVersion.AppInstanceVersionLow = appInstanceVersionLow.Value;
                clientCreateContexts =
                new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    },
                    appInstanceVersion
                };
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with AppInstanceVersionHigh = {0}, AppInstanceVersionLow = {1}.", appInstanceVersion.AppInstanceVersionHigh, appInstanceVersion.AppInstanceVersionLow);
            }
            else
            {
                clientCreateContexts =
                new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    }
                };
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request without AppInstanceVersion.");
            }

            client.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                clientCreateContexts,
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        expectedCreateResponseStatus,
                        header.Status,
                        (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS ?
                        "The open will be closed. Create should succeed. Actually server returns with {0}."
                        : "The open cannot be closed. Create should not succeed. Actually server returns with {0}."),
                        Smb2Status.GetStatusCode(header.Status));
                });

            #endregion
        }
コード例 #60
0
ファイル: TreeMgmt.cs プロジェクト: pirenga/CVE-2020-1206-POC
        public void TreeMgmt_SMB311_TREE_CONNECT_EXTENSION_PRESENT()
        {
            #region Check Applicability
            TestConfig.CheckPlatform(Platform.WindowsServer2019);
            TestConfig.CheckDialect(DialectRevision.Smb311);
            #endregion

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

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: CONNECT; NEGOTIATE; SESSION_SETUP");
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            //Use domain credential to do session setup (e.g. contoso.com\administrator)
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            string infraSharePath = string.Format(@"\\{0}\{1}", TestConfig.ClusteredInfrastructureFileServerName, TestConfig.InfrastructureRootShare);
            uint   treeId;

            string          domainName = TestConfig.DriverComputerName;
            string          userName   = TestConfig.UserName;
            string          password   = TestConfig.UserPassword;
            const int       LOGON32_PROVIDER_DEFAULT  = 0;
            const int       LOGON32_LOGON_INTERACTIVE = 2; //This parameter causes LogonUser to create a primary token.
            SafeTokenHandle safeTokenHandle;               // Call LogonUser to obtain a handle to an access token.
            bool            returnValue = LogonUser(userName, domainName, password,
                                                    LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                                                    out safeTokenHandle);
            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                throw new System.ComponentModel.Win32Exception(ret);
            }
            using (safeTokenHandle)
            {
                using (WindowsIdentity identity = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
                {
                    BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request with extension context and expects success");
                    //Use another local account(e.g. local\administrator) as an idenity passed in tree connect extension
                    client.TreeConnect(
                        infraSharePath,
                        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_IDENTITY_REMOTING),
                            "The share should support identity remoting, actually server returns {0}.", response.ShareFlags.ToString());
                    },
                        TreeConnect_Flags.SMB2_SHAREFLAG_EXTENSION_PRESENT,
                        identity);

                    FILEID fileId;
                    Smb2CreateContextResponse[] serverCreateContexts;
                    BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client impersonates another log in user to send CREATE request and expects success.");
                    client.Create(
                        treeId,
                        GetTestFileName(infraSharePath),
                        CreateOptions_Values.FILE_DIRECTORY_FILE,
                        out fileId,
                        out serverCreateContexts,
                        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.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
                    client.Close(treeId, fileId);
                }
            }

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