/// <summary>
        /// This method will send ComNegotiate request before sending a Negotiate request to simulate windows client behaviour.
        /// If ComNegotiate failed, the Negotiate request will still be sent.
        /// </summary>
        public uint MultiProtocolNegotiate(
            Smb2Client client,
            ushort creditCharge,
            ushort creditRequest,
            Packet_Header_Flags_Values flags,
            ulong messageId,
            DialectRevision[] dialects,
            SecurityMode_Values securityMode,
            Capabilities_Values capabilities,
            Guid clientGuid,
            out DialectRevision selectedDialect,
            out byte[] gssToken,
            out Packet_Header responseHeader,
            out NEGOTIATE_Response responsePayload)
        {
            uint status = client.MultiProtocolNegotiate(
                new string[] { "SMB 2.002", "SMB 2.???" },
                out selectedDialect,
                out gssToken,
                out responseHeader,
                out responsePayload);

            if (responseHeader.Status != Smb2Status.STATUS_SUCCESS)
            {
                LogFailedStatus("ComNegotiate", responseHeader.Status);
            }


            PreauthIntegrityHashID[] preauthHashAlgs = null;
            EncryptionAlgorithm[]    encryptionAlgs  = null;

            // For back compatibility, if dialects contains SMB 3.11, preauthentication integrity context should be present.
            if (Array.IndexOf(dialects, DialectRevision.Smb311) >= 0)
            {
                preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 };
                encryptionAlgs  = new EncryptionAlgorithm[] {
                    EncryptionAlgorithm.ENCRYPTION_AES128_GCM,
                    EncryptionAlgorithm.ENCRYPTION_AES128_CCM
                };
            }

            status = client.Negotiate(
                creditCharge,
                creditRequest,
                flags,
                messageId,
                dialects,
                securityMode,
                capabilities,
                clientGuid,
                out selectedDialect,
                out gssToken,
                out responseHeader,
                out responsePayload,
                0,
                preauthHashAlgs,
                encryptionAlgs);

            return(status);
        }
示例#2
0
        private SecurityMode_Values GetNegotiateSecurityMode(SigningEnabledType signingEnabledType, SigningRequiredType signingRequiredType)
        {
            SecurityMode_Values securityMode = SecurityMode_Values.NONE;

            if (signingEnabledType == SigningEnabledType.SigningEnabledSet)
            {
                securityMode |= SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;
            }
            if (signingRequiredType == SigningRequiredType.SigningRequiredSet)
            {
                securityMode |= SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED;
            }

            return(securityMode);
        }
        public static void SetupConnection(ModelDialectRevision dialect,
                                           ModelCapabilities capabilities,
                                           SecurityMode_Values securityMode)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            // capabilities, securityMode should be isolated and combined with dialect separately.
            Combination.Interaction(dialect, capabilities);
            Combination.Interaction(dialect, securityMode);

            State = ModelState.Connected;
            Connection_Dialect            = dialect;
            Connection_ClientCapabilities = capabilities;
            Connection_ClientSecurityMode = securityMode;
        }
        /// <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>
        /// 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;
            Connection_ClientSecurityMode = securityMode;
            Connection_ClientGuid = clientGuid;
        }
        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 TriggerServerTerminateConnection()
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client sends negotiate to make server disconnect the connection");
            try
            {
                DialectRevision[]   requestDialect     = new DialectRevision[] { DialectRevision.Smb2002, DialectRevision.Smb21 };
                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;
                clientBeforeDisconnection.Negotiate(requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid);
            }
            catch
            {
            }

            BaseTestSite.Assert.IsTrue(
                clientBeforeDisconnection.Smb2Client.IsServerDisconnected,
                "If Negotiate after Create, the Connection.NegotiateDialect in server is 0x0202, 0x0210, or 0x0300, the server MUST disconnect the connection and not reply");
        }
        public uint Negotiate(DialectRevision[] dialects, SecurityMode_Values securityMode, Capabilities_Values capabilityValue, Guid clientGuid, out DialectRevision selectedDialect, ushort creditRequest = 1)
        {
            Packet_Header      header;
            NEGOTIATE_Response negotiateResponse;

            uint status = client.Negotiate(
                0,
                creditRequest,
                Packet_Header_Flags_Values.NONE,
                messageId++,
                dialects,
                securityMode,
                capabilityValue,
                clientGuid,
                out selectedDialect,
                out serverGssToken,
                out header,
                out negotiateResponse);

            grantedCredit = header.CreditRequestResponse;

            return(status);
        }
        /// <summary>
        /// This method will send ComNegotiate request before sending a Negotiate request to simulate windows client behaviour.
        /// If ComNegotiate failed, the Negotiate request will still be sent.      
        /// </summary>
        public uint MultiProtocolNegotiate(
            Smb2Client client,
            ushort creditCharge,
            ushort creditRequest,
            Packet_Header_Flags_Values flags,
            ulong messageId,
            DialectRevision[] dialects,
            SecurityMode_Values securityMode,
            Capabilities_Values capabilities,
            Guid clientGuid,
            out DialectRevision selectedDialect,
            out byte[] gssToken,
            out Packet_Header responseHeader,
            out NEGOTIATE_Response responsePayload)
        {
            uint status = client.MultiProtocolNegotiate(
                    new string[] { "SMB 2.002", "SMB 2.???" },
                    out selectedDialect,
                    out gssToken,
                    out responseHeader,
                    out responsePayload);

            if (responseHeader.Status != Smb2Status.STATUS_SUCCESS)
            {
                LogFailedStatus("ComNegotiate", responseHeader.Status);
            }

            // If server only supports Smb2002, no further SMB2 negotiate needed
            if (selectedDialect == DialectRevision.Smb2002)
            {
                return status;
            }

            PreauthIntegrityHashID[] preauthHashAlgs = null;
            EncryptionAlgorithm[] encryptionAlgs = null;

            // For back compatibility, if dialects contains SMB 3.11, preauthentication integrity context should be present.
            if (Array.IndexOf(dialects, DialectRevision.Smb311) >= 0)
            {
                preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 };
                encryptionAlgs = new EncryptionAlgorithm[] {
                EncryptionAlgorithm.ENCRYPTION_AES128_GCM,
                EncryptionAlgorithm.ENCRYPTION_AES128_CCM };
            }

            status = client.Negotiate(
                creditCharge,
                creditRequest,
                flags,
                messageId,
                dialects,
                securityMode,
                capabilities,
                clientGuid,
                out selectedDialect,
                out gssToken,
                out responseHeader,
                out responsePayload,
                0,
                preauthHashAlgs,
                encryptionAlgs);

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

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

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

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);

                negotiateResponse = response;
            });


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when {0}", errCondition);
        }
        /// <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();
        }
        /// <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 static void SetupConnection(ModelDialectRevision dialect,
            ModelCapabilities capabilities,
            SecurityMode_Values securityMode)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            // capabilities, securityMode should be isolated and combined with dialect separately.
            Combination.Interaction(dialect, capabilities);
            Combination.Interaction(dialect, securityMode);

            State = ModelState.Connected;
            Connection_Dialect = dialect;
            Connection_ClientCapabilities = capabilities;
            Connection_ClientSecurityMode = securityMode;
        }