Пример #1
0
 public ModelReplayCreateRequest(ModelReplayChannel channel,
                                 ReplayModelSwitchChannelType switchChannelType,
                                 ReplayModelChannelSequenceType channelSequence,
                                 ReplayModelDurableHandle modelDurableHandle,
                                 ReplayModelRequestedOplockLevel requestedOplockLevel,
                                 ReplayModelFileName fileName,
                                 ReplayModelCreateGuid createGuid,
                                 ReplayModelFileAttributes fileAttributes,
                                 ReplayModelCreateDisposition createDisposition,
                                 ReplayModelLeaseState leaseState,
                                 ReplayModelSetReplayFlag isSetReplayFlag,
                                 ReplayModelLeaseKey leaseKey)
     : base(0)
 {
     this.channel              = channel;
     this.switchChannelType    = switchChannelType;
     this.channelSequence      = channelSequence;
     this.modelDurableHandle   = modelDurableHandle;
     this.requestedOplockLevel = requestedOplockLevel;
     this.fileName             = fileName;
     this.createGuid           = createGuid;
     this.fileAttributes       = fileAttributes;
     this.createDisposition    = createDisposition;
     this.leaseState           = leaseState;
     this.isSetReplayFlag      = isSetReplayFlag;
     this.leaseKey             = leaseKey;
 }
 public ModelReplayCreateRequest(ModelReplayChannel channel,
     ReplayModelSwitchChannelType switchChannelType,
     ReplayModelChannelSequenceType channelSequence,
     ReplayModelDurableHandle modelDurableHandle,
     ReplayModelRequestedOplockLevel requestedOplockLevel,
     ReplayModelFileName fileName,
     ReplayModelCreateGuid createGuid,
     ReplayModelFileAttributes fileAttributes,
     ReplayModelCreateDisposition createDisposition,
     ReplayModelLeaseState leaseState,
     ReplayModelSetReplayFlag isSetReplayFlag,
     ReplayModelLeaseKey leaseKey)
     : base(0)
 {
     this.channel = channel;
     this.switchChannelType = switchChannelType;
     this.channelSequence = channelSequence;
     this.modelDurableHandle = modelDurableHandle;
     this.requestedOplockLevel = requestedOplockLevel;
     this.fileName = fileName;
     this.createGuid = createGuid;
     this.fileAttributes = fileAttributes;
     this.createDisposition = createDisposition;
     this.leaseState = leaseState;
     this.isSetReplayFlag = isSetReplayFlag;
     this.leaseKey = leaseKey;
 }
        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 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 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);
        }