public void PrepareOpen(
            ModelDialectRevision dialect,
            AppInstanceIdType appInstanceIdType,
            CreateType createType)
        {
            // Connect, Negotiate, SessionSetup, TreeConnect
            prepareClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            this.connection_ClientGuid = Guid.NewGuid();
            clientDialect = dialect;
            ConnectToShare(clientDialect, prepareClient, connection_ClientGuid, testConfig.BasicFileShare, out treeConnect_TreeId);

            // Create
            this.fileName = GetTestFileName(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare));
            Smb2CreateContextResponse[] createContextResponse;

            prepareClient.Create(
                this.treeConnect_TreeId,
                this.fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out this.open_FileId,
                out createContextResponse,
                createContexts: CreateContexts(appInstanceIdType, createType, true),
                shareAccess: ShareAccess_Values.NONE);

            if (createType == CreateType.CreateDurableThenDisconnect)
            {
                prepareClient.Disconnect();
            }
        }
        public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType)
        {
            Condition.IsTrue(state == ModelState.Initialized);
            Condition.IsNull(request);

            negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, config.MaxSmbVersionSupported);

            Connection_ClientCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? true : false;

            if (ModelUtility.IsSmb3xFamily(negotiateDialect) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption)
            {
                ModelHelper.Log(LogType.Requirement,
                                "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:");
                ModelHelper.Log(LogType.Requirement,
                                "\tSMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect belongs to the SMB 3.x dialect family, the server supports encryption, " +
                                "and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request.");

                // Encrpytion Model only applies to server that supports encryption.
                ModelHelper.Log(LogType.TestInfo,
                                "Connection.Dialect is {0}, the server supports encryption and SMB2_GLOBAL_CAP_ENCRYPTION is set. " +
                                "So SMB2_GLOBAL_CAP_ENCRYPTION bit is set in Capabilities field.", negotiateDialect);
                Connection_ServerCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION = true;
            }

            state = ModelState.Connected;
        }
        public void ReadConfig(out ModelDialectRevision dialectRevision)
        {
            // No need to run the case if SMB2_CREATE_APP_INSTANCE_ID is not supported.
            testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID);

            dialectRevision = ModelUtility.GetModelDialectRevision(testConfig.MaxSmbVersionSupported);
        }
        public void PrepareCreate(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelClientSupportPersistent isClientSupportPersistent,
            ReplayModelDurableHandle modelDurableHandle,
            ReplayModelShareType shareType,
            ReplayModelRequestedOplockLevel requestedOplockLevel,
            ReplayModelLeaseState leaseState)
        {
            InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType, out treeIdMainChannel, false, isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);

            Smb2CreateContextRequest[]  contexts;
            RequestedOplockLevel_Values oplockLevel;
            LeaseStateValues            requestLeaseState;

            FillParameters(leaseState, requestedOplockLevel, modelDurableHandle, createGuidMainChannel,
                           leaseKeyMainChannel, out requestLeaseState, out oplockLevel, out contexts);

            Smb2CreateContextResponse[] serverCreateContexts;
            smb2ClientMainChannel.Create(
                treeIdMainChannel,
                fileNameMainChannel,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdMainChannel,
                out serverCreateContexts,
                oplockLevel,
                contexts
                );

            ReplayModelDurableHandle preparedHandle = ConvertHandle(serverCreateContexts);

            Site.Assert.IsTrue(modelDurableHandle == preparedHandle, "Prepared handle should be {0}, actual is {1}", modelDurableHandle, preparedHandle);

            prepared = true;
        }
        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);
        }
示例#6
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);
        }
        public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            // Then maxSmbVersionClientSupported can not be larger than Config.MaxSmbVersionServerSupported (by DetermineNegotiateDialect)
            ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, Config.MaxSmbVersionServerSupported);

            State = ModelState.Connected;
        }
        public static void PrepareOpen(ModelDialectRevision clientMaxDialect, DurableHandle durableHandle)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            Connection_Dialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, Config.MaxSmbVersionSupported);

            State = ModelState.Connected;
            Open  = new ModelOpen(durableHandle == DurableHandle.DurableHandle? true : false);
        }
示例#9
0
 public ModelFileOperationRequest(
     FileOperation operation,
     OperatorType operatorType,
     ModelDialectRevision dialect)
     : base(0)
 {
     this.Operation = operation;
     this.OptorType = operatorType;
     this.Dialect   = dialect;
 }
示例#10
0
        public static void ReadConfigReturn(ModelDialectRevision dialectRevision)
        {
            Condition.IsTrue(dialectRevision == ModelDialectRevision.Smb2002 ||
                             dialectRevision == ModelDialectRevision.Smb21 ||
                             dialectRevision == ModelDialectRevision.Smb30 ||
                             dialectRevision == ModelDialectRevision.Smb302);
            MaxSmbVersionSupported = dialectRevision;

            State = ModelState.Initialized;
        }
示例#11
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.");
            }
        }
        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;
        }
        public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportDirectoryLeasingType clientSupportDirectoryLeasingType)
        {
            Condition.IsTrue(state == ModelState.Initialized);

            // Current leasing only supports to test leasing on the file. So limit the exploration.
            Condition.IsTrue(clientSupportDirectoryLeasingType == ClientSupportDirectoryLeasingType.ClientNotSupportDirectoryLeasing);

            request          = null;
            negotiateDialect = DialectRevision.Smb2Unknown;
            smb2Lease        = null;

            negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, config.MaxSmbVersionSupported);

            state = ModelState.Connected;
        }
示例#14
0
        public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ModelShareFlag shareFlag, ModelShareType shareType)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            Open               = null;
            Request            = null;
            Connection_Dialect = DialectRevision.Smb2Unknown;

            Connection_Dialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, Config.MaxSmbVersionSupported);

            Share_ForceLevel2Oplock = shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK;
            Share_Type_Include_STYPE_CLUSTER_SOFS = shareType == ModelShareType.STYPE_CLUSTER_SOFS;

            State = ModelState.Connected;
        }
        /// <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>
        /// Convert dialect from DialectRevision to ModelDialectRevision.
        /// </summary>
        /// <param name="dialect">DialectRevision</param>
        /// <returns>ModelDialectRevision</returns>
        public static ModelDialectRevision GetModelDialectRevision(DialectRevision dialect)
        {
            ModelDialectRevision revision = (ModelDialectRevision)(uint)dialect;

            if (Enum.IsDefined(typeof(ModelDialectRevision), revision))
            {
                return(revision);
            }
            else if (dialect > DialectRevision.Smb302 && dialect != DialectRevision.Smb2Unknown)
            {
                return(ModelDialectRevision.Smb302); // Model cases only test Dialect lower than 3.11
            }
            else
            {
                throw new ArgumentException("Unexpected dialect");
            }
        }
示例#17
0
 public ModelReplayFileOperationRequest(ModelReplayChannel channel,
                                        ReplayModelSwitchChannelType switchChannelType,
                                        ModelDialectRevision maxSmbVersionClientSupported,
                                        ReplayModelRequestCommand requestCommand,
                                        ReplayModelChannelSequenceType channelSequence,
                                        ReplayModelSetReplayFlag isSetReplayFlag,
                                        ReplayModelRequestCommandParameters requestCommandParameters
                                        )
     : base(0)
 {
     this.channel                  = channel;
     this.switchChannelType        = switchChannelType;
     this.requestCommand           = requestCommand;
     this.channelSequence          = channelSequence;
     this.isSetReplayFlag          = isSetReplayFlag;
     this.requestCommandParameters = requestCommandParameters;
 }
        /// <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 static void PrepareOpen(
            ModelDialectRevision clientDialect,
            AppInstanceIdType appInstanceIdType,
            CreateType createType)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            // appInstanceIdType should not be Invalid or None when preparing.
            Condition.IsFalse(appInstanceIdType == AppInstanceIdType.InvalidAppInstanceId || appInstanceIdType == AppInstanceIdType.NoAppInstanceId);
            Condition.IsFalse(createType == CreateType.ReconnectDurable);

            Combination.Isolated(clientDialect == ModelDialectRevision.Smb2002);
            Combination.Isolated(clientDialect == ModelDialectRevision.Smb21);

            // If the server doesn't support Dialect 3.x family, then createdurablev2 will not work and CreateDurableThenDisconnect will result in Open is null.
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(MaxSmbVersionSupported), createType != CreateType.CreateDurableThenDisconnect);

            State = ModelState.Connected;
            Open  = new AppInstanceIdModelOpen();
            Open.CreateTypeWhenPrepare = createType;
            Open.AppInstanceId         = AppInstanceIdType.NoAppInstanceId;

            if (!ModelUtility.IsSmb3xFamily(MaxSmbVersionSupported))
            {
                ModelHelper.Log(LogType.TestInfo,
                                "Connection.Dialect does not belong to SMB 3.x dialect family. So Open.AppInstanceId is not set.");
                return;
            }

            // TDI: 72179
            ModelHelper.Log(LogType.Requirement,
                            "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family, the server MUST initialize the following:");
            ModelHelper.Log(LogType.TestInfo, "Server supports dialect {0}.", MaxSmbVersionSupported);

            if (createType == CreateType.CreateDurable)
            {
                ModelHelper.Log(LogType.Requirement,
                                "3.3.5.9: Open.AppInstanceId MUST be set to AppInstanceId in the SMB2_CREATE_APP_INSTANCE_ID create context request " +
                                "if the create request includes the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 and SMB2_CREATE_APP_INSTANCE_ID create contexts.");
                Open.AppInstanceId = appInstanceIdType;
                ModelHelper.Log(LogType.TestInfo,
                                "The create request includes the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 and SMB2_CREATE_APP_INSTANCE_ID create contexts.");
            }
        }
示例#20
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);
        }
        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);
        }
        public static void NegotiateRequest(
            ModelDialectRevision maxSmbVersionClientSupported,
            SigningFlagType signingFlagType,
            SigningEnabledType signingEnabledType,
            SigningRequiredType signingRequiredType)
        {
            Condition.IsTrue(State == ModelState.Initialized);
            Condition.IsNull(Request);

            // Add isolate for SigningFlagType to reduce redundant cases: If the signingFlagType is set to SignedFlagSet, server will always return error
            // code STATUS_INVALID_PARAMETER, we don't need to cover all the invalid combination with other params.
            Combination.Isolated(signingFlagType == SigningFlagType.SignedFlagSet);

            NegotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, Config.MaxSmbVersionSupported);

            Request = new SigningModelRequest(signingFlagType, signingEnabledType, signingRequiredType);

            State = ModelState.Connected;
        }
        public static void NegotiateRequest(
            ModelDialectRevision maxSmbVersionClientSupported,
            SigningFlagType signingFlagType,
            SigningEnabledType signingEnabledType,
            SigningRequiredType signingRequiredType)
        {
            Condition.IsTrue(State == ModelState.Initialized);
            Condition.IsNull(Request);

            // Add isolate for SigningFlagType to reduce redundant cases: If the signingFlagType is set to SignedFlagSet, server will always return error
            // code STATUS_INVALID_PARAMETER, we don't need to cover all the invalid combination with other params.
            Combination.Isolated(signingFlagType == SigningFlagType.SignedFlagSet);

            NegotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, Config.MaxSmbVersionSupported);

            Request = new SigningModelRequest(signingFlagType, signingEnabledType, signingRequiredType);

            State = ModelState.Connected;
        }
        public static void SetupConnection(ModelConnectionId connectionId, ModelDialectRevision clientMaxDialect)
        {
            // Restrict model contains 2 connections at most
            Condition.IsTrue(!ConnectionList.ContainsKey(connectionId));

            // Reduce states
            Combination.NWise(1, connectionId, clientMaxDialect);

            DialectRevision dialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, config.MaxSmbVersionSupported);

            // Establish new connection
            ConnectionList.Add(
                connectionId,
                new ModelConnection(dialect));

            ConnectionList[connectionId].ConnectionState = ModelState.Connected;

            ModelHelper.Log(LogType.Requirement, "3.3.5.1: Connection.ConstrainedConnection is set to TRUE.");
            ConnectionList[connectionId].ConstrainedConnection = true;
        }
        private bool CheckIfOpenClosed(ModelDialectRevision dialect, CreateType createType)
        {
            if (createType == CreateType.ReconnectDurable)
            {
                /// prepareClient is disconnected, so
                /// Reconnect to the share and try to get the open, if the durable open can be reconnected, then it's not closed.
                Smb2FunctionalClient reconnectClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
                uint treeId;
                ConnectToShare(
                    dialect,
                    reconnectClient,
                    this.connection_ClientGuid,
                    testConfig.BasicFileShare,
                    out treeId);
                FILEID fileId;
                Smb2CreateContextResponse[] createContextResponse;
                uint status = reconnectClient.Create(
                    treeId,
                    this.fileName,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    out fileId,
                    out createContextResponse,
                    createContexts: CreateContexts(AppInstanceIdType.NoAppInstanceId, createType, false),
                    shareAccess: ShareAccess_Values.NONE,
                    checker: (header, response) => {});

                Site.Log.Add(LogEntryKind.Debug, "CheckIfOpenClosed: status of reconnectClient.Create is " + Smb2Status.GetStatusCode(status));

                reconnectClient.Close(treeId, fileId, (header, response) => { });
                reconnectClient.Disconnect();
                return(!(status == Smb2Status.STATUS_SUCCESS));
            }
            else
            {
                /// Write (using the FileID got from the create response of PrepareOpen) to check if the Open is closed.
                uint status = prepareClient.Write(this.treeConnect_TreeId, this.open_FileId, "AppInstanceId", checker: (header, response) => { });
                Site.Log.Add(LogEntryKind.Debug, "CheckIfOpenClosed: status of Write is " + Smb2Status.GetStatusCode(status));
                prepareClient.Close(this.treeConnect_TreeId, this.open_FileId, (header, response) => { });
                return(status == Smb2Status.STATUS_FILE_CLOSED);
            }
        }
        public static void SetupConnection(ModelDialectRevision clientMaxDialect)
        {
            Condition.IsTrue(state == ModelState.Initialized);
            Condition.IsNull(request);

            negotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, config.MaxSmbVersionSupported);

            if ((negotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(negotiateDialect)) &&
                config.IsMultiCreditSupportedOnServer)
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.4: If the common dialect is SMB 2.1 or 3.x dialect family and the underlying connection is either TCP port 445 or RDMA," +
                    "Connection.SupportsMultiCredit MUST be set to TRUE; otherwise, it MUST be set to FALSE.");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Common dialect is {0} and server implementation {1} multicredit", negotiateDialect,
                    config.IsMultiCreditSupportedOnServer ? "supports" : "does not support");

                isMultiCreditSupported = true;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to TRUE");
            }
            else
            {
                isMultiCreditSupported = false;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to FALSE");
            }

            state = ModelState.Connected;
        }
        public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            testClient.Smb2Client.Disconnected += new Action(OnServerDisconnected);

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

            //Set capabilities according to isClientSupportsEncryption
            Capabilities_Values commonCapability = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            Capabilities_Values encryptionCapability = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? (commonCapability | Capabilities_Values.GLOBAL_CAP_ENCRYPTION) : commonCapability;

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

                    negotiateResponse = response;
                });

            selectedDialect = negotiateResponse.Value.DialectRevision;
            if (Smb2Utility.IsSmb3xFamily(selectedDialect) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption)
            {
                /// TD section 3.3.5.4
                /// SMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect belongs to the SMB 3.x dialect, the server supports encryption,
                /// and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request
                Site.Assert.IsTrue(
                            negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION),
                            "SMB2_GLOBAL_CAP_ENCRYPTION should be set in the negotiate response.");
            }
            else
            {
                Site.Assert.IsFalse(
                            negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION),
                            "SMB2_GLOBAL_CAP_ENCRYPTION should not be set in the negotiate response.");
            }
        }
        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;
        }
        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>
        /// 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();
        }
        public static void PrepareOpen(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            ModelHandleType modelHandleType,
            OplockLeaseType oplockLeaseType)
        {
            Condition.IsNull(Request);
            Condition.IsNull(Open);

            // CAShare, Persistent Handle , Durable Handle v2 and Lease V2 are only applied for SMB 3.x family.
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), connectToCAShare == CAShareType.NonCAShare);
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), persistentBit == PersistentBitType.PersistentBitNotSet);
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), modelHandleType == ModelHandleType.DurableHandleV1);

            // Case will go to non-accpeting state if clientMaxDialect > Config.MaxSmbVersionSupported.
            NegotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, Config.MaxSmbVersionSupported);

            // Restrict the params combination
            Combination.Pairwise(clientMaxDialect, persistentBit, connectToCAShare, modelHandleType, oplockLeaseType);

            Share_IsCA = (connectToCAShare == CAShareType.CAShare);

            Open = new HandleModelOpen();
            Open.IsConnectionExisted = true;
            Open.IsSessionExisted = true;

            if (oplockLeaseType == OplockLeaseType.LeaseV1)
            {
                Open.IsLeaseExisted = true;
                Open.LeaseVersion = 1;
            }
            else if (oplockLeaseType == OplockLeaseType.LeaseV2)
            {
                Open.IsLeaseExisted = true;
                Open.LeaseVersion = 2;
            }
            else if (oplockLeaseType == OplockLeaseType.BatchOplock)
            {
                Open.IsBatchOplockExisted = true;
            }

            if (modelHandleType == ModelHandleType.DurableHandleV1)
            {
                if (!Open.IsBatchOplockExisted && !Open.IsLeaseExisted)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "3.3.5.9.6: If the RequestedOplockLevel field in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH and " +
                        "the create request does not include an SMB2_CREATE_REQUEST_LEASE create context with a LeaseState field that " +
                        "includes the SMB2_LEASE_HANDLE_CACHING bit value, " +
                        "the server MUST ignore this create context and skip this section.");
                    ModelHelper.Log(LogType.TestInfo, "This section is skipped.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    return;
                }

                ModelHelper.Log(LogType.Requirement, "3.3.5.9.6: In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE. ");
                ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE.");
                Open.IsDurable = true;
            }
            else if (modelHandleType == ModelHandleType.DurableHandleV2 || modelHandleType == ModelHandleType.PersistentHandle)
            {
                ModelHelper.Log(LogType.Requirement, "3.3.5.9.10: This section applies only to servers that implement the SMB 3.x dialect family. ");
                if (!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported))
                {
                    ModelHelper.Log(LogType.TestInfo, "The server implements the dialect {0}.", Config.MaxSmbVersionSupported);
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    return;
                }

                if (modelHandleType != ModelHandleType.PersistentHandle && !Open.IsBatchOplockExisted && !Open.IsLeaseExisted)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If the SMB2_DHANDLE_FLAG_PERSISTENT bit is not set in the Flags field of this create context, " +
                        "if RequestedOplockLevel in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH, " +
                        "and if the create request does not include a SMB2_CREATE_REQUEST_LEASE or " +
                        "SMB2_CREATE_REQUEST_LEASE_V2 create context with a LeaseState field that includes SMB2_LEASE_HANDLE_CACHING, " +
                        "the server MUST ignore this create context and skip this section.");
                    ModelHelper.Log(LogType.TestInfo, "This section is skipped.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);

                    return;
                }

                if (ModelUtility.IsSmb3xFamily(NegotiateDialect)
                    && persistentBit == PersistentBitType.PersistentBitSet
                    && Config.IsPersistentHandleSupported)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:");
                    ModelHelper.Log(LogType.Requirement,
                        "\tSMB2_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.");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So SMB2_DHANDLE_FLAG_PERSISTENT bit is set in Connection.ServerCapabilities.");
                    ServerCapabilities_PersistentBitSet = true;
                }

                if (modelHandleType == ModelHandleType.PersistentHandle
                    && !(Share_IsCA && ServerCapabilities_PersistentBitSet))
                {
                    // TDI: if client asks for a persistent handle to a non CA share or
                    // Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_PERSISTENT_HANDLES
                    // The persistent handle is not granted.
                    ModelHelper.Log(
                        LogType.TestInfo,
                        "Share is not a CA share or Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_PERSISTENT_HANDLES.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    return;
                }

                ModelHelper.Log(LogType.Requirement, "In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE. ");
                ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE.");
                Open.IsDurable = true;

                if (modelHandleType == ModelHandleType.PersistentHandle && Share_IsCA && ServerCapabilities_PersistentBitSet)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "3.3.5.9.10: If the SMB2_DHANDLE_FLAG_PERSISTENT bit is set in the Flags field of the request, " +
                        "TreeConnect.Share.IsCA is TRUE, " +
                        "and Connection.ServerCapabilities includes SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, " +
                        "the server MUST set Open.IsPersistent to TRUE.");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So Open.IsPersistent is set to TRUE.");
                    Open.IsPersistent = true;
                }
            }
        }
        public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType)
        {
            Condition.IsTrue(state == ModelState.Initialized);
            Condition.IsNull(request);

            negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, config.MaxSmbVersionSupported);

            Connection_ClientCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? true : false;

            if (ModelUtility.IsSmb3xFamily(negotiateDialect) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption)
            {
                ModelHelper.Log(LogType.Requirement,
                    "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:");
                ModelHelper.Log(LogType.Requirement,
                    "\tSMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect belongs to the SMB 3.x dialect family, the server supports encryption, " +
                    "and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request.");

                // Encrpytion Model only applies to server that supports encryption.
                ModelHelper.Log(LogType.TestInfo,
                    "Connection.Dialect is {0}, the server supports encryption and SMB2_GLOBAL_CAP_ENCRYPTION is set. " +
                    "So SMB2_GLOBAL_CAP_ENCRYPTION bit is set in Capabilities field.", negotiateDialect);
                Connection_ServerCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION = true;
            }

            state = ModelState.Connected;
        }
        public void SetupConnection(ModelDialectRevision clientMaxDialect)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            testClient.RequestSent += new Action<Packet_Header>(PrintSequenceWindow);

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

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

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

                    negotiateResponse = response;
                });

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

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

            negotiateDialect = negotiateResponse.Value.DialectRevision;

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

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

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

            Smb2CreateContextResponse[] serverCreateContexts;
            fileName = Guid.NewGuid().ToString();
            status = testClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);
        }
        public void FileOperationToBreakLeaseRequest(FileOperation operation, OperatorType operatorType, ModelDialectRevision dialect, out LeasingConfig c)
        {
            c = leasingConfig;

            LeasingClientInfo clientInfo = clients[(int)operatorType];

            // Avoid to fail because Windows issue
            if (dialect == ModelDialectRevision.Smb2002)
            {
                clientInfo.ClientGuid = Guid.NewGuid();
            }

            if (!clientInfo.IsInitialized)
            {
                InitializeClient(clientInfo, dialect);
            }

            if (operation == FileOperation.WRITE_DATA)
            {
                #region WRITE_DATA

                uint status = Smb2Status.STATUS_SUCCESS;

                Packet_Header header;
                CREATE_Response createResponse;
                Smb2CreateContextResponse[] serverCreateContexts;

                if (!clientInfo.IsOpened)
                {
                    status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                        originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OPEN_IF,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts,
                        out clientInfo.FileId,
                        out serverCreateContexts,
                        out header,
                        out createResponse);
                    Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Expect that creation succeeds.");
                }

                byte[] data = Encoding.ASCII.GetBytes("Write data to break READ caching.");
                ushort creditCharge = Smb2Utility.CalculateCreditCharge((uint)data.Length, ModelUtility.GetDialectRevision(dialect));

                clientInfo.LastOperationMessageId = clientInfo.MessageId;
                clientInfo.Client.WriteRequest(creditCharge, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId,
                    0, clientInfo.FileId, Channel_Values.CHANNEL_NONE, WRITE_Request_Flags_Values.None, new byte[0], data);
                clientInfo.MessageId += (ulong)creditCharge;

                #endregion
            }
            else if (operation == FileOperation.SIZE_CHANGED)
            {
                #region SIZE_CHANGED

                uint status = Smb2Status.STATUS_SUCCESS;

                Packet_Header header;
                CREATE_Response createResponse;
                Smb2CreateContextResponse[] serverCreateContexts;

                if (!clientInfo.IsOpened)
                {
                    status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                        originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OPEN,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts,
                        out clientInfo.FileId,
                        out serverCreateContexts,
                        out header,
                        out createResponse);
                    Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Expect that creation succeeds.");
                }

                FileEndOfFileInformation changeSizeInfo;
                changeSizeInfo.EndOfFile = 512;

                byte[] inputBuffer;
                inputBuffer = TypeMarshal.ToBytes<FileEndOfFileInformation>(changeSizeInfo);

                clientInfo.LastOperationMessageId = clientInfo.MessageId;
                clientInfo.Client.SetInfoRequest(
                    1,
                    1,
                    clientInfo.Flags,
                    clientInfo.MessageId++,
                    clientInfo.SessionId,
                    clientInfo.TreeId,
                    SET_INFO_Request_InfoType_Values.SMB2_0_INFO_FILE,
                    (byte)FileInformationClasses.FileEndOfFileInformation,
                    SET_INFO_Request_AdditionalInformation_Values.NONE,
                    clientInfo.FileId,
                    inputBuffer);

                #endregion
            }
            else if (operation == FileOperation.RANGE_LOCK)
            {
                #region RANGE_LOCK

                uint status = Smb2Status.STATUS_SUCCESS;

                Packet_Header header;
                CREATE_Response createResponse;
                Smb2CreateContextResponse[] serverCreateContexts;

                if (!clientInfo.IsOpened)
                {
                    status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                        originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OPEN,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts,
                        out clientInfo.FileId,
                        out serverCreateContexts,
                        out header,
                        out createResponse);
                    Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Expect that creation succeeds.");
                }

                clientInfo.Locks = new LOCK_ELEMENT[1];
                clientInfo.LockSequence = 0;
                clientInfo.Locks[0].Offset = 0;
                clientInfo.Locks[0].Length = (ulong)1 * 1024 / 2;
                clientInfo.Locks[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_SHARED_LOCK;

                clientInfo.LastOperationMessageId = clientInfo.MessageId;
                clientInfo.Client.LockRequest(
                    1,
                    1,
                    clientInfo.Flags,
                    clientInfo.MessageId++,
                    clientInfo.SessionId,
                    clientInfo.TreeId,
                    clientInfo.LockSequence++,
                    clientInfo.FileId,
                    clientInfo.Locks
                    );

                #endregion
            }
            else if (operation == FileOperation.OPEN_OVERWRITE)
            {
                #region OPEN_OVERWRITE
                if (clientInfo.IsOpened)
                {
                    clientInfo.Reset(operatorType == OperatorType.SecondClient);

                    InitializeClient(clientInfo, dialect);
                }

                clientInfo.LastOperationMessageId = clientInfo.MessageId;
                clientInfo.Client.CreateRequest(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                    AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                    ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                    originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    CreateDisposition_Values.FILE_OVERWRITE,
                    File_Attributes.NONE,
                    ImpersonationLevel_Values.Impersonation,
                    SecurityFlags_Values.NONE,
                    clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                    clientInfo.CreateContexts);

                #endregion
            }
            else if (operation == FileOperation.OPEN_WITHOUT_OVERWRITE)
            {
                #region OPEN_WITHOUT_OVERWRITE
                if (clientInfo.IsOpened)
                {
                    clientInfo.Reset(operatorType == OperatorType.SecondClient);

                    InitializeClient(clientInfo, dialect);
                }

                if (!clientInfo.IsOpened)
                {
                    clientInfo.LastOperationMessageId = clientInfo.MessageId;
                    clientInfo.Client.CreateRequest(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                        originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OPEN,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts);
                }

                #endregion
            }
            else if (operation == FileOperation.OPEN_SHARING_VIOLATION)
            {
                #region OPEN_SHARING_VIOLATION
                if (clientInfo.IsOpened)
                {
                    clientInfo.Reset(operatorType == OperatorType.SecondClient);

                    InitializeClient(clientInfo, dialect);
                }

                if (!clientInfo.IsOpened)
                {
                    clientInfo.LastOperationMessageId = clientInfo.MessageId;
                    clientInfo.Client.CreateRequest(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ,
                        originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OPEN,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts);
                }
                #endregion
            }
            else if (operation == FileOperation.OPEN_SHARING_VIOLATION_WITH_OVERWRITE)
            {
                #region OPEN_SHARING_VIOLATION_WITH_OVERWRITE
                if (clientInfo.IsOpened)
                {
                    clientInfo.Reset(operatorType == OperatorType.SecondClient);

                    InitializeClient(clientInfo, dialect);
                }

                if (!clientInfo.IsOpened)
                {
                    clientInfo.LastOperationMessageId = clientInfo.MessageId;
                    clientInfo.Client.CreateRequest(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ,
                        originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OVERWRITE,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts);
                }

                #endregion
            }
            else if (operation == FileOperation.DELETED)
            {
                #region DELETED
                if (clientInfo.IsOpened)
                {
                    clientInfo.Reset(operatorType == OperatorType.SecondClient);

                    InitializeClient(clientInfo, dialect);
                }

                uint status = Smb2Status.STATUS_SUCCESS;

                Packet_Header header;
                CREATE_Response createResponse;
                Smb2CreateContextResponse[] serverCreateContexts;

                if (!clientInfo.IsOpened)
                {
                    clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                        (originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE) | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                        CreateDisposition_Values.FILE_OPEN,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts,
                        out clientInfo.FileId,
                        out serverCreateContexts,
                        out header,
                        out createResponse);
                    Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Expect that creation succeeds.");
                }

                FileDispositionInformation deleteInfo;
                deleteInfo.DeletePending = 1;

                byte[] inputBuffer;
                inputBuffer = TypeMarshal.ToBytes<FileDispositionInformation>(deleteInfo);

                clientInfo.LastOperationMessageId = clientInfo.MessageId;
                clientInfo.Client.SetInfoRequest(
                    1,
                    1,
                    clientInfo.Flags,
                    clientInfo.MessageId++,
                    clientInfo.SessionId,
                    clientInfo.TreeId,
                    SET_INFO_Request_InfoType_Values.SMB2_0_INFO_FILE,
                    (byte)FileInformationClasses.FileDispositionInformation,
                    SET_INFO_Request_AdditionalInformation_Values.NONE,
                    clientInfo.FileId,
                    inputBuffer);
                #endregion
            }
            else if (operation == FileOperation.RENAMEED)
            {
                #region RENAMEED
                if (clientInfo.IsOpened)
                {
                    clientInfo.Reset(operatorType == OperatorType.SecondClient);

                    InitializeClient(clientInfo, dialect);
                }

                uint status = Smb2Status.STATUS_SUCCESS;

                Packet_Header header;
                CREATE_Response createResponse;
                Smb2CreateContextResponse[] serverCreateContexts;

                if (!clientInfo.IsOpened)
                {
                    status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.File,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                        originalClient.IsDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OPEN,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        clientInfo.CreateContexts == null ? RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE : RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                        clientInfo.CreateContexts,
                        out clientInfo.FileId,
                        out serverCreateContexts,
                        out header,
                        out createResponse);
                    Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Expect that creation succeeds.");
                }

                string newFileName = originalClient.ParentDirectory + "\\" + Guid.NewGuid().ToString();
                FileRenameInformation info = new FileRenameInformation();
                info.ReplaceIfExists = 1;
                info.FileName = ConvertStringToByteArray(newFileName);
                info.FileNameLength = (uint)info.FileName.Length;
                info.RootDirectory = FileRenameInformation_RootDirectory_Values.V1;
                info.Reserved = new byte[7];

                byte[] inputBuffer;
                inputBuffer = TypeMarshal.ToBytes<FileRenameInformation>(info);

                clientInfo.LastOperationMessageId = clientInfo.MessageId;
                clientInfo.Client.SetInfoRequest(
                    1,
                    1,
                    clientInfo.Flags,
                    clientInfo.MessageId++,
                    clientInfo.SessionId,
                    clientInfo.TreeId,
                    SET_INFO_Request_InfoType_Values.SMB2_0_INFO_FILE,
                    (byte)FileInformationClasses.FileRenameInformation,
                    SET_INFO_Request_AdditionalInformation_Values.NONE,
                    clientInfo.FileId,
                    inputBuffer);

                originalClient.File = newFileName;
                #endregion
            }
            else if (operation == FileOperation.PARENT_DIR_RENAMED)
            {
                #region PARENT_DIR_RENAMED
                if (clientInfo.IsOpened)
                {
                    clientInfo.Reset(operatorType == OperatorType.SecondClient);

                    InitializeClient(clientInfo, dialect);
                }

                uint status = Smb2Status.STATUS_SUCCESS;

                Packet_Header header;
                CREATE_Response createResponse;
                Smb2CreateContextResponse[] serverCreateContexts;

                if (!clientInfo.IsOpened)
                {
                    status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, originalClient.ParentDirectory,
                        AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                        ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                        CreateOptions_Values.FILE_DIRECTORY_FILE,
                        CreateDisposition_Values.FILE_OPEN,
                        File_Attributes.NONE,
                        ImpersonationLevel_Values.Impersonation,
                        SecurityFlags_Values.NONE,
                        RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                        null,
                        out clientInfo.FileId,
                        out serverCreateContexts,
                        out header,
                        out createResponse);
                    Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Expect that creation succeeds.");
                }

                string newFileName = "LeasingDir_" + Guid.NewGuid().ToString();
                FileRenameInformation info = new FileRenameInformation();
                info.ReplaceIfExists = 0;
                info.FileName = ConvertStringToByteArray(newFileName);
                info.FileNameLength = (uint)info.FileName.Length;
                info.RootDirectory = FileRenameInformation_RootDirectory_Values.V1;
                info.Reserved = new byte[7];

                byte[] inputBuffer;
                inputBuffer = TypeMarshal.ToBytes<FileRenameInformation>(info);

                clientInfo.LastOperationMessageId = clientInfo.MessageId;
                clientInfo.Client.SetInfoRequest(
                    1,
                    1,
                    clientInfo.Flags,
                    clientInfo.MessageId++,
                    clientInfo.SessionId,
                    clientInfo.TreeId,
                    SET_INFO_Request_InfoType_Values.SMB2_0_INFO_FILE,
                    (byte)FileInformationClasses.FileRenameInformation,
                    SET_INFO_Request_AdditionalInformation_Values.NONE,
                    clientInfo.FileId,
                    inputBuffer);
                // Does not need to update these two fields File and ParentDirectory in orginal client because the operation will fail.
                #endregion
            }

            lastOperation = new BreakOperation(operation, operatorType);
        }
 /// <summary>
 /// Determine if a given model dialect belongs to the SMB 2 dialect family
 /// </summary>
 /// <param name="dialect">Model dialect to be determined</param>
 /// <returns>Return true if given model dialect belongs to the SMB 2 dialect family, otherwise return false</returns>
 public static bool IsSmb2Family(ModelDialectRevision dialect)
 {
     return dialect == ModelDialectRevision.Smb2002 || dialect == ModelDialectRevision.Smb21;
 }
 public ModelFileOperationRequest(
     FileOperation operation,
     OperatorType operatorType,
     ModelDialectRevision dialect)
     : base(0)
 {
     this.Operation = operation;
     this.OptorType = operatorType;
     this.Dialect = dialect;
 }
示例#37
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
        }
        public void SetupConnection(ModelDialectRevision dialect, ClientSupportDirectoryLeasingType clientSupportDirectoryLeasingType)
        {
            string parentDirectory = "LeasingDir_" + Guid.NewGuid().ToString();
            CreateFile(dialect, parentDirectory, true);

            originalClient = new LeasingClientInfo(testConfig.Timeout, testConfig);
            originalClient.ParentDirectory = parentDirectory;
            originalClient.File = parentDirectory + "\\" + Guid.NewGuid().ToString();

            originalClient.Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived);

            bool isClientSupportDirectoryLeasing = clientSupportDirectoryLeasingType == ClientSupportDirectoryLeasingType.ClientSupportDirectoryLeasing;
            InitializeClient(originalClient, dialect, isClientSupportDirectoryLeasing);

            clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig, originalClient.ClientGuid)); // SameClientId
            clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig, originalClient.ClientGuid)); // SameClientGuidDifferentLeaseKey
            clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig)); // Second client

            clients[(int)OperatorType.SameClientId].Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(clients[(int)OperatorType.SameClientId].OnLeaseBreakNotificationReceived);
        }
        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 ");
                    }
                });
        }
        public static void CreateRequest(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelShareType shareType,
            ReplayModelClientSupportPersistent clientPersistentCapability,
            ReplayModelSwitchChannelType switchChannelType,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isSetReplayFlag,
            ReplayModelDurableHandle modelDurableHandle,
            ReplayModelRequestedOplockLevel requestedOplockLevel,
            ReplayModelLeaseState leaseState,
            ReplayModelFileName fileName,
            ReplayModelCreateGuid createGuid,
            ReplayModelFileAttributes fileAttributes,
            ReplayModelCreateDisposition createDisposition,
            ReplayModelLeaseKey leaseKey)
        {
            Condition.IsTrue(State == ModelState.Connected || State == ModelState.Initialized);
            Condition.IsNull(Request);

            Combination.NWise(2, maxSmbVersionClientSupported, shareType, clientPersistentCapability, switchChannelType, channelSequence, isSetReplayFlag, modelDurableHandle,
                requestedOplockLevel, leaseState, fileName, createGuid, fileAttributes, createDisposition, leaseKey);

            Combination.Isolated(channelSequence == ReplayModelChannelSequenceType.InvalidChannelSequence);
            Combination.Isolated(channelSequence == ReplayModelChannelSequenceType.ChannelSequenceBoundaryValid);

            //No lease for non durable handle 
            Condition.IfThen(modelDurableHandle == ReplayModelDurableHandle.NormalHandle,
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 &&
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV2);

            //No lease state or lease key(default) if not requesting lease
            Condition.IfThen(
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 &&
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV2,
                leaseState == ReplayModelLeaseState.LeaseStateIsNone && leaseKey == ReplayModelLeaseKey.DefaultLeaseKey);

            //Ensure valid lease state if requesting lease
            Condition.IfThen(
                requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 ||
                requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2,
                leaseState != ReplayModelLeaseState.LeaseStateIsNone);

            if (State == ModelState.Initialized)
            {
                Condition.IsTrue(switchChannelType == ReplayModelSwitchChannelType.MainChannel);

                DialectRevision negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported,
                    Config.MaxSmbVersionSupported);

                MainChannel = new ModelReplayChannel(negotiateDialect, shareType,
                    clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent);
            }
            else // There's already an open exist
            {
                //Open eixsts
                Condition.IsTrue(Open != null);

                // Ensure same dialect
                Condition.IsTrue(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported) == MainChannel.Connection_NegotiateDialect);

                // Ensure connect to same share
                Condition.IsTrue(shareType == MainChannel.Connection_Session_TreeConnect_Share_IsCA);

                switch (switchChannelType)
                {
                    case ReplayModelSwitchChannelType.MainChannel:
                    {
                        Condition.IsTrue((clientPersistentCapability ==
                                          ReplayModelClientSupportPersistent.ClientSupportPersistent) ==
                                         MainChannel.Connection_ClientCapabilities_SupportPersistent);
                        break;
                    }
                    case ReplayModelSwitchChannelType.ReconnectMainChannel:
                    {
                        MainChannel.Connection_ClientCapabilities_SupportPersistent =
                            (clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                        break;
                    }
                    case ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel:
                    case ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel:
                    case ReplayModelSwitchChannelType.MainChannelWithAlternativeChannel:
                    {
                        AlternativeChannel = new ModelReplayChannel(MainChannel.Connection_NegotiateDialect, shareType,
                            clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                        break;
                    }
                }

                #region Handle state changes when there's connection lost or reconnection
                if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel ||
                    switchChannelType == ReplayModelSwitchChannelType.ReconnectMainChannel)
                {
                    bool isPreserved = false;

                    ModelHelper.Log(
                        LogType.Requirement,
                        "3.3.7.1: The server MUST iterate over the Session.OpenTable and determine whether each Open is to be preserved for reconnect." +
                        " If any of the following conditions is satisfied, it indicates that the Open is to be preserved for reconnect");
                    ModelHelper.Log(
                        LogType.TestInfo,
                        "Open.OplockLevel is {0}, Open.OplockState is {1}, Open.IsDurable {2}", Open.OplockLevel,
                        Open.OplockStateIsHeld ? "Held" : "not Held", Open.IsDurable);
                    if (Open.Lease != null)
                    {
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "LeaseState is {0}", Open.Lease.LeaseState);
                    }

                    if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel)
                    {
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "TD does not states the open is preserved when multi channels exist.");
                        isPreserved = true;
                    }
                    else if (Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelBatch &&
                             Open.OplockStateIsHeld &&
                             Open.IsDurable) // Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH and Open.OplockState is equal to Held, and Open.IsDurable is TRUE");

                        isPreserved = true;

                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Open is to be preserved for reconnect");
                    }
                    else if (((Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 ||
                               Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2) && 
                              Open.Lease != null &&
                              Open.Lease.LeaseState == ReplayModelLeaseState.LeaseStateIncludeH &&
                              Open.OplockStateIsHeld &&
                              Open.IsDurable)) // Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_LEASE and contains SMB2_LEASE_HANDLE_CACHING
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_LEASE, Lease.LeaseState contains SMB2_LEASE_HANDLE_CACHING," +
                            " Open.OplockState is equal to Held, and Open.IsDurable is TRUE.");

                        isPreserved = true;

                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Open is to be preserved for reconnect");
                    }
                    // "The server supports leasing and Open.IsResilient is TRUE" covered by resilient model

                    if (isPreserved)
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "If the Open is to be preserved for reconnect, perform the following actions:");
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Set Open.Connection to NULL");
                        //Skip requirement for resilient handle which covered by resilient model

                        Open.ConnectionIsNotNull = false;
                    }
                    else
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "If the Open is not to be preserved for reconnect, the server MUST close the Open as specified in section 3.3.4.17");

                        LastOpen = Open;
                        Open = null;

                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Open is set to NULL");
                    }
                }
                #endregion

            }

            ModelReplayChannel channel = GetChannel(switchChannelType);

            ModelReplayCreateRequest replayCreateRequest = 
                new ModelReplayCreateRequest(channel, switchChannelType, channelSequence, modelDurableHandle, requestedOplockLevel, fileName,
                    createGuid, fileAttributes, createDisposition, leaseState, isSetReplayFlag, leaseKey);

            Request = replayCreateRequest;
            State = ModelState.Connected;
        }
        public static void PrepareCreate(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelClientSupportPersistent clientPersistentCapability,
            ReplayModelDurableHandle modelDurableHandle,
            ReplayModelShareType shareType,
            ReplayModelRequestedOplockLevel requestedOplockLevel,
            ReplayModelLeaseState leaseState)
        {
            Condition.IsNull(MainChannel);

            DialectRevision negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported,
                Config.MaxSmbVersionSupported);

            Combination.NWise(2, maxSmbVersionClientSupported, clientPersistentCapability, modelDurableHandle, shareType,
                requestedOplockLevel, leaseState);

            //No lease state if no lease requested
            Condition.IfThen(requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 && 
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV2,
                leaseState == ReplayModelLeaseState.LeaseStateIsNone);

            //Do not set lease state to none if requesting a lease
            Condition.IfThen(requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 || 
                requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2,
                leaseState != ReplayModelLeaseState.LeaseStateIsNone);

            MainChannel = new ModelReplayChannel(negotiateDialect, shareType, 
                clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent);

            if (Config.TreeConnect_Share_Type_Include_STYPE_CLUSTER_SOFS &&
                requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelBatch)
            {
                // Replay will always use 3.x family
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family TreeConnect.Share.Type" +
                    " includes STYPE_CLUSTER_SOFS and the RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH," +
                    " the server MUST set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II");

                requestedOplockLevel = ReplayModelRequestedOplockLevel.OplockLevelII;
            }

            Open = new ReplayOpen();

            if (requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1)
            {
                // Replay will always use 3.x family
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.9: If Connection.Dialect is \"2.100\" or belongs to the \"3.x\" dialect family, and the DataLength field equals 0x20," +
                    " the server MUST attempt to acquire a lease on the open from the underlying object store as described in section 3.3.5.9.8");
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.9.8: The server MUST set Open.OplockState to Held");

                Open.Lease = new ReplayLease(leaseState);
                Open.OplockStateIsHeld = true;
            }

            if (requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2)
            {
                // Replay will always use 3.x family
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.9: If Connection.Dialect belongs to the \"3.x\" dialect family, and the DataLength field equals 0x34," +
                    " the server MUST attempt to acquire a lease on the open from the underlying object store, as described in section 3.3.5.9.11");
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.9.11: The server MUST set Open.OplockState to Held");

                Open.Lease = new ReplayLease(leaseState);
                Open.OplockStateIsHeld = true;
            }

            Open.OplockLevel = requestedOplockLevel;
            State = ModelState.Connected;

            switch (modelDurableHandle)
            {
                case ReplayModelDurableHandle.DurableHandleV1:
                {
                    if (requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelBatch &&
                        !((requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 ||
                           requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2) && 
                          leaseState == ReplayModelLeaseState.LeaseStateIncludeH))
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.9.6: If the RequestedOplockLevel field in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH and" +
                            " the create request does not include an SMB2_CREATE_REQUEST_LEASE create context with a LeaseState field that includes the SMB2_LEASE_HANDLE_CACHING bit value," +
                            " the server MUST ignore this create context and skip this section.");
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Create context is ignored and skipped due to above conditions");
                        ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    }
                    else
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.9.6: In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE." +
                            " This permits the client to use Open.DurableFileId to request a reopen of the file on a subsequent request as specified in section 3.3.5.9.7." +
                            " The server MUST also set Open.DurableOwner to a security descriptor accessible only by the user represented by Open.Session.SecurityContext.");

                        Open.IsDurable = true;

                        ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE");
                    }
                    break;
                }
                case ReplayModelDurableHandle.DurableHandleV2:
                case ReplayModelDurableHandle.DurableHandleV2Persistent:
                {
                    if (modelDurableHandle == ReplayModelDurableHandle.DurableHandleV2 &&
                        requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelBatch &&
                        !((requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 ||
                           requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2) &&
                          leaseState == ReplayModelLeaseState.LeaseStateIncludeH))
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.9.10: If the SMB2_DHANDLE_FLAG_PERSISTENT bit is not set in the Flags field of this create context," +
                            " if RequestedOplockLevel in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH, and if the create request does not include" +
                            " a SMB2_CREATE_REQUEST_LEASE or SMB2_CREATE_REQUEST_LEASE_V2 create context with a LeaseState field that includes SMB2_LEASE_HANDLE_CACHING," +
                            " the server MUST ignore this create context and skip this section");
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Create context is ignored and skipped due to above conditions");
                        ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    }
                    else
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.9.10: The server MUST set Open.CreateGuid to the CreateGuid in SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2.");

                        Open.CreateGuidIsNotNull = true;

                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.9.10: In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE." +
                            " The server MUST also set Open.DurableOwner to a security descriptor accessible only by the user represented by Open.Session.SecurityContext.");

                        Open.IsDurable = true;

                        ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE");

                        if (modelDurableHandle == ReplayModelDurableHandle.DurableHandleV2Persistent &&
                            shareType == ReplayModelShareType.CAShare &&
                            clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent) //assume connection dialect always 3.x
                        {
                            ModelHelper.Log(
                                LogType.Requirement,
                                "3.3.5.9.10: If the SMB2_DHANDLE_FLAG_PERSISTENT bit is set in the Flags field of the request, TreeConnect.Share.IsCA is TRUE," +
                                " and Connection.ServerCapabilities includes SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, the server MUST set Open.IsPersistent to TRUE");

                            Open.IsPersistent = true;

                            ModelHelper.Log(LogType.TestInfo, "Open.IsPersistent is set to TRUE");
                        }
                    }
                    break;
                }
                case ReplayModelDurableHandle.NormalHandle:
                {
                    //Do nothing for NormalHandle
                    break;
                }
                default:
                    break;
            }
        }
 /// <summary>
 /// Convert dialect from ModelDialectRevision to DialectRevision.
 /// </summary>
 /// <param name="dialect">ModelDialectRevision</param>
 /// <returns>DialectRevision</returns>
 public static DialectRevision GetDialectRevision(ModelDialectRevision dialect)
 {
     return (DialectRevision)(uint)dialect;
 }
        public static void OpenRequest(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            OplockLeaseType oplockLeaseType,
            DurableV1RequestContext durableV1RequestContext,
            DurableV2RequestContext durableV2RequestContext,
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext)
        {
            Condition.IsNull(Request);
            Condition.IsNull(Open);

            // CAShare, Persistent Handle and Durable Handle V2 are only applied for SMB 3.x family.
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), connectToCAShare == CAShareType.NonCAShare);
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), persistentBit == PersistentBitType.PersistentBitNotSet);
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), durableV2RequestContext == DurableV2RequestContext.DurableV2RequestContextNotExist);
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextNotExist);
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), oplockLeaseType != OplockLeaseType.LeaseV2);

            // If leasing is not supported, do not test LeaseV1 or LeaseV2.
            Condition.IfThen(!Config.IsLeasingSupported, oplockLeaseType != OplockLeaseType.LeaseV1 && oplockLeaseType != OplockLeaseType.LeaseV2);

            Combination.Pairwise(
                clientMaxDialect,
                persistentBit,
                connectToCAShare,
                oplockLeaseType,
                durableV1RequestContext,
                durableV2RequestContext,
                durableV1ReconnectContext,
                durableV2ReconnectContext);

            NegotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, Config.MaxSmbVersionSupported);

            Share_IsCA = (connectToCAShare == CAShareType.CAShare);

            if (ModelUtility.IsSmb3xFamily(NegotiateDialect)
                && persistentBit == PersistentBitType.PersistentBitSet
                && Config.IsPersistentHandleSupported)
            {
                ModelHelper.Log(LogType.Requirement,
                    "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:");
                ModelHelper.Log(LogType.Requirement,
                    "\tSMB2_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.");
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So SMB2_DHANDLE_FLAG_PERSISTENT bit is set in Connection.ServerCapabilities.");
                ServerCapabilities_PersistentBitSet = true;
            }

            Request = new ModelOpenFileRequest(
                durableV1RequestContext,
                durableV2RequestContext,
                durableV1ReconnectContext,
                durableV2ReconnectContext,
                oplockLeaseType,
                false,
                false,
                false);
        }
        public void CreateRequest(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelShareType shareType,
            ReplayModelClientSupportPersistent isClientSupportPersistent,
            ReplayModelSwitchChannelType switchChannelType,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isSetReplayFlag,
            ReplayModelDurableHandle modelDurableHandle,
            ReplayModelRequestedOplockLevel requestedOplockLevel,
            ReplayModelLeaseState leaseState,
            ReplayModelFileName fileName,
            ReplayModelCreateGuid createGuid,
            ReplayModelFileAttributes fileAttributes,
            ReplayModelCreateDisposition createDisposition,
            ReplayModelLeaseKey leaseKey)
        {
            Smb2FunctionalClient client = null;

            switch (switchChannelType)
            {
            case ReplayModelSwitchChannelType.MainChannel:
            {
                if (smb2ClientMainChannel == null)
                {
                    InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType,
                                          out treeIdMainChannel, false,
                                          isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                }
                break;
            }

            case ReplayModelSwitchChannelType.ReconnectMainChannel:
            {
                Site.Assume.IsNotNull(smb2ClientMainChannel, "Main channel is expected to exist.");
                smb2ClientMainChannel.Disconnect();
                smb2ClientMainChannel = null;
                InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType,
                                      out treeIdMainChannel, true,
                                      isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                break;
            }

            default:     //AlternativeChannelWithMainChannel, AlternativeChannelWithDisconnectMainChannel, MainChannelWithAlternativeChannel
            {
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel,
                    isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);

                if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel)
                {
                    smb2ClientMainChannel.Disconnect();
                    smb2ClientMainChannel = null;
                }
                break;
            }
            }

            if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel ||
                switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel)
            {
                client = smb2ClientAlternativeChannel;
            }
            else
            {
                client = smb2ClientMainChannel;
            }

            Smb2CreateContextRequest[]  contexts;
            RequestedOplockLevel_Values oplockLevel;
            LeaseStateValues            requestLeaseState;

            FillParameters(leaseState,
                           requestedOplockLevel,
                           modelDurableHandle,
                           createGuid == ReplayModelCreateGuid.DefaultCreateGuid ? createGuidMainChannel : Guid.NewGuid(),
                           leaseKey == ReplayModelLeaseKey.DefaultLeaseKey ? leaseKeyMainChannel : Guid.NewGuid(),
                           out requestLeaseState,
                           out oplockLevel,
                           out contexts);

            FillChannelSequence(client, channelSequence);

            Smb2CreateContextResponse[] serverCreateContexts;
            ulong createRequestId;

            client.CreateRequest(
                treeIdMainChannel,
                fileName == ReplayModelFileName.DefaultFileName ? fileNameMainChannel : Guid.NewGuid().ToString(),
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                (isSetReplayFlag == ReplayModelSetReplayFlag.WithReplayFlag ? Packet_Header_Flags_Values.FLAGS_REPLAY_OPERATION : Packet_Header_Flags_Values.NONE) | (testConfig.SendSignedRequest ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE),
                out createRequestId,
                oplockLevel,
                contexts,
                createDisposition: createDisposition == ReplayModelCreateDisposition.DefaultCreateDisposition ? CreateDisposition_Values.FILE_OPEN_IF : CreateDisposition_Values.FILE_OVERWRITE_IF,
                fileAttributes: fileAttributes == ReplayModelFileAttributes.DefaultFileAttributes ? File_Attributes.NONE : File_Attributes.FILE_ATTRIBUTE_TEMPORARY
                );

            uint status = client.CreateResponse(
                createRequestId,
                out fileIdMainChannel,
                out serverCreateContexts,
                checker: (header, response) =>
            {
            }
                );

            CreateResponse(
                (ModelSmb2Status)status,
                ConvertHandle(serverCreateContexts),
                replayConfig);
        }
        public static void FileOperationRequest(
            ReplayModelSwitchChannelType switchChannelType,
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isSetReplayFlag,
            ReplayModelRequestCommandParameters requestCommandParameters)
        {
            Condition.IsNull(Request);
            Condition.IfThen(ModelRequestCommand != ReplayModelRequestCommand.NoRequest, ModelRequestCommand == requestCommand);
            Condition.IsTrue(requestCommand != ReplayModelRequestCommand.Create && requestCommand != ReplayModelRequestCommand.NoRequest);
            Condition.IsTrue(switchChannelType != ReplayModelSwitchChannelType.ReconnectMainChannel);

            Combination.NWise(2, switchChannelType, maxSmbVersionClientSupported, requestCommand, channelSequence, isSetReplayFlag, 
                requestCommandParameters);
            
            ModelReplayChannel channel = null;
            if (State == ModelState.Initialized)
            {
                Condition.IsTrue(switchChannelType == ReplayModelSwitchChannelType.MainChannel);
                Condition.IsTrue(requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters);

                MainChannel =
                    new ModelReplayChannel(ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported,
                        Config.MaxSmbVersionSupported));

                Open = new ReplayOpen();
                channel = MainChannel;
            }
            else
            {
                Condition.IsNotNull(MainChannel);
                Condition.IsNotNull(Open);
                Condition.IsTrue(maxSmbVersionClientSupported == ModelUtility.GetModelDialectRevision(MainChannel.Connection_NegotiateDialect));

                if (switchChannelType == ReplayModelSwitchChannelType.MainChannel)
                {
                    channel = MainChannel;
                }
                else
                {
                    AlternativeChannel = new ModelReplayChannel(MainChannel.Connection_NegotiateDialect);
                    channel = AlternativeChannel;
                }
            }

            ModelReplayFileOperationRequest operationRequest = new ModelReplayFileOperationRequest(channel, switchChannelType, 
                maxSmbVersionClientSupported, requestCommand, channelSequence, isSetReplayFlag, requestCommandParameters);

            Request = operationRequest;

            State = ModelState.Connected;
        }
        public static void SetupConnection(ModelDialectRevision clientMaxDialect)
        {
            Condition.IsTrue(state == ModelState.Initialized);
            Condition.IsNull(request);

            negotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, config.MaxSmbVersionSupported);

            if ((negotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(negotiateDialect))
                && config.IsMultiCreditSupportedOnServer)
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.4: If the common dialect is SMB 2.1 or 3.x dialect family and the underlying connection is either TCP port 445 or RDMA," +
                    "Connection.SupportsMultiCredit MUST be set to TRUE; otherwise, it MUST be set to FALSE.");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Common dialect is {0} and server implementation {1} multicredit", negotiateDialect,
                    config.IsMultiCreditSupportedOnServer ? "supports" : "does not support");

                isMultiCreditSupported = true;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to TRUE");
            }
            else
            {
                isMultiCreditSupported = false;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.SupportsMultiCredit is set to FALSE");
            }

            state = ModelState.Connected;
        }
        public static void PrepareFileOperation(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand)
        {
            // Condition.IsTrue(maxSmbVersionClientSupported != ModelDialectRevision.Smb302);
            Condition.IsTrue(State == ModelState.Initialized);
            Condition.IsNull(MainChannel);
            Condition.IsNull(Open);
            Condition.IsTrue(ModelRequestCommand == ReplayModelRequestCommand.NoRequest);
            Condition.IsTrue(requestCommand != ReplayModelRequestCommand.Create && requestCommand != ReplayModelRequestCommand.NoRequest);

            MainChannel =
                new ModelReplayChannel(ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported,
                    Config.MaxSmbVersionSupported));

            Open = new ReplayOpen();
            ModelRequestCommand = requestCommand;

            State = ModelState.Connected;
        }
        public static void PrepareOpen(
            ModelDialectRevision clientDialect,
            AppInstanceIdType appInstanceIdType,
            CreateType createType)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            // appInstanceIdType should not be Invalid or None when preparing.
            Condition.IsFalse(appInstanceIdType == AppInstanceIdType.InvalidAppInstanceId || appInstanceIdType == AppInstanceIdType.NoAppInstanceId);
            Condition.IsFalse(createType == CreateType.ReconnectDurable);

            Combination.Isolated(clientDialect == ModelDialectRevision.Smb2002);
            Combination.Isolated(clientDialect == ModelDialectRevision.Smb21);

            // If the server doesn't support Dialect 3.x family, then createdurablev2 will not work and CreateDurableThenDisconnect will result in Open is null.
            Condition.IfThen(!ModelUtility.IsSmb3xFamily(MaxSmbVersionSupported), createType != CreateType.CreateDurableThenDisconnect);

            State = ModelState.Connected;
            Open = new AppInstanceIdModelOpen();
            Open.CreateTypeWhenPrepare = createType;
            Open.AppInstanceId = AppInstanceIdType.NoAppInstanceId;

            if (!ModelUtility.IsSmb3xFamily(MaxSmbVersionSupported))
            {
                ModelHelper.Log(LogType.TestInfo,
                    "Connection.Dialect does not belong to SMB 3.x dialect family. So Open.AppInstanceId is not set.");
                return;
            }

            ModelHelper.Log(LogType.Requirement,
                "3.3.5.9: If the server implements the SMB 3.x dialect family,  the server MUST initialize the following:");
            ModelHelper.Log(LogType.TestInfo, "Server supports dialect {0}.", MaxSmbVersionSupported);

            if (createType == CreateType.CreateDurable)
            {
                ModelHelper.Log(LogType.Requirement,
                    "3.3.5.9: Open.AppInstanceId MUST be set to AppInstanceId in the SMB2_CREATE_APP_INSTANCE_ID create context request " +
                    "if the create request includes the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 and SMB2_CREATE_APP_INSTANCE_ID create contexts.");
                Open.AppInstanceId = appInstanceIdType;
                ModelHelper.Log(LogType.TestInfo,
                    "The create request includes the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 and SMB2_CREATE_APP_INSTANCE_ID create contexts.");
            }
        }
        public void OpenRequest(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            OplockLeaseType oplockLeaseType,
            DurableV1RequestContext durableV1RequestContext,
            DurableV2RequestContext durableV2RequestContext,
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext)
        {
            requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));
            clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING |
                    Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL;
            if (persistentBit == PersistentBitType.PersistentBitSet)
            {
                clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            }

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

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

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

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

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

            testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection);

            #endregion

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

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

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

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

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

            #endregion

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

            testClientBeforeDisconnection.TreeDisconnect(treeIdAfterDisconnection, (header, response) => { });
            testClientBeforeDisconnection.LogOff();
        }
        public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ModelShareFlag shareFlag, ModelShareType shareType)
        {
            Condition.IsTrue(State == ModelState.Initialized);

            Open = null;
            Request = null;
            Connection_Dialect = DialectRevision.Smb2Unknown;

            Connection_Dialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, Config.MaxSmbVersionSupported);

            Share_ForceLevel2Oplock = shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK;
            Share_Type_Include_STYPE_CLUSTER_SOFS = shareType == ModelShareType.STYPE_CLUSTER_SOFS;

            State = ModelState.Connected;
        }
        public void PrepareFileOperation(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand)
        {
            if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                testConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY);
            }

            InitializeMainChannel(
                maxSmbVersionClientSupported,
                clientGuidMainChannel,
                ReplayModelShareType.NonCAShare,
                out treeIdMainChannel);

            uint status = 0;

            #region Create
            Smb2CreateContextResponse[] serverCreateContexts = null;

            status = smb2ClientMainChannel.Create(
                treeIdMainChannel,
                fileNameMainChannel,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdMainChannel,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null);
            #endregion

            if (requestCommand == ReplayModelRequestCommand.Write)
            {
                #region Write
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.SetInfo)
            {
                #region SetInfo
                byte[] buffer = TypeMarshal.ToBytes <FileEndOfFileInformation>(endOfFileInformation);

                status = smb2ClientMainChannel.SetFileAttributes(
                    treeIdMainChannel,
                    (byte)FileInformationClasses.FileEndOfFileInformation,
                    fileIdMainChannel,
                    buffer);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                #region IOCtl
                Packet_Header  ioCtlHeader;
                IOCTL_Response ioCtlResponse;
                byte[]         inputInResponse;
                byte[]         outputInResponse;
                status = smb2ClientMainChannel.ResiliencyRequest(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)),
                    out ioCtlHeader,
                    out ioCtlResponse,
                    out inputInResponse,
                    out outputInResponse,
                    checker: (header, response) =>
                {
                    // do nothing, skip the exception
                }
                    );
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.Read)
            {
                #region Read
                #region Prepare data for read
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
                #endregion

                string data;
                status = smb2ClientMainChannel.Read(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    (uint)testConfig.WriteBufferLengthInKb * 1024,
                    out data);
                #endregion
            }

            prepared = true;
        }
 /// <summary>
 /// Determine if a given model dialect belongs to the SMB 3.x dialect family
 /// </summary>
 /// <param name="dialect">Model dialect to be determined</param>
 /// <returns>Return true if given model dialect belongs to the SMB 3.x dialect family, otherwise return false</returns>
 public static bool IsSmb3xFamily(ModelDialectRevision dialect)
 {
     return dialect >= ModelDialectRevision.Smb30;
 }
        public static void ReadConfigReturn(ModelDialectRevision dialectRevision)
        {
            Condition.IsTrue(dialectRevision == ModelDialectRevision.Smb2002 ||
                             dialectRevision == ModelDialectRevision.Smb21 ||
                             dialectRevision == ModelDialectRevision.Smb30 ||
                             dialectRevision == ModelDialectRevision.Smb302);
            MaxSmbVersionSupported = dialectRevision;

            State = ModelState.Initialized;
        }
        public void FileOperationRequest(
            ReplayModelSwitchChannelType switchChannelType,
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isReplay,
            ReplayModelRequestCommandParameters requestCommandParameters)
        {
            if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                testConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY);
            }

            uint status = Smb2Status.STATUS_SUCCESS;
            Smb2FunctionalClient client = null;

            #region Switch channel
            switch (switchChannelType)
            {
            case ReplayModelSwitchChannelType.MainChannel:
                if (smb2ClientMainChannel == null)
                {
                    InitializeMainChannel(
                        maxSmbVersionClientSupported,
                        clientGuidMainChannel,
                        ReplayModelShareType.NonCAShare,
                        out treeIdMainChannel);

                    #region Create
                    Smb2CreateContextResponse[] serverCreateContexts = null;

                    status = smb2ClientMainChannel.Create(
                        treeIdMainChannel,
                        fileNameMainChannel,
                        CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        out fileIdMainChannel,
                        out serverCreateContexts,
                        RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                        null,
                        shareAccess: ShareAccess_Values.NONE);
                    #endregion
                }
                client = smb2ClientMainChannel;
                break;

            case ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel:
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel);
                client = smb2ClientAlternativeChannel;
                break;

            case ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel:
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel);
                smb2ClientMainChannel.Disconnect();
                smb2ClientMainChannel = null;
                client = smb2ClientAlternativeChannel;
                break;

            case ReplayModelSwitchChannelType.MainChannelWithAlternativeChannel:
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel);
                client = smb2ClientMainChannel;
                break;

            default:
                Site.Assume.Fail("Unknown ReplayModelSwitchChannelType {0}.", switchChannelType);
                break;
            }
            #endregion

            #region Prepare data for read
            if (switchChannelType == ReplayModelSwitchChannelType.MainChannel && !prepared && requestCommand == ReplayModelRequestCommand.Read)
            {
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
            }
            #endregion

            FillChannelSequence(client, channelSequence);

            if (requestCommand == ReplayModelRequestCommand.Write)
            {
                #region Write
                status = client.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? writeContent : Smb2Utility.CreateRandomString(testConfig.WriteBufferLengthInKb),
                    checker: (header, response) =>
                {
                },
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.SetInfo)
            {
                #region SetInfo
                if (requestCommandParameters == ReplayModelRequestCommandParameters.AlternativeParameters)
                {
                    endOfFileInformation.EndOfFile = 512;
                }
                byte[] buffer = TypeMarshal.ToBytes <FileEndOfFileInformation>(endOfFileInformation);

                status = client.SetFileAttributes(
                    treeIdMainChannel,
                    (byte)FileInformationClasses.FileEndOfFileInformation,
                    fileIdMainChannel,
                    buffer,
                    checker: (header, response) =>
                {
                },
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                #region IOCtl
                Packet_Header  ioCtlHeader;
                IOCTL_Response ioCtlResponse;
                byte[]         inputInResponse;
                byte[]         outputInResponse;
                status = client.ResiliencyRequest(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    (uint)(requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? 0 : 2000),
                    (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)),
                    out ioCtlHeader,
                    out ioCtlResponse,
                    out inputInResponse,
                    out outputInResponse,
                    checker: (header, response) =>
                {
                    // do nothing, skip the exception
                }
                    );
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.Read)
            {
                #region Read
                string data;
                status = client.Read(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? (uint)testConfig.WriteBufferLengthInKb * 1024 : 512,
                    out data,
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }

            FileOperationResponse((ModelSmb2Status)status, replayConfig);
        }
        private void CreateFile(ModelDialectRevision dialect, string target, bool isDirectory)
        {
            LeasingClientInfo clientInfo = new LeasingClientInfo(testConfig.Timeout, testConfig);
            clientInfo.File = target;

            InitializeClient(clientInfo, dialect);

            Packet_Header header;
            CREATE_Response createResponse;
            Smb2CreateContextResponse[] serverCreateContexts;
            uint status = 0;

            status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, clientInfo.File,
                AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                CreateDisposition_Values.FILE_OPEN_IF,
                File_Attributes.NONE,
                ImpersonationLevel_Values.Impersonation,
                SecurityFlags_Values.NONE,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null,
                out clientInfo.FileId,
                out serverCreateContexts,
                out header,
                out createResponse);
            clientInfo.GrantedCredit = header.CreditRequestResponse;
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Create a file {0} should succeed, actual status is {1}", clientInfo.File, Smb2Status.GetStatusCode(status));

            clientInfo.Cleanup();
        }
        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
        }
示例#57
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 DeleteFile(ModelDialectRevision dialect, string target, bool isDirectory)
        {
            LeasingClientInfo clientInfo = new LeasingClientInfo(testConfig.Timeout, testConfig);

            InitializeClient(clientInfo, dialect);

            Packet_Header header;
            CREATE_Response createResponse;
            Smb2CreateContextResponse[] serverCreateContexts;
            uint status = 0;

            status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, target,
                AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                (isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE) | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                CreateDisposition_Values.FILE_OPEN_IF,
                File_Attributes.NONE,
                ImpersonationLevel_Values.Impersonation,
                SecurityFlags_Values.NONE,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null,
                out clientInfo.FileId,
                out serverCreateContexts,
                out header,
                out createResponse);
            clientInfo.GrantedCredit = header.CreditRequestResponse;

            FileDispositionInformation deleteInfo;
            deleteInfo.DeletePending = 1;

            byte[] inputBuffer;
            inputBuffer = TypeMarshal.ToBytes<FileDispositionInformation>(deleteInfo);

            SET_INFO_Response responsePayload;
            clientInfo.Client.SetInfo(
                1,
                1,
                clientInfo.Flags,
                clientInfo.MessageId++,
                clientInfo.SessionId,
                clientInfo.TreeId,
                SET_INFO_Request_InfoType_Values.SMB2_0_INFO_FILE,
                (byte)FileInformationClasses.FileDispositionInformation,
                SET_INFO_Request_AdditionalInformation_Values.NONE,
                clientInfo.FileId,
                inputBuffer,
                out header,
                out responsePayload);
            clientInfo.Cleanup();
        }
 public ModelReplayFileOperationRequest(ModelReplayChannel channel,
     ReplayModelSwitchChannelType switchChannelType,
     ModelDialectRevision maxSmbVersionClientSupported,
     ReplayModelRequestCommand requestCommand,
     ReplayModelChannelSequenceType channelSequence,
     ReplayModelSetReplayFlag isSetReplayFlag,
     ReplayModelRequestCommandParameters requestCommandParameters
     )
     : base(0)
 {
     this.channel = channel;
     this.switchChannelType = switchChannelType;
     this.requestCommand = requestCommand;
     this.channelSequence = channelSequence;
     this.isSetReplayFlag = isSetReplayFlag;
     this.requestCommandParameters = requestCommandParameters;
 }
        private void InitializeClient(LeasingClientInfo clientInfo, ModelDialectRevision dialect, bool isClientSupportDirectoryLeasing = false)
        {
            #region Connect to server
            switch (testConfig.UnderlyingTransport)
            {
                case Smb2TransportType.Tcp:
                    Site.Assert.IsTrue(
                        testConfig.SutIPAddress != null && testConfig.SutIPAddress != System.Net.IPAddress.None,
                        "Server IP should not be empty when transport type is TCP.");
                    Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over TCP", testConfig.SutIPAddress.ToString());
                    clientInfo.Client.ConnectOverTCP(testConfig.SutIPAddress);
                    break;
                case Smb2TransportType.NetBios:
                    Site.Assert.IsFalse(string.IsNullOrEmpty(testConfig.SutComputerName), "Server name should not be null when transport type is NetBIOS.");
                    Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over NetBios", testConfig.SutComputerName);
                    clientInfo.Client.ConnectOverNetbios(testConfig.SutComputerName);
                    break;
                default:
                    Site.Assert.Fail("The transport type is {0}, but currently only Tcp and NetBIOS are supported.", testConfig.UnderlyingTransport);
                    break;
            }
            #endregion

            uint status = 0;
            Packet_Header responseHeader = new Packet_Header();
            DialectRevision selectedDialect;
            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect));
            NEGOTIATE_Response negotiatePayload;

            #region Negotiate
            status = clientInfo.Client.Negotiate(0, 1, Packet_Header_Flags_Values.NONE, clientInfo.MessageId++,
                dialects, SecurityMode_Values.NONE, isClientSupportDirectoryLeasing ? Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING : Capabilities_Values.NONE,
                clientInfo.ClientGuid,
                out selectedDialect,
                out clientInfo.ServerGssToken,
                out responseHeader,
                out negotiatePayload);
            Site.Assert.AreEqual(ModelUtility.GetDialectRevision(dialect), negotiatePayload.DialectRevision,
                "DialectRevision 0x{0:x4} is expected.", (ushort)ModelUtility.GetDialectRevision(dialect));
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Negotiation is expected success");
            clientInfo.Dialect = selectedDialect;

            #region Validate Negotiate Response
            if (Smb2Utility.IsSmb3xFamily(selectedDialect))
            {
                Site.Assert.AreEqual<bool>(leasingConfig.IsLeasingSupported,
                    negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING),
                    "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_LEASING 0x00000002.", leasingConfig.IsLeasingSupported ? "contains" : "does not contain");
                Site.Assert.AreEqual<bool>(leasingConfig.IsDirectoryLeasingSupported & isClientSupportDirectoryLeasing,
                    negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING),
                    "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020.",
                    leasingConfig.IsDirectoryLeasingSupported & isClientSupportDirectoryLeasing ? "contains" : "does not contain");
            }
            else if (selectedDialect == DialectRevision.Smb21)
            {
                Site.Assert.AreEqual<bool>(leasingConfig.IsLeasingSupported,
                    negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING),
                    "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_LEASING 0x00000002.", leasingConfig.IsLeasingSupported ? "contains" : "does not contain");
                Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING),
                    "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020.");
            }
            else
            {
                Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING),
                    "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_LEASING 0x00000002.");
                Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING),
                    "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020.");
            }
            #endregion
            #endregion

            #region SESSION_SETUP
            Packet_Header header;
            SESSION_SETUP_Response sessionSetupResponse;

            SspiClientSecurityContext sspiClientGss =
                new SspiClientSecurityContext(
                    testConfig.DefaultSecurityPackage,
                    testConfig.AccountCredential,
                    Smb2Utility.GetCifsServicePrincipalName(testConfig.SutComputerName),
                    ClientSecurityContextAttribute.None,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            // Server GSS token is used only for Negotiate authentication when enabled
            if (testConfig.DefaultSecurityPackage == SecurityPackageType.Negotiate && testConfig.UseServerGssToken)
                sspiClientGss.Initialize(clientInfo.ServerGssToken);
            else
                sspiClientGss.Initialize(null);

            do
            {
                status = clientInfo.Client.SessionSetup(
                    1,
                    64,
                    Packet_Header_Flags_Values.NONE,
                    clientInfo.MessageId++,
                    clientInfo.SessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    SESSION_SETUP_Request_Capabilities_Values.NONE,
                    0,
                    sspiClientGss.Token,
                    out clientInfo.SessionId,
                    out clientInfo.ServerGssToken,
                    out header,
                    out sessionSetupResponse);

                if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) &&
                    clientInfo.ServerGssToken != null && clientInfo.ServerGssToken.Length > 0)
                {
                    sspiClientGss.Initialize(clientInfo.ServerGssToken);
                }
            } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED);

            if (status == Smb2Status.STATUS_SUCCESS)
            {
                clientInfo.SessionKey = sspiClientGss.SessionKey;
                clientInfo.Client.GenerateCryptoKeys(clientInfo.SessionId, clientInfo.SessionKey, true, false);
            }

            clientInfo.GrantedCredit = header.CreditRequestResponse;
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "SessionSetup should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion

            #region TREE_CONNECT to share
            TREE_CONNECT_Response treeConnectPayload;
            status = clientInfo.Client.TreeConnect(1, 1, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, uncSharePath,
                out clientInfo.TreeId, out header, out treeConnectPayload);
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "TreeConnect to {0} should succeed, actual status is {1}", uncSharePath, Smb2Status.GetStatusCode(status));
            if (treeConnectPayload.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK))
            {
                Site.Assert.Inconclusive("This test case is not applicable for the share whose ShareFlags includes SHAREFLAG_FORCE_LEVELII_OPLOCK.");
            }
            if (treeConnectPayload.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT))
            {
                Site.Assert.Inconclusive("This test case is not applicable for the share whose Capabilities includes SHARE_CAP_SCALEOUT.");
            }
            #endregion
        }