Ejemplo n.º 1
0
        private void NegotiateWithSpecificDialect(DialectRevision clientMaxDialectSupported)
        {
            DialectRevision serverMaxDialectSupported = TestConfig.MaxSmbVersionSupported;

            DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported);

            if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported)
            {
                BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.",
                                                 TestConfig.MaxSmbVersionClientSupported,
                                                 clientMaxDialectSupported);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with maximum dialect: {0}.", clientMaxDialectSupported);
            client.Negotiate(
                Packet_Header_Flags_Values.NONE,
                negotiateDialects,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                DialectRevision expectedDialect = clientMaxDialectSupported < serverMaxDialectSupported
                        ? clientMaxDialectSupported : serverMaxDialectSupported;

                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check negotiate response contains expected dialect.");
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
                BaseTestSite.Assert.AreEqual(expectedDialect, response.DialectRevision, "Selected dialect should be {0}", expectedDialect);
            });
        }
Ejemplo n.º 2
0
        private void NegotiateWithNegotiateContexts(
            DialectRevision clientMaxDialectSupported,
            PreauthIntegrityHashID[] preauthHashAlgs,
            EncryptionAlgorithm[] encryptionAlgs         = null,
            ResponseChecker <NEGOTIATE_Response> checker = null)
        {
            // ensure clientMaxDialectSupported higher than 3.11
            if (clientMaxDialectSupported < DialectRevision.Smb311)
            {
                clientMaxDialectSupported = DialectRevision.Smb311;
            }
            DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported);

            if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported)
            {
                BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.",
                                                 TestConfig.MaxSmbVersionClientSupported,
                                                 clientMaxDialectSupported);
            }

            status = client.NegotiateWithContexts(
                Packet_Header_Flags_Values.NONE,
                negotiateDialects,
                preauthHashAlgs: preauthHashAlgs,
                encryptionAlgs: encryptionAlgs,
                checker: checker);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        public void Negotiate_SMB311_WithEncryptionContextWithoutIntegrityContext()
        {
            if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311)
            {
                BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11.");
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, with SMB2_ENCRYPTION_CAPABILITIES context, " +
                                 "without SMB2_PREAUTH_INTEGRITY_CAPABILITIES context.");
            client.NegotiateWithContexts(
                Packet_Header_Flags_Values.NONE,
                Smb2Utility.GetDialects(DialectRevision.Smb311),
                preauthHashAlgs: null,
                encryptionAlgs: new EncryptionAlgorithm[] {
                EncryptionAlgorithm.ENCRYPTION_AES128_GCM,
                EncryptionAlgorithm.ENCRYPTION_AES128_CCM
            },
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server fails the negotiate request with STATUS_INVALID_PARAMETER.");
                BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_INVALID_PARAMETER, header.Status,
                                             "[MS-SMB2] 3.3.5.4 If the negotiate context list does not contain exactly one SMB2_PREAUTH_INTEGRITY_CAPABILITIES negotiate context, " +
                                             "then the server MUST fail the negotiate request with STATUS_INVALID_PARAMETER.");
            });
        }
        /// <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);
            AccountCredential accountCredential = false ? TestConfig.NonAdminAccountCredential : TestConfig.AccountCredential;

            client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, accountCredential, false);
            //client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId);

            //uint treeId_t;
            string sharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);

            client.TreeConnect(sharePath, out treeId);

            return(client);
        }
        private bool ConnectToShare(string uncSharePath, out uint treeId)
        {
            treeId = 0;

            string serverName = Smb2Utility.GetServerName(uncSharePath);
            var    serverIPs  = Dns.GetHostEntry(serverName).AddressList;

            if (serverIPs == null || serverIPs.Length == 0)
            {
                return(false);
            }

            uint status = 0;

            foreach (var ip in serverIPs) // Try to connect to each IP since not all of them can be connected successfully.
            {
                try
                {
                    client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, Site);
                    client.ConnectToServer(Smb2TransportType.Tcp, serverName, ip);
                    status = client.Negotiate(
                        Smb2Utility.GetDialects(testConfig.MaxSmbVersionSupported),
                        true,
                        checker: (header, response) => { });
                    if (status != Smb2Status.STATUS_SUCCESS)
                    {
                        continue;
                    }

                    status = client.SessionSetup(testConfig.DefaultSecurityPackage, serverName, testConfig.AccountCredential, false, checker: (header, response) => { });
                    if (status != Smb2Status.STATUS_SUCCESS)
                    {
                        client.Disconnect();
                        continue;
                    }

                    status = client.TreeConnect(uncSharePath, out treeId, checker: (header, response) => { });
                    if (status == Smb2Status.STATUS_SUCCESS)
                    {
                        return(true);
                    }
                    else
                    {
                        client.LogOff();
                        client.Disconnect();
                    }
                }
                catch
                {
                    // Catch the exceptions thrown in Negotiage/SessionSetup/TreeConnect
                    // Try next IP
                }
            }

            return(false);
        }
Ejemplo n.º 7
0
        public void Signing_VerifyAesGmacSigning()
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb311);
            TestConfig.CheckSigning();
            #endregion

            var signingAlgorithms = new SigningAlgorithm[] { SigningAlgorithm.AES_GMAC };
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends NEGOTIATE with the Aes-GMAC signing algorithm and NEGOTIATE_SIGNING_REQUIRED.");
            client.NegotiateWithContexts(
                Packet_Header_Flags_Values.NONE,
                Smb2Utility.GetDialects(DialectRevision.Smb311),
                SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED,
                preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 },
                compressionFlags: SMB2_COMPRESSION_CAPABILITIES_Flags.SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE,
                signingAlgorithms: signingAlgorithms,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "SUT MUST return STATUS_SUCCESS if the negotiation finished successfully.");
            });

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends SESSION_SETUP request and expects response.");
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken,
                SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED);

            string uncSharepath =
                Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            uint treeId;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT to share: {0}", uncSharepath);
            client.TreeConnect(
                uncSharepath,
                out treeId,
                (Packet_Header header, TREE_CONNECT_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "TreeConnect should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                BaseTestSite.Assert.AreEqual(
                    Packet_Header_Flags_Values.FLAGS_SIGNED,
                    Packet_Header_Flags_Values.FLAGS_SIGNED & header.Flags,
                    "Server should set SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header");
            });

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF");
            client.TreeDisconnect(treeId);
            client.LogOff();
        }
Ejemplo n.º 8
0
        public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType)
        {
            // Set checkEncrypt to false to not check if the response from the server is actually encrypted.
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site, checkEncrypt: false);
            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;
            },
                ifHandleRejectUnencryptedAccessSeparately: true,
                ifAddGLOBAL_CAP_ENCRYPTION: false,
                addDefaultEncryption: true
                );

            selectedDialect = negotiateResponse.Value.DialectRevision;

            if ((selectedDialect == DialectRevision.Smb30 || selectedDialect == DialectRevision.Smb302) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption)
            {
                /// TD section 3.3.5.4
                /// SMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect is "3.0" or "3.0.2", 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.");
            }
        }
        /// <summary>
        /// Negotiate, SessionSetup and TreeConnect
        /// </summary>
        public void SetupConnection(ModelDialectRevision dialect, ModelCapabilities capabilities, SecurityMode_Values securityMode)
        {
            #region Connect to server
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            #endregion

            // It MUST be a GUID generated by the client, if the Dialects field contains a value other than 0x0202. Otherwise, the client MUST set this to 0.
            Guid clientGuid = (dialect == ModelDialectRevision.Smb2002) ? Guid.Empty : Guid.NewGuid();

            #region negotiate
            testClient.Negotiate(
                Packet_Header_Flags_Values.NONE,
                Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)),
                securityMode,
                (Capabilities_Values)capabilities,
                clientGuid,
                (header, response) =>
            {
                Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command);
                negotiateResponse = response;
            });
            #endregion

            #region session setup
            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken,
                (SESSION_SETUP_Request_SecurityMode_Values)securityMode);
            #endregion

            #region treeconnect
            testClient.TreeConnect(
                Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare),
                out treeId);
            #endregion

            Connection_Dialect            = ModelUtility.GetModelDialectRevision(negotiateResponse.DialectRevision);
            Connection_ClientCapabilities = (Capabilities_Values)capabilities;
            if (dialect >= ModelDialectRevision.Smb30) // GLOBAL_CAP_ENCRYPTION will be added in Functional client when dialect >= SMB30
            {
                Connection_ClientCapabilities |= Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            }
            Connection_ClientSecurityMode = securityMode;
            Connection_ClientGuid         = clientGuid;
        }
        /// <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;
        }
        /// <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);
        }
        public void BVT_PersistentHandles()
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            if (!TestConfig.IsPersistentHandlesSupported)
            {
                Site.Assert.Inconclusive("Test case is applicable in servers that support persistent handles");
            }
            #endregion

            DialectRevision[]   requestDialect     = Smb2Utility.GetDialects(DialectRevision.Smb311);
            Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS
                                                     | Capabilities_Values.GLOBAL_CAP_LEASING
                                                     | Capabilities_Values.GLOBAL_CAP_LARGE_MTU
                                                     | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL
                                                     | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES
                                                     | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING
                                                     | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING
                                                     | Capabilities_Values.GLOBAL_CAP_ENCRYPTION;


            SecurityMode_Values clientSecuirtyMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;

            smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP);
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with client capabilitites: {0}.", clientCapabilities.ToString());

            smb2Functionalclient.Negotiate(
                Packet_Header_Flags_Values.NONE,
                requestDialect,
                clientSecuirtyMode,
                clientCapabilities,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check negotiate response contains {0} in Capabilities.", Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES);
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
                BaseTestSite.Assert.IsTrue(response.DialectRevision >= DialectRevision.Smb30, "Select dialect is {0}, And it should be SMB 3.0 or higher dialect.", response.DialectRevision);
                BaseTestSite.Assert.IsTrue(response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES), "Server Capability should with flag {0} being set.", NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES);
            }
                );
        }
        private void ConnectToShare(ModelDialectRevision dialect, Smb2FunctionalClient client, Guid guid, string share, out uint treeId)
        {
            #region Connect to server
            client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            #endregion

            client.Negotiate(
                Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)),
                testConfig.IsSMB1NegotiateEnabled,
                clientGuid: guid);

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

            client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, share), out treeId);
        }
Ejemplo n.º 14
0
        public void SetupConnection(ModelDialectRevision dialect)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

            testClient.Negotiate(Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)), testConfig.IsSMB1NegotiateEnabled);

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

            string share = testConfig.BasicFileShare;

            testClient.TreeConnect(
                Smb2Utility.GetUncPath(testConfig.SutComputerName, share),
                out treeId);
        }
        public void BVT_SMBDialect()
        {
            smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP);
            DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(DialectRevision.Smb30);

            BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "Send Negotiate request with maximum dialect: {0}.", DialectRevision.Smb30);

            smb2Functionalclient.Negotiate(
                Packet_Header_Flags_Values.NONE,
                negotiateDialects,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "Check dialect in negotiate response is equal to {0}.", DialectRevision.Smb30);
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
                BaseTestSite.Assert.AreEqual(DialectRevision.Smb30, response.DialectRevision, "Selected dialect should be {0}.", DialectRevision.Smb30);
            }
                );
        }
Ejemplo n.º 16
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;
        }
        public void Negotiate_SMB311_Compression_InvalidSmbDialect()
        {
            CheckCompressionApplicability();

            var negotiateDialects = Smb2Utility.GetDialects(DialectRevision.Smb302);

            var compressionAlgorithms = TestConfig.SupportedCompressionAlgorithmList.ToArray();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send NEGOTIATE request with SMB dialects less than 3.1.1.");
            client.NegotiateWithContexts(
                Packet_Header_Flags_Values.NONE,
                negotiateDialects,
                preauthHashAlgs: null,
                compressionAlgorithms: compressionAlgorithms,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "SUT MUST return STATUS_SUCCESS if the negotiation finished successfully.");

                bool isExpectedCompressionContext = client.Smb2Client.CompressionInfo.CompressionIds.Length == 0;

                BaseTestSite.Assert.IsTrue(isExpectedCompressionContext, "SUT MUST ignore SMB2_COMPRESSION_CAPABILITIES if negotiated SMB dialect is less than 3.1.1.");
            });
        }
        /// <summary>
        /// Send ValidateNegotiateInfoRequest to Server, fill in the fields according to params.
        /// Verify the response.
        /// </summary>
        public void ValidateNegotiateInfoRequest(DialectType dialectType,
                                                 CapabilitiesType capabilitiesType,
                                                 SecurityModeType securityModeType,
                                                 ClientGuidType clientGuidType)
        {
            Capabilities_Values capbilities = Connection_ClientCapabilities;

            if (capabilitiesType == CapabilitiesType.CapabilitiesDifferentFromNegotiate)
            {
                capbilities ^= Capabilities_Values.GLOBAL_CAP_DFS;
            }

            SecurityMode_Values securityMode = Connection_ClientSecurityMode;

            if (securityModeType == SecurityModeType.SecurityModeDifferentFromNegotiate)
            {
                securityMode ^= SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;
            }

            Guid guid = clientGuidType == ClientGuidType.ClientGuidSameWithNegotiate ? Connection_ClientGuid : Guid.NewGuid();

            DialectRevision[] dialects = null;
            if (DialectType.None != dialectType)
            {
                ModelDialectRevision dialect = Connection_Dialect;
                if (DialectType.DialectDifferentFromNegotiate == dialectType)
                {
                    dialect = ModelDialectRevision.Smb30 == Connection_Dialect ? ModelDialectRevision.Smb21 : ModelDialectRevision.Smb30;
                }
                dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect));
            }
            else
            {
                dialects = new DialectRevision[] { 0 }
            };

            VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoRequest;

            validateNegotiateInfoRequest.Dialects     = dialects;
            validateNegotiateInfoRequest.DialectCount = (ushort)dialects.Length;
            validateNegotiateInfoRequest.Capabilities = capbilities;
            validateNegotiateInfoRequest.SecurityMode = securityMode;
            validateNegotiateInfoRequest.Guid         = guid;

            Site.Log.Add(
                LogEntryKind.Debug,
                "Dialects in ValidateNegotiateInfoRequest: {0}", Smb2Utility.GetArrayString(validateNegotiateInfoRequest.Dialects));
            Site.Log.Add(
                LogEntryKind.Debug,
                "DialectCount in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.DialectCount);
            Site.Log.Add(
                LogEntryKind.Debug,
                "Capabilities in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.Capabilities);
            Site.Log.Add(
                LogEntryKind.Debug,
                "SecurityMode in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.SecurityMode);
            Site.Log.Add(
                LogEntryKind.Debug,
                "Guid in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.Guid);

            byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoRequest);
            byte[] outputBuffer;
            try
            {
                uint status = testClient.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: CheckIoCtlResponse);
                if (Smb2Status.STATUS_SUCCESS == status)
                {
                    VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResponse = TypeMarshal.ToStruct <VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer);
                    Site.Assert.AreEqual(negotiateResponse.DialectRevision,
                                         validateNegotiateInfoResponse.Dialect,
                                         "Dialect in Negotiate response({0}) and ValidateNegotiateInfo response({1}) should be the same",
                                         negotiateResponse.DialectRevision.ToString(),
                                         validateNegotiateInfoResponse.Dialect.ToString());

                    Site.Assert.AreEqual((uint)negotiateResponse.Capabilities,
                                         (uint)validateNegotiateInfoResponse.Capabilities,
                                         "Capabilities in Negotiate response({0}) and ValidateNegotiateResponse({1}) should be the same",
                                         negotiateResponse.Capabilities.ToString(),
                                         validateNegotiateInfoResponse.Capabilities.ToString());

                    Site.Assert.AreEqual((ushort)negotiateResponse.SecurityMode,
                                         (ushort)validateNegotiateInfoResponse.SecurityMode,
                                         "SecurityMode in Negotiate response({0}) and ValidateNegotiateInfo response({1}) should be the same",
                                         negotiateResponse.SecurityMode.ToString(),
                                         validateNegotiateInfoResponse.SecurityMode.ToString());

                    Site.Assert.AreEqual(negotiateResponse.ServerGuid,
                                         validateNegotiateInfoResponse.Guid,
                                         "ClientGuid in Negotiate response({0}) and ValidateNegotiateInfo response({1}) should be the same",
                                         negotiateResponse.ServerGuid.ToString(),
                                         validateNegotiateInfoResponse.Guid.ToString());
                }

                testClient.TreeDisconnect(treeId);
                testClient.LogOff();
                testClient.Disconnect();
                this.ValidateNegotiateInfoResponse((ModelSmb2Status)status, validateNegotiateInfoConfig);
                return;
            }
            catch
            {
            }

            Site.Assert.IsTrue(testClient.Smb2Client.IsServerDisconnected, "ValidateNegotiationInfo failure should be caused by transport connection termination");
            TerminateConnection();
        }
        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
        }
Ejemplo n.º 20
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>
        /// 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");
                }
            });
        }
        public void SetupConnection(ModelConnectionId connectionId, ModelDialectRevision clientMaxDialect)
        {
            connectionList.Add(connectionId, new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site));

            if (connectionId == ModelConnectionId.MainConnection)
            {
                connectionList[connectionId].ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress, testConfig.ClientNic1IPAddress);
            }
            else
            {
                connectionList[connectionId].ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress, testConfig.ClientNic2IPAddress);
            }

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

            uint status;
            NEGOTIATE_Response?negotiateResponse = null;

            status = connectionList[connectionId].Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL,
                clientGuid: GetClientGuid(connectionId, dialects),
                checker: (header, response) =>
            {
                Site.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed", header.Command);

                negotiateResponse = response;
            });

            DialectRevision expectedDialect;

            if (clientMaxDialect < sessionMgmtConfig.MaxSmbVersionSupported)
            {
                expectedDialect = ModelUtility.GetDialectRevision(clientMaxDialect);
            }
            else
            {
                expectedDialect = ModelUtility.GetDialectRevision(sessionMgmtConfig.MaxSmbVersionSupported);
            }

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

            if (ModelUtility.IsSmb3xFamily(negotiateResponse.Value.DialectRevision) && sessionMgmtConfig.IsMultiChannelCapable)
            {
                // SMB2_GLOBAL_CAP_MULTI_CHANNEL if Connection.Dialect belongs to the SMB 3.x dialect family,
                // IsMultiChannelCapable is TRUE, and SMB2_GLOBAL_CAP_MULTI_CHANNEL is set in the Capabilities field of the request.
                Site.Assert.AreEqual(
                    Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL,
                    Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL & (Capabilities_Values)negotiateResponse.Value.Capabilities,
                    "");
            }
            else
            {
                Site.Assert.AreNotEqual(
                    Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL,
                    Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL & (Capabilities_Values)negotiateResponse.Value.Capabilities,
                    "");
            }
        }
        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
        }
        public void PrepareOpen(ModelDialectRevision clientMaxDialect, DurableHandle durableHandle)
        {
            prepareOpenClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            clientGuid        = Guid.NewGuid();
            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));

            // Connect to Share
            ConnectToShare(
                Site,
                testConfig,
                prepareOpenClient,
                dialects,
                clientGuid,
                testConfig.AccountCredential,
                out dialect,
                out treeId);
            Site.Assert.AreEqual(
                ModelUtility.GetDialectRevision(clientMaxDialect),
                dialect,
                "DialectRevision {0} is expected", ModelUtility.GetDialectRevision(clientMaxDialect));

            // SMB2 Create
            RequestedOplockLevel_Values opLockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;

            Smb2CreateContextRequest[] createContextRequests = new Smb2CreateContextRequest[0];
            createGuid = Guid.Empty;

            if (durableHandle == DurableHandle.DurableHandle)
            {// durable handle request context with batch opLock
                opLockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
                createGuid  = Guid.NewGuid();

                testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST);

                createContextRequests = new Smb2CreateContextRequest[]
                {
                    new Smb2CreateDurableHandleRequest
                    {
                        DurableRequest = createGuid
                    }
                };
            }

            // create
            Smb2CreateContextResponse[] createContextResponse;
            prepareOpenClient.Create(
                treeId,
                GetTestFileName(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare)),
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out createContextResponse,
                requestedOplockLevel_Values: opLockLevel,
                createContexts: createContextRequests,
                checker: (header, response) =>
            {
                Site.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed", header.Command);

                if (durableHandle == DurableHandle.DurableHandle)
                {
                    Site.Assert.AreEqual <OplockLevel_Values>(
                        OplockLevel_Values.OPLOCK_LEVEL_BATCH,
                        response.OplockLevel,
                        "OplockLevel should be OPLOCK_LEVEL_BATCH if Durable Handle");
                }
            }
                );

            if (durableHandle == DurableHandle.DurableHandle)
            {
                // check whether response contain Durable Context
                Site.Assert.IsTrue(
                    ContainDurableHandleResponse(createContextResponse),
                    "Durable Handle Response should be in the Create response.");
            }
        }
        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);
            // 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");

            DialectRevision[] requestDialects;
            if (requestType == ValidateNegotiateInfoRequestType.InvalidSMB311Dialect)
            {
                requestDialects = Smb2Utility.GetDialects(DialectRevision.Smb311);
            }
            else
            {
                // FSCTL_VALIDATE_NEGOTIATE_INFO is only supported in SMB30 and SMB302. For SMB311 and later, we use SMB30 to test the server behavior.
                requestDialects = (TestConfig.MaxSmbVersionClientSupported > DialectRevision.Smb302) ? Smb2Utility.GetDialects(DialectRevision.Smb30) : TestConfig.RequestDialects;
            }

            Guid clientGuid = Guid.NewGuid();
            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;
            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;
            });


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

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

            VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq;
            switch (requestType)
            {
            case ValidateNegotiateInfoRequestType.None:
            case ValidateNegotiateInfoRequestType.InvalidSMB311Dialect:
            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;
            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)
            {
                uint status = client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: (header, response) => { });

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

                VALIDATE_NEGOTIATE_INFO_Response 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");
            }
            else
            {
                string errCondition;
                switch (requestType)
                {
                case ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse:
                    errCondition = "MaxOutputResponse in the request is less than the size of a VALIDATE_NEGOTIATE_INFO Response";
                    break;

                case ValidateNegotiateInfoRequestType.InvalidSMB311Dialect:
                    errCondition = "Connection.Dialect is \"3.1.1\"";
                    break;

                case ValidateNegotiateInfoRequestType.InvalidDialects:
                    errCondition = "there is no greatest common dialect between Dialects field in VALIDATE_NEGOTIATE_INFO Request and the server implemented dialect, or the greatest common dialect is not equal to Connection.Dialect";
                    break;

                case ValidateNegotiateInfoRequestType.InvalidGuid:
                    errCondition = "Guid field in VALIDATE_NEGOTIATE_INFO request is not equal to the ClientGuid sent in the original SMB2 NEGOTIATE request";
                    break;

                case ValidateNegotiateInfoRequestType.InvalidSecurityMode:
                    errCondition = "SecurityMode field in VALIDATE_NEGOTIATE_INFO request is not equal to the SecurityMode sent in the original SMB2 NEGOTIATE request";
                    break;

                case ValidateNegotiateInfoRequestType.InvalidCapabilities:
                    errCondition = "Capabilities field in VALIDATE_NEGOTIATE_INFO request is not equal to the Capabilities sent in the original SMB2 NEGOTIATE request";
                    break;

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

                try
                {
                    uint maxOutputResponse = (requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse) ? (uint)0 : Smb2FunctionalClient.DefaultMaxOutputResponse;
                    client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, maxOutputResponse, checker: (header, response) => { });
                    client.TreeDisconnect(treeId);
                    client.LogOff();
                }
                catch
                {
                }

                BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when {0}", errCondition);
            }
        }
        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 ");
                }
            });
        }
Ejemplo n.º 27
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\".");
        }
Ejemplo n.º 28
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 = GetTestFileName(uncSharePath);
            status   = testClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);
        }
Ejemplo n.º 29
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, delegate(Packet_Header responseHeader, TREE_CONNECT_Response response)
            {
                if (isCAShare)
                {
                    if (!response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY))
                    {
                        // skip test case for CA share is invalid
                        Site.Assert.Inconclusive("This test case is applicable only when CA share is valid.");
                    }
                }
            });

            #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();
        }
        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 = string.Format(@"{0}\{1}", 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: Guid.NewGuid(),
                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
        }