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; }
private void InitializeAlternativeChannel( Guid clientGuid, uint treeId, bool isClientSupportPersistent = true) { Site.Assume.IsNull(smb2ClientAlternativeChannel, "Expect smb2ClientAlternativeChannel is NULL."); testConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL); smb2ClientAlternativeChannel = new Smb2FunctionalClient(testConfig.Timeout, testConfig, Site); smb2ClientAlternativeChannel.Smb2Client.LeaseBreakNotificationReceived += new Action <Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived); smb2ClientAlternativeChannel.Smb2Client.OplockBreakNotificationReceived += new Action <Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnOplockBreakNotificationReceived); smb2ClientAlternativeChannel.ConnectToServer(testConfig.UnderlyingTransport, serverNameMainChannel, serverIpMainChannel); 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; status = smb2ClientAlternativeChannel.Negotiate( new DialectRevision[] { dialectMainChannel }, testConfig.IsSMB1NegotiateEnabled, capabilityValue: ModelUtility.IsSmb3xFamily(dialectMainChannel) ? capability : Capabilities_Values.NONE, clientGuid: dialectMainChannel == DialectRevision.Smb2002 ? Guid.Empty : clientGuid, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }); Site.Assert.AreEqual( dialectMainChannel, negotiateResponse.Value.DialectRevision, "DialectRevision {0} is expected", dialectMainChannel); #endregion #region SESSION_SETUP status = smb2ClientAlternativeChannel.AlternativeChannelSessionSetup( smb2ClientMainChannel, testConfig.DefaultSecurityPackage, principleNameMainChannel, testConfig.AccountCredential, testConfig.UseServerGssToken); Site.Log.Add( LogEntryKind.Debug, "Global encryption disabled"); #endregion }
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."); } }
public static void ReadConfigReturn(SessionMgmtConfig c) { Condition.IsTrue(ConnectionList == null); Condition.IsNotNull(c); Condition.IsTrue(c.MaxSmbVersionSupported == ModelDialectRevision.Smb2002 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb21 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb30 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb302); if (!ModelUtility.IsSmb3xFamily(c.MaxSmbVersionSupported)) { Condition.IsFalse(c.IsMultiChannelCapable); } ConnectionList = new MapContainer <ModelConnectionId, ModelConnection>(); GlobalSessionTable = new MapContainer <ModelSessionId, ModelSession>(); config = c; }
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 FileOperationToBreakLeaseRequestReturn(LeasingConfig c) { Condition.IsTrue(state == ModelState.Connected); ModelFileOperationRequest fileOperationRequest = ModelHelper.RetrieveOutstandingRequest <ModelFileOperationRequest>(ref request); Condition.IsFalse(negotiateDialect == DialectRevision.Smb2002); Condition.IsTrue(config.IsDirectoryLeasingSupported == c.IsDirectoryLeasingSupported); Condition.IsTrue(config.IsLeasingSupported == c.IsLeasingSupported); Condition.IsTrue(c.IsLeasingSupported || c.IsDirectoryLeasingSupported); Condition.IsTrue(config.MaxSmbVersionSupported == c.MaxSmbVersionSupported); // 3.3.1.4 Algorithm for Leasing in an Object Store smb2Lease.BreakToLeaseState = smb2Lease.LeaseState; if (fileOperationRequest.OptorType != OperatorType.SameClientId) { ModelHelper.Log( LogType.Requirement, "3.3.1.4: READ caching permits the SMB2 client to cache data read from the object. Before processing one of the following operations from a client with a different ClientId, " + "the object store MUST request that the server revoke READ caching. The object store is not required to wait for acknowledgment:"); if ((smb2Lease.LeaseState & (uint)LeaseStateValues.SMB2_LEASE_READ_CACHING) != 0 && ((fileOperationRequest.Operation == FileOperation.OPEN_OVERWRITE) || (fileOperationRequest.Operation == FileOperation.WRITE_DATA) || (fileOperationRequest.Operation == FileOperation.SIZE_CHANGED) || (fileOperationRequest.Operation == FileOperation.RANGE_LOCK))) { ModelHelper.Log(LogType.Requirement, "READ caching on a file:"); ModelHelper.Log(LogType.Requirement, "\tThe file is opened in a manner that overwrites the existing file."); ModelHelper.Log(LogType.Requirement, "\tData is written to the file."); ModelHelper.Log(LogType.Requirement, "\tThe file size is changed."); ModelHelper.Log(LogType.Requirement, "\tA byte range lock is requested for the file."); ModelHelper.Log(LogType.TestInfo, "READ caching lease state is broken."); smb2Lease.BreakToLeaseState &= ~(uint)LeaseStateValues.SMB2_LEASE_READ_CACHING; } } if (fileOperationRequest.OptorType != OperatorType.SameClientId) { ModelHelper.Log( LogType.Requirement, "WRITE caching permits the SMB2 client to cache writes and byte-range locks on an object. " + "Before processing one of the following operations, the underlying object store MUST request that the server revoke WRITE caching, " + "and the object store MUST wait for acknowledgment from the server before proceeding with the operation:"); if ((smb2Lease.LeaseState & (uint)LeaseStateValues.SMB2_LEASE_WRITE_CACHING) != 0 && fileOperationRequest.Operation != FileOperation.OPEN_SHARING_VIOLATION && fileOperationRequest.Operation != FileOperation.OPEN_SHARING_VIOLATION_WITH_OVERWRITE && fileOperationRequest.Operation != FileOperation.PARENT_DIR_RENAMED) { ModelHelper.Log( LogType.Requirement, "The file is opened by a local application or via another protocol, " + "or opened via SMB2 without providing the same ClientId, and requested access includes any flags other than FILE_READ_ATTRIBUTES, " + "FILE_WRITE_ATTRIBUTES, and SYNCHRONIZE."); ModelHelper.Log( LogType.TestInfo, "WRITE caching lease state is broken."); smb2Lease.BreakToLeaseState &= ~(uint)LeaseStateValues.SMB2_LEASE_WRITE_CACHING; } ModelHelper.Log( LogType.Requirement, "HANDLE caching permits one or more SMB2 clients to delay closing handles it holds open, " + "or to defer sending opens. Before processing one of the following operations, " + "the underlying object store MUST request that the server revoke HANDLE caching, " + "and the object store MUST wait for acknowledgment before proceeding with the operation:"); if ((smb2Lease.LeaseState & (uint)LeaseStateValues.SMB2_LEASE_HANDLE_CACHING) != 0 && (fileOperationRequest.Operation == FileOperation.OPEN_SHARING_VIOLATION || fileOperationRequest.Operation == FileOperation.OPEN_SHARING_VIOLATION_WITH_OVERWRITE || fileOperationRequest.Operation == FileOperation.RENAMEED || fileOperationRequest.Operation == FileOperation.DELETED || fileOperationRequest.Operation == FileOperation.PARENT_DIR_RENAMED)) { ModelHelper.Log(LogType.Requirement, "HANDLE caching on a file:"); ModelHelper.Log( LogType.Requirement, "\tA file is opened with an access or share mode incompatible with opens from different ClientIds " + "or local applications as described in [MS-FSA] section 2.1.5.1.2."); ModelHelper.Log(LogType.Requirement, "\tThe parent directory is being renamed."); ModelHelper.Log( LogType.TestInfo, "HANDLE caching lease state is broken."); smb2Lease.BreakToLeaseState &= ~(uint)LeaseStateValues.SMB2_LEASE_HANDLE_CACHING; } } // HANDLE caching permits one or more SMB2 clients to delay closing handles it holds open, or to defer sending opens. // Before processing one of the following operations, the underlying object store MUST request that the server revoke HANDLE caching, // and the object store MUST wait for acknowledgment before proceeding with the operation: // The parent directory is being renamed. if ((smb2Lease.LeaseState & (uint)LeaseStateValues.SMB2_LEASE_HANDLE_CACHING) != 0 && fileOperationRequest.Operation == FileOperation.PARENT_DIR_RENAMED) { smb2Lease.BreakToLeaseState &= ~(uint)LeaseStateValues.SMB2_LEASE_HANDLE_CACHING; } if (smb2Lease.BreakToLeaseState != smb2Lease.LeaseState) { if (smb2Lease.LeaseState != (uint)LeaseStateValues.SMB2_LEASE_READ_CACHING) { // 3.3.4.7 Object Store Indicates a Lease Break // The server MUST set Lease.Breaking to TRUE ModelHelper.Log(LogType.TestInfo, "Lease.Breaking is set to TRUE."); smb2Lease.Breaking = true; } // 3.3.4.7 Object Store Indicates a Lease Break if (ModelUtility.IsSmb3xFamily(c.MaxSmbVersionSupported) && smb2Lease.Version == 2) { ModelHelper.Log( LogType.Requirement, "3.3.4.7: If the server implements the SMB 3.x dialect family and Lease.Version is 2, the server MUST set NewEpoch to Lease.Epoch + 1. "); ModelHelper.Log(LogType.TestInfo, "The server implements the SMB 3.x dialect family and Lease.Version is 2."); smb2Lease.Epoch++; } // 3.3.1.4 Algorithm for Leasing in an Object Store // The algorithm SHOULD support the following combinations of caching flags on a file: // No caching, Read caching, Read + Write caching, Read + Handle caching, and Read + Write + Handle caching. if ((smb2Lease.BreakToLeaseState & (uint)LeaseStateValues.SMB2_LEASE_READ_CACHING) == 0) { ModelHelper.Log(LogType.TestInfo, "Lease state is set to No caching."); smb2Lease.BreakToLeaseState = 0; } } }
public static void RequestOplockAndOperateFileReturn(OplockLevel_Values grantedOplockLevel, OplockConfig c) { Condition.IsTrue(State == ModelState.Connected); Condition.IsNotNull(Request); ModelRequestOplockAndTriggerBreakRequest requestOplockAndTriggerBreakRequest = ModelHelper.RetrieveOutstandingRequest <ModelRequestOplockAndTriggerBreakRequest>(ref Request); Condition.IsTrue(Config.Platform == c.Platform); if (Share_ForceLevel2Oplock && (requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH || requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE)) { ModelHelper.Log(LogType.Requirement, "3.3.5.9: If TreeConnect.Share.ForceLevel2Oplock is TRUE, " + "and RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH or SMB2_OPLOCK_LEVEL_EXCLUSIVE, " + "the server SHOULD<245> set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II."); if (Config.Platform != Platform.NonWindows) { ModelHelper.Log(LogType.TestInfo, "The SUT platform is Windows."); Condition.IsTrue(grantedOplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II); // Skip following WBN which is for pre-Win8 // <226> Section 3.3.5.9: Windows Vista and Windows Server 2008 do not support the SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK flag // and ignore the TreeConnect.Share.ForceLevel2Oplock value. } } if (ModelUtility.IsSmb3xFamily(Connection_Dialect) && Share_Type_Include_STYPE_CLUSTER_SOFS && requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH) { 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."); // The Oplock acquisition depends on underlying object store implemention specific // we may not garantee level2 would be always granted // Only assert it's not batch ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); Condition.IsTrue(grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_BATCH); } Open = new ModelOplockOpen(); ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE."); Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to None."); Open.OplockState = OplockState.None; // Acquire Oplock from underlying object // If the underlying object store grants the oplock, // then Open.OplockState is set to Held and Open.OplockLevel is set to the level of the oplock acquired. if (grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE) { ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to Held."); Open.OplockState = OplockState.Held; Open.OplockLevel = grantedOplockLevel; } }
public static void OpenRequest( ClientGuidType clientGuidType, PathNameType pathNameType, CreateType createType, ShareType shareType, AppInstanceIdType appInstanceIdType) { Condition.IsTrue(State == ModelState.Connected); Condition.IsNotNull(Open); // Isolate below params to limite the expanded test cases. Combination.Isolated(clientGuidType == ClientGuidType.SameClientGuid); Combination.Isolated(pathNameType == PathNameType.DifferentPathName); Combination.Isolated(shareType == ShareType.DifferentShareDifferentLocal); Combination.Isolated(shareType == ShareType.DifferentShareSameLocal); Combination.Isolated(appInstanceIdType == AppInstanceIdType.InvalidAppInstanceId); Combination.Isolated(appInstanceIdType == AppInstanceIdType.NoAppInstanceId); // "AppInstanceId is zero" is only applicable for the first Create Request. // For the second Create Request, only valid/notvalid/none make sense. Condition.IsFalse(appInstanceIdType == AppInstanceIdType.AppInstanceIdIsZero); // CreateDurableThenDisconnect is only applicable for the first Create Request. Condition.IsFalse(createType == CreateType.CreateDurableThenDisconnect); // If the client doesn't disconnect from the server after sending the first Create Request, // then the second Create Request does not need to contain reconnect context. // And vice versa. Condition.IfThen(Open.CreateTypeWhenPrepare != CreateType.CreateDurableThenDisconnect, createType != CreateType.ReconnectDurable); Condition.IfThen(Open.CreateTypeWhenPrepare == CreateType.CreateDurableThenDisconnect, createType == CreateType.ReconnectDurable); if (createType == CreateType.ReconnectDurable) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.13: If the create request also includes the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 create context, " + "the server MUST process the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 create context as specified in section 3.3.5.9.12, " + "and this section MUST be skipped."); ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 create context is included."); return; } if (!ModelUtility.IsSmb3xFamily(MaxSmbVersionSupported)) { ModelHelper.Log(LogType.Requirement, "2.2.13.2.13: The SMB2_CREATE_APP_INSTANCE_ID context is valid only for the SMB 3.x dialect family."); ModelHelper.Log(LogType.TestInfo, "The dialect version of the server is {0}.", MaxSmbVersionSupported); return; } if (appInstanceIdType == AppInstanceIdType.ValidAppInstanceId && Open.AppInstanceId != AppInstanceIdType.NoAppInstanceId && pathNameType == PathNameType.SamePathName && shareType == ShareType.SameShare && clientGuidType == ClientGuidType.DifferentClientGuid) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.13: The server MUST attempt to locate an Open in GlobalOpenTable where:"); ModelHelper.Log(LogType.Requirement, "\tAppInstanceId in the request is equal to Open.AppInstanceId."); ModelHelper.Log(LogType.Requirement, "\tTarget path name is equal to Open.PathName."); ModelHelper.Log(LogType.Requirement, "\tOpen.TreeConnect.Share is equal to TreeConnect.Share."); ModelHelper.Log(LogType.Requirement, "\tOpen.Session.Connection.ClientGuid is not equal to the current Connection.ClientGuid."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.Requirement, "If an Open is found, the server MUST calculate the maximal access that the user, " + "identified by Session.SecurityContext, has on the file being opened<277>. " + "If the maximal access includes GENERIC_READ access, the server MUST close the open as specified in 3.3.4.17."); // The user used in this model is administrator, so maximal access always includes GENERIC_READ access. ModelHelper.Log(LogType.TestInfo, "The maximal access includes GENERIC_READ access. So open is closed."); // close open Open = null; } else { ModelHelper.Log(LogType.TestInfo, "appInstanceIdType is {0}.", appInstanceIdType.ToString()); ModelHelper.Log(LogType.TestInfo, "pathNameType is {0}.", pathNameType.ToString()); ModelHelper.Log(LogType.TestInfo, "shareType is {0}.", shareType.ToString()); ModelHelper.Log(LogType.TestInfo, "clientGuidType is {0}.", clientGuidType.ToString()); ModelHelper.Log(LogType.TestInfo, "All the above conditions do not match the requirement, so open will not be closed."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); } }
private static void HandleGssApiAuth(ModelSmb2Status status, ModelSessionSetupRequest sessionSetupRequest) { ModelHelper.Log(LogType.Requirement, "3.3.5.5.3: 1. The status code in the SMB2 header of the response MUST be set to STATUS_SUCCESS. "); if (status != ModelSmb2Status.STATUS_SUCCESS) { return; } if (ModelUtility.IsSmb3xFamily(ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect)) { ModelHelper.Log(LogType.Requirement, "If Connection.Dialect belongs to the SMB 3.x dialect family, the server MUST insert the Session into Connection.SessionTable. "); ModelHelper.Log(LogType.TestInfo, "Connection.Dialect is {0}", ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect); ConnectionList[sessionSetupRequest.connectionId].Session = GlobalSessionTable[sessionSetupRequest.sessionId]; } ModelHelper.Log(LogType.Requirement, "If Session.IsAnonymous is FALSE, the server MUST set Connection.ConstrainedConnection to FALSE."); ModelHelper.Log(LogType.TestInfo, "Session.IsAnonymous is FALSE, so set Connection.ConstrainedConnection to FALSE"); ConnectionList[sessionSetupRequest.connectionId].ConstrainedConnection = false; /* * Assuming STATUS_SUCCESS indicates final message in the authentication exchange * * Skip following requirement according to assumption 6. * If the returned anon_state is TRUE, the server MUST set Session.IsAnonymous to TRUE and the server MAY set * the SMB2_SESSION_FLAG_IS_NULL flag in the SessionFlags field of the SMB2 SESSION_SETUP Response. * Otherwise, if the returned src_name corresponds to an implementation-specific guest user,<211> * the server MUST set the SMB2_SESSION_FLAG_IS_GUEST in the SessionFlags field of the SMB2 SESSION_SETUP Response * and MUST set Session.IsGuest to TRUE. */ if (sessionSetupRequest.previousSessionId != ModelSessionId.ZeroSessionId) { ModelHelper.Log(LogType.Requirement, "12. If the PreviousSessionId field of the request is not equal to zero, the server MUST take the following actions:"); ModelHelper.Log(LogType.TestInfo, "PreviousSessionId is not equal to zero."); ModelHelper.Log(LogType.Requirement, "1. The server MUST look up the old session in GlobalSessionTable, where Session.SessionId matches PreviousSessionId. "); if (GlobalSessionTable.ContainsKey(sessionSetupRequest.previousSessionId)) { ModelHelper.Log(LogType.Requirement, "If a session is found with Session.SessionId equal to PreviousSessionId, " + "the server MUST determine if the old session and the newly established session are created by the same user " + "by comparing the user identifiers obtained from the Session.SecurityContext on the new and old session."); ModelHelper.Log(LogType.TestInfo, "There is a session with Session.SessionId equal to PreviousSessionId."); if (sessionSetupRequest.previousSessionId == sessionSetupRequest.sessionId) { ModelHelper.Log(LogType.Requirement, "1. If the PreviousSessionId and SessionId values in the SMB2 header of the request are equal, " + "the server SHOULD<230> ignore PreviousSessionId and no other processing is required."); ModelHelper.Log(LogType.TestInfo, "PreviousSessionId is equal to SessionId."); // Do nothing } else if (sessionSetupRequest.user == ModelUser.DefaultUser) { ModelHelper.Log(LogType.Requirement, "2. Otherwise, if the server determines the authentications were for the same user, " + "the server MUST remove the old session from the GlobalSessionTable and also from the Connection.SessionTable, as specified in section 3.3.7.1."); ModelHelper.Log(LogType.TestInfo, "The authentications were for the same user"); GlobalSessionTable.Remove(sessionSetupRequest.previousSessionId); } } } ModelHelper.Log(LogType.Requirement, "13. Session.State MUST be set to Valid."); // Update both GlobalSessionTable and ConnectionList GlobalSessionTable[sessionSetupRequest.sessionId].State = ModelSessionState.Valid; ConnectionList[sessionSetupRequest.connectionId].Session.State = ModelSessionState.Valid; }
public static void SessionSetupResponse(ModelSmb2Status status, ModelConnectionId connectionId, SessionMgmtConfig c) { VerifyConnection(connectionId); Condition.IsNotNull(ConnectionList[connectionId].Request); Condition.IsTrue(config.Platform == c.Platform); Condition.IsTrue(config.IsMultiChannelCapable == c.IsMultiChannelCapable); ModelSessionSetupRequest sessionSetupRequest = RetrieveOutstandingRequest <ModelSessionSetupRequest>(connectionId); if (sessionSetupRequest.isSigned) { ModelHelper.Log(LogType.Requirement, "3.3.5.2.4: If the SMB2 header of the request has SMB2_FLAGS_SIGNED set in the Flags field, the server MUST verify the signature."); ModelHelper.Log(LogType.TestInfo, "SMB2_FLAGS_SIGNED is set in the SMB2 header of the SessionSetup Request."); // If server does not support Multiple channel then whether binding is set is meaningless. if (config.IsMultiChannelCapable && sessionSetupRequest.flags == ModelFlags.Binding) { ModelHelper.Log(LogType.Requirement, "If the request is for binding the session, the server MUST look up the session in the GlobalSessionTable using the SessionId in the SMB2 header of the request. "); ModelHelper.Log(LogType.TestInfo, "SMB2_SESSION_FLAG_BINDING bit is set."); if (!GlobalSessionTable.ContainsKey(sessionSetupRequest.sessionId)) { ModelHelper.Log(LogType.Requirement, "If the session is not found, the request MUST be failed, as specified in section Sending an Error Response (section 3.3.4.4), " + "with the error code STATUS_USER_SESSION_DELETED. "); ModelHelper.Log(LogType.TestInfo, "The session is not found in GlobalSessionTable."); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); Condition.IsTrue(status == ModelSmb2Status.STATUS_USER_SESSION_DELETED); return; } } else { ModelHelper.Log(LogType.Requirement, "For all other requests, the server MUST look up the session in the Connection.SessionTable using the SessionId in the SMB2 header of the request."); ModelHelper.Log(LogType.TestInfo, "SMB2_SESSION_FLAG_BINDING bit is not set."); if (ConnectionList[connectionId].Session == null || ConnectionList[connectionId].Session.SessionId != sessionSetupRequest.sessionId) { ModelHelper.Log(LogType.Requirement, "If the session is not found, the request MUST be failed, as specified in section Sending an Error Response (section 3.3.4.4), " + "with the error code STATUS_USER_SESSION_DELETED. "); ModelHelper.Log(LogType.TestInfo, "The session is not found in Connection.SessionTable."); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); Condition.IsTrue(status == ModelSmb2Status.STATUS_USER_SESSION_DELETED); return; } } } if (sessionSetupRequest.sessionId == ModelSessionId.ZeroSessionId) { ModelHelper.Log(LogType.Requirement, "3.3.5.5: 3. If SessionId in the SMB2 header of the request is zero, the server MUST process the authentication request as specified in section 3.3.5.5.1."); ModelHelper.Log(LogType.TestInfo, "The SessionId of the SessionSetup Request is zero"); AuthNewSession(status, sessionSetupRequest); Condition.IsTrue(status == ModelSmb2Status.STATUS_SUCCESS || status == ModelSmb2Status.STATUS_MORE_PROCESSING_REQUIRED); return; } if (ModelUtility.IsSmb3xFamily(ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect) && config.IsMultiChannelCapable && sessionSetupRequest.flags == ModelFlags.Binding) { ModelHelper.Log(LogType.Requirement, "3.3.5.5: 4. If Connection.Dialect belongs to the SMB 3.x dialect family, IsMultiChannelCapable is TRUE," + "and the SMB2_SESSION_FLAG_BINDING bit is set in the Flags field of the request, the server MUST perform the following:" + "The server MUST look up the session in GlobalSessionTable using the SessionId from the SMB2 header."); ModelHelper.Log(LogType.TestInfo, "Connection.Dialect is {0}, IsMultiChannelCapable is TRUE, and the SMB2_SESSION_FLAG_BINDING bit is set", ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect); if (!GlobalSessionTable.ContainsKey(sessionSetupRequest.sessionId)) { ModelHelper.Log(LogType.Requirement, "If the session is not found, the server MUST fail the session setup request with STATUS_USER_SESSION_DELETED."); ModelHelper.Log(LogType.TestInfo, "The SessionId cannot be found in GlobalSessionTable"); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); Condition.IsTrue(status == ModelSmb2Status.STATUS_USER_SESSION_DELETED); return; } ModelHelper.Log(LogType.Requirement, "If a session is found, the server MUST do the following:"); if (ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect != GlobalSessionTable[sessionSetupRequest.sessionId].Dialect) { ModelHelper.Log(LogType.Requirement, "If Connection.Dialect is not the same as Session.Connection.Dialect, the server MUST fail the request with STATUS_INVALID_PARAMETER."); ModelHelper.Log(LogType.TestInfo, "The Connection.Dialect is {0}, Session.Connection.Dialect is {1}", ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect, GlobalSessionTable[sessionSetupRequest.sessionId].Dialect); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); return; } if (!sessionSetupRequest.isSigned) { ModelHelper.Log(LogType.Requirement, "If the SMB2_FLAGS_SIGNED bit is not set in the Flags field in the header, the server MUST fail the request with error STATUS_INVALID_PARAMETER."); ModelHelper.Log(LogType.TestInfo, "The SMB2_FLAGS_SIGNED bit is not set in the SessionSetup Request"); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); return; } if (GlobalSessionTable[sessionSetupRequest.sessionId].State == ModelSessionState.InProgress) { ModelHelper.Log(LogType.Requirement, "If Session.State is InProgress, the server MUST fail the request with STATUS_REQUEST_NOT_ACCEPTED."); ModelHelper.Log(LogType.TestInfo, "Session.State is InProgress"); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_REQUEST_NOT_ACCEPTED); return; } // If Session.IsAnonymousor Session.IsGuestis TRUE, the server MUST fail the request with STATUS_NOT_SUPPORTED. // Skip above requirement according to assumption 6. if (ConnectionList[sessionSetupRequest.connectionId].Session != null && ConnectionList[sessionSetupRequest.connectionId].Session.SessionId == sessionSetupRequest.sessionId) { ModelHelper.Log(LogType.Requirement, "If there is a session in Connection.SessionTable identified by the SessionId in the request, the server MUST fail the request with STATUS_REQUEST_NOT_ACCEPTED."); ModelHelper.Log(LogType.TestInfo, "There is a session in Connection.SessionTable which has a same SessionId in the request"); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_REQUEST_NOT_ACCEPTED); return; } // The server MUST verify the signature as specified in section 3.3.5.2.4, using the Session.SessionKey. // Skip above requirement as it is verified in signing model if (sessionSetupRequest.user == ModelUser.DiffUser) { ModelHelper.Log(LogType.Requirement, "The server MUST obtain the security context from the GSS authentication subsystem, " + "and it MUST invoke the GSS_Inquire_context call as specified in [RFC2743] section 2.2.6, " + "passing the security context as the input parameter." + "If the returned \"src_name\" does not match with the Session.Username, the server MUST fail the request with error code STATUS_NOT_SUPPORTED."); ModelHelper.Log(LogType.TestInfo, "A different user is used when binding to an existing session"); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_NOT_SUPPORTED); return; } } else { if (config.Platform == Platform.WindowsServer2012 && sessionSetupRequest.flags == ModelFlags.Binding) { ModelHelper.Log(LogType.Requirement, "<232> Section 3.3.5.5: Windows 8 and Windows Server 2012 look up the session in GlobalSessionTable using the SessionId from the SMB2 header " + "if the SMB2_SESSION_FLAG_BINDING bit is set in the Flags field of the request. "); ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}. The SMB2_SESSION_FLAG_BINDING bit is set.", config.Platform); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); if (GlobalSessionTable.ContainsKey(sessionSetupRequest.sessionId)) { ModelHelper.Log(LogType.Requirement, "If the session is found, the server fails the request with STATUS_REQUEST_NOT_ACCEPTED. "); ModelHelper.Log(LogType.TestInfo, "The session is found"); Condition.IsTrue(status == ModelSmb2Status.STATUS_REQUEST_NOT_ACCEPTED); return; } else { ModelHelper.Log(LogType.Requirement, "If the session is not found, the server fails the request with STATUS_USER_SESSION_DELETED."); ModelHelper.Log(LogType.TestInfo, "The session is not found"); Condition.IsTrue(status == ModelSmb2Status.STATUS_USER_SESSION_DELETED); return; } } if (ModelUtility.IsSmb3xFamily(config.MaxSmbVersionSupported) && ((ModelUtility.IsSmb2Family(ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect) || !config.IsMultiChannelCapable)) && sessionSetupRequest.flags == ModelFlags.Binding) { ModelHelper.Log(LogType.Requirement, "3.3.5.5: Otherwise, if the server implements the SMB 3.x dialect family, " + "and Connection.Dialect is equal to \"2.002\" or \"2.100\" or IsMultiChannelCapable is FALSE, " + "and SMB2_SESSION_FLAG_BINDING bit is set in the Flags field of the request, " + "the server SHOULD<225> fail the session setup request with STATUS_REQUEST_NOT_ACCEPTED."); ModelHelper.Log(LogType.TestInfo, "Connection.Dialect is {0}, IsMultiChannelCapable is {1}, SUT platform is {2}, Max Smb version supported is {3} and SMB2_SESSION_FLAG_BINDING bit is set.", ConnectionList[sessionSetupRequest.connectionId].NegotiateDialect, config.IsMultiChannelCapable, config.Platform, config.MaxSmbVersionSupported); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); if (config.Platform != Platform.NonWindows) { Condition.IsTrue(status == ModelSmb2Status.STATUS_REQUEST_NOT_ACCEPTED); } else { ModelHelper.Log(LogType.TestInfo, "The SUT platform is NonWindows, so the server could fail the request with other error code."); Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS); } return; } else { if (ConnectionList[sessionSetupRequest.connectionId].Session == null || ConnectionList[sessionSetupRequest.connectionId].Session.SessionId != sessionSetupRequest.sessionId) { ModelHelper.Log(LogType.Requirement, "3.3.5.5: Otherwise, the server MUST look up the session in Connection.SessionTable using the SessionId from the SMB2 header." + "If the session is not found, the server MUST fail the session setup request with STATUS_USER_SESSION_DELETED. "); ModelHelper.Log(LogType.TestInfo, "The session is not found using the SessionId of the request"); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_USER_SESSION_DELETED); return; } } } if (GlobalSessionTable[sessionSetupRequest.sessionId].State == ModelSessionState.Valid) { ModelHelper.Log(LogType.Requirement, "3.3.5.5: 6. If Session.State is Valid, the server SHOULD process the session setup request as specified in section 3.3.5.5.2."); ModelHelper.Log(LogType.TestInfo, "Session.State is Valid"); if (config.Platform == Platform.WindowsServer2008) { ModelHelper.Log(LogType.Requirement, "Footnote: Windows Vista SP1 and Windows Server 2008 servers fail the session setup request with STATUS_REQUEST_NOT_ACCEPTED."); ModelHelper.Log(LogType.TestInfo, "The SUT platform is Windows Server 2008"); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_REQUEST_NOT_ACCEPTED); return; } if (config.Platform != Platform.NonWindows) { ModelHelper.Log(LogType.TestInfo, "The SUT platform is Windows"); ReAuthentication(status, sessionSetupRequest); Condition.IsTrue(status == ModelSmb2Status.STATUS_SUCCESS || status == ModelSmb2Status.STATUS_MORE_PROCESSING_REQUIRED); return; } } ModelHelper.Log(LogType.Requirement, "3.3.5.5: 7. The server MUST continue processing the request as specified in section 3.3.5.5.3."); HandleGssApiAuth(status, sessionSetupRequest); ModelHelper.Log(LogType.TestInfo, "The authentication should succeed."); Condition.IsTrue(status == ModelSmb2Status.STATUS_SUCCESS || status == ModelSmb2Status.STATUS_MORE_PROCESSING_REQUIRED); }
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 }
public void SessionSetupRequest( ModelConnectionId connectionId, ModelSessionId sessionId, ModelSessionId previousSessionId, ModelSigned signed, ModelFlags flags, ModelUser user, ModelAllowReauthentication ReAuthentication) { ulong adapterSessionId; ulong adapterPreviousSessionId; Packet_Header_Flags_Values headerFlags; SESSION_SETUP_Request_Flags sessionSetupFlags; AccountCredential credential; #region sessionId if (sessionTable.ContainsKey(sessionId)) { adapterSessionId = sessionTable[sessionId]; // For sessionId is 0 which indicates session creation // assign a new one if (sessionId == ModelSessionId.ZeroSessionId) { if (!sessionTable.ContainsKey(ModelSessionId.MainSessionId)) { sessionId = ModelSessionId.MainSessionId; } else if (!sessionTable.ContainsKey(ModelSessionId.AlternativeSessionId)) { sessionId = ModelSessionId.AlternativeSessionId; } } } else { Random r = new Random(); adapterSessionId = (ulong)r.Next(1, int.MaxValue); } Site.Log.Add( LogEntryKind.Debug, "ModelSessionId: {0}, AdapterSessionId: 0x{1:x8}", sessionId, adapterSessionId); #endregion #region previousSessionId if (sessionTable.ContainsKey(previousSessionId)) { adapterPreviousSessionId = sessionTable[previousSessionId]; } else { Random r = new Random(); adapterPreviousSessionId = (ulong)r.Next(1, int.MaxValue); } Site.Log.Add( LogEntryKind.Debug, "ModelSessionId: {0}, adapterPreviousSessionId: 0x{1:x8}", sessionId, adapterPreviousSessionId); #endregion #region isSigned headerFlags = (signed == ModelSigned.SignFlagSet) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE; #endregion #region flags switch (flags) { case ModelFlags.Binding: { sessionSetupFlags = SESSION_SETUP_Request_Flags.SESSION_FLAG_BINDING; break; } case ModelFlags.NotBinding: { sessionSetupFlags = SESSION_SETUP_Request_Flags.NONE; break; } default: throw new ArgumentException("flags"); } #endregion #region user switch (user) { case ModelUser.DefaultUser: { credential = testConfig.AccountCredential; break; } case ModelUser.DiffUser: { credential = testConfig.NonAdminAccountCredential; break; } default: throw new ArgumentException("user"); } #endregion #region MultipleChannel // Multiple Channel only takes affect when Connection.Dialect belongs to the SMB 3.x dialect family bool isMultipleChannelSupported = sessionMgmtConfig.IsMultiChannelCapable && ModelUtility.IsSmb3xFamily(connectionList[connectionId].Dialect); #endregion PrintCurrentSessionTable("Before SessionSetup Request"); #region Send Request uint status; SESSION_SETUP_Response?sessionSetupResponse = null; string serverName = testConfig.SutComputerName; SecurityPackageType securityPackageType = testConfig.DefaultSecurityPackage; bool useServerGssToken = testConfig.UseServerGssToken; // Use desired explored sessionId ulong oldSessionId = connectionList[connectionId].SessionId; connectionList[connectionId].SessionId = adapterSessionId; // alternative connection and never session setup if (connectionId == ModelConnectionId.AlternativeConnection && sessionId == ModelSessionId.MainSessionId && connectionList[connectionId].SessionKey == null && connectionList.ContainsKey(ModelConnectionId.MainConnection)) { connectionList[connectionId].GenerateCryptoKeys(testConfig.SendSignedRequest, false, connectionList[ModelConnectionId.MainConnection], true); } status = connectionList[connectionId].SessionSetup( headerFlags, sessionSetupFlags, adapterPreviousSessionId, securityPackageType, serverName, credential, useServerGssToken, isMultipleChannelSupported, (header, response) => { sessionSetupResponse = response; }); if (status != Smb2Status.STATUS_SUCCESS && status != Smb2Status.STATUS_MORE_PROCESSING_REQUIRED) { // Restore original sessionId if request failed connectionList[connectionId].SessionId = oldSessionId; } #endregion // Insert session to session table if (!sessionTable.ContainsKey(sessionId) && (status == Smb2Status.STATUS_SUCCESS || status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED)) { sessionTable.Add(sessionId, connectionList[connectionId].SessionId); } PrintCurrentSessionTable("After SessionSetup Request"); SessionSetupResponse((ModelSmb2Status)status, connectionId, sessionMgmtConfig); }
public static void SessionSetupResponse(ModelSmb2Status status, SessionEncryptDataType sessionEncryptDataType, EncryptionConfig c) { Condition.IsTrue(state == ModelState.Connected); Condition.IsTrue(config.IsGlobalEncryptDataEnabled == c.IsGlobalEncryptDataEnabled); Condition.IsTrue(config.IsGlobalRejectUnencryptedAccessEnabled == c.IsGlobalRejectUnencryptedAccessEnabled); if (ModelUtility.IsSmb3xFamily(config.MaxSmbVersionSupported) && !Smb2Utility.IsSmb3xFamily(negotiateDialect) && config.IsGlobalEncryptDataEnabled && config.IsGlobalRejectUnencryptedAccessEnabled) { ModelHelper.Log(LogType.Requirement, "3.3.5.5: 1. If the server implements the SMB 3.x dialect family, " + "Connection.Dialect does not belong to the SMB 3.x dialect family, EncryptData is TRUE, " + "and RejectUnencryptedAccess is TRUE, the server MUST fail the request with STATUS_ACCESS_DENIED."); ModelHelper.Log(LogType.TestInfo, "The server implements {0}, Connection.Dialect is {1}, EncryptData is TRUE and RejectUnencryptedAccess is TRUE", config.MaxSmbVersionSupported, negotiateDialect); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_ACCESS_DENIED); return; } if (Smb2Utility.IsSmb3xFamily(negotiateDialect) && config.IsGlobalEncryptDataEnabled && config.IsGlobalRejectUnencryptedAccessEnabled && !Connection_ClientCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION) { ModelHelper.Log(LogType.Requirement, "3.3.5.5: 2. If Connection.Dialect belongs to the SMB 3.x dialect family, " + "EncryptData is TRUE, RejectUnencryptedAccess is TRUE, " + "and Connection.ClientCapabilities does not include the SMB2_GLOBAL_CAP_ENCRYPTION bit, " + "the server MUST fail the request with STATUS_ACCESS_DENIED."); ModelHelper.Log(LogType.TestInfo, "Connection.Dialect is {0}, EncryptData is TRUE, RejectUnencryptedAccess is TRUE, " + "and Connection.ClientCapabilities does not include the SMB2_GLOBAL_CAP_ENCRYPTION bit.", negotiateDialect); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_ACCESS_DENIED); return; } if (Smb2Utility.IsSmb3xFamily(negotiateDialect) && config.IsGlobalEncryptDataEnabled && (Connection_ServerCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION || config.IsGlobalRejectUnencryptedAccessEnabled)) { ModelHelper.Log(LogType.Requirement, "3.3.5.5.3: 10. If global EncryptData is TRUE, the server MUST do the following: " + "If Connection.ServerCapabilities includes SMB2_GLOBAL_CAP_ENCRYPTION or RejectUnencryptedAccess is TRUE,"); Condition.IsTrue(sessionEncryptDataType == SessionEncryptDataType.SessionEncryptDataSet); Session_EncryptData = SessionEncryptDataType.SessionEncryptDataSet; } Condition.IsTrue(status == Smb2Status.STATUS_SUCCESS); Session_IsExisted = true; }
public void SetupConnection(ModelDialectRevision clientMaxDialect) { testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); testClient.RequestSent += new Action <Packet_Header>(PrintSequenceWindow); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); uint status; NEGOTIATE_Response?negotiateResponse = null; status = testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_LARGE_MTU, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); // The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE. Site.Assert.IsTrue( header.CreditRequestResponse >= 1, "The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE"); negotiateResponse = response; }); Site.Log.Add( LogEntryKind.Debug, "The maximum size, in bytes, of Length in READ/WRITE that server will accept on the connection is {0}", testClient.MaxBufferSize); Site.Assert.AreEqual( ModelUtility.GetDialectRevision(clientMaxDialect), negotiateResponse.Value.DialectRevision, "DialectRevision {0} is expected", ModelUtility.GetDialectRevision(clientMaxDialect)); negotiateDialect = negotiateResponse.Value.DialectRevision; if ((negotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(negotiateDialect)) // In case server does not support multicredit even implement Smb21 or Smb30 && testConfig.IsMultiCreditSupported) { isMultiCreditSupportedOnConnection = true; } else { isMultiCreditSupportedOnConnection = false; } status = testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); status = testClient.TreeConnect( uncSharePath, out treeId); Smb2CreateContextResponse[] serverCreateContexts; fileName = GetTestFileName(uncSharePath); status = testClient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); }
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 "); } }); }
private static bool VerifyTreeConnect(ModelSmb2Status status, ModelRequestType modelRequestType, EncryptionConfig c) { ModelHelper.Log(LogType.Requirement, "3.3.5.2.11 Verifying the Tree Connect"); if (Encryption_TreeId == EncryptionTreeId.NoTreeId) { ModelHelper.Log(LogType.Requirement, "The server MUST look up the TreeConnect in Session.TreeConnectTable by using the TreeId in the SMB2 header of the request. " + "If no tree connect is found, the request MUST be failed with STATUS_NETWORK_NAME_DELETED."); ModelHelper.Log(LogType.TestInfo, "No tree connect is found."); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); Condition.IsTrue(status == ModelSmb2Status.STATUS_NETWORK_NAME_DELETED); return(false); } if (ModelUtility.IsSmb3xFamily(config.MaxSmbVersionSupported)) { ModelHelper.Log(LogType.Requirement, "If the server implements the SMB 3.x dialect family, it MUST return STATUS_ACCESS_DENIED for the following cases:"); ModelHelper.Log(LogType.TestInfo, "The server implements {0}.", config.MaxSmbVersionSupported); if (Encryption_TreeId == EncryptionTreeId.TreeIdToEncryptShare && config.IsGlobalRejectUnencryptedAccessEnabled && modelRequestType == ModelRequestType.UnEncryptedRequest) { ModelHelper.Log(LogType.Requirement, "\tIf TreeConnect.Share.EncryptData is TRUE, RejectUnencryptedAccess is TRUE, and Request.IsEncrypted is FALSE."); ModelHelper.Log(LogType.TestInfo, "The above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_ACCESS_DENIED); return(false); } else if (config.IsGlobalEncryptDataEnabled && config.IsGlobalRejectUnencryptedAccessEnabled && modelRequestType == ModelRequestType.UnEncryptedRequest) { ModelHelper.Log(LogType.Requirement, "\tIf EncryptData is TRUE, RejectUnencryptedAccess is TRUE, and Request.IsEncrypted is FALSE."); ModelHelper.Log(LogType.TestInfo, "The above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_ACCESS_DENIED); return(false); } } if (ModelUtility.IsSmb3xFamily(config.MaxSmbVersionSupported) && (config.IsGlobalEncryptDataEnabled || Encryption_TreeId == EncryptionTreeId.TreeIdToEncryptShare || modelRequestType == ModelRequestType.EncryptedRequest) && config.IsGlobalRejectUnencryptedAccessEnabled && !Connection_ServerCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION) { ModelHelper.Log(LogType.Requirement, "If the server implements the SMB 3.x dialect family, EncryptData or TreeConnect.Share.EncryptData or Request.IsEncrypted is TRUE, " + "RejectUnencryptedAccess is TRUE, and Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_ENCRYPTION, " + "the server SHOULD fail the request with STATUS_ACCESS_DENIED."); Condition.IsTrue(config.Platform == c.Platform); ModelHelper.Log(LogType.TestInfo, "The server implements {0}, EncryptData is {1}, TreeConnect.Share.EncryptData is {2}, " + "Request.IsEncrypted is {3}, RejectUnencryptedAccess is TRUE, " + "and Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_ENCRYPTION.", config.MaxSmbVersionSupported, config.IsGlobalEncryptDataEnabled, Encryption_TreeId == EncryptionTreeId.TreeIdToEncryptShare ? "TRUE" : "FALSE", modelRequestType == ModelRequestType.EncryptedRequest ? "TRUE" : "FALSE"); ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}.", config.Platform); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); if (config.Platform == Platform.NonWindows) { Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS); } else { Condition.IsTrue(status == ModelSmb2Status.STATUS_ACCESS_DENIED); } return(false); } return(true); }
public static void NegotiateResponse(ModelSmb2Status status, DialectRevision dialectRevision) { Condition.IsTrue(State == ModelState.Connected); Condition.IsTrue(Request is ModelComNegotiateRequest || Request is NegotiateRequest); // Avoid "Microsoft.SpecExplorer.Runtime.Testing.UnboundVariableException: Variable's value cannot be read before it is bound" Condition.IsTrue(dialectRevision == DialectRevision.Smb2002 || dialectRevision == DialectRevision.Smb21 || dialectRevision == DialectRevision.Smb30 || dialectRevision == DialectRevision.Smb302 || dialectRevision == DialectRevision.Smb2Wildcard || dialectRevision == DialectRevision.Smb2Unknown); if (Request is ModelComNegotiateRequest) { ModelComNegotiateRequest comNegotiateReq = ModelHelper.RetrieveOutstandingRequest <ModelComNegotiateRequest>(ref Request); if (Config.MaxSmbVersionSupported != DialectRevision.Smb21 && !ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported)) { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the server does not implement the SMB 2.1 or 3.x dialect family, processing MUST continue as specified in 3.3.5.3.2."); ComNegotiateHandleSmb2002InResponse(dialectRevision); } else { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: Otherwise, the server MUST scan the dialects provided for the dialect string \"SMB 2.???\"."); if (comNegotiateReq.Dialects.Contains(SMBDialects.SMB_2_X)) { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the string is present, the server MUST respond with an SMB2 NEGOTIATE Response as specified in 2.2.4."); ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: DialectRevision MUST be set to 0x02FF"); NegotiateDialect = DialectRevision.Smb2Wildcard; ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: Connection.NegotiateDialect MUST be set to 0x02FF, and the response is sent to the client"); Condition.IsTrue(dialectRevision == DialectRevision.Smb2Wildcard); } else { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the string is not present, continue to section 3.3.5.3.2"); ComNegotiateHandleSmb2002InResponse(dialectRevision); } } } else { NegotiateRequest negotiateReq = ModelHelper.RetrieveOutstandingRequest <NegotiateRequest>(ref Request); if (negotiateReq.Dialects.Count == 0) { ModelHelper.Log( LogType.Requirement, "3.3.5.4: If the DialectCount of the SMB2 NEGOTIATE Request is 0, the server MUST fail the request with STATUS_INVALID_PARAMETER"); ModelHelper.Log( LogType.TestInfo, "DialectCount of the SMB2 NEGOTIATE Request is 0"); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); return; } ModelHelper.Log( LogType.Requirement, "3.3.5.4: The server MUST select the greatest common dialect between the dialects it implements and the Dialects array of the SMB2 NEGOTIATE request"); DialectRevision commonDialect = SelectCommonDialect(negotiateReq.Dialects); ModelHelper.Log( LogType.TestInfo, "Common dialect is {0}", commonDialect); if (commonDialect == DialectRevision.Smb2Unknown) { ModelHelper.Log( LogType.Requirement, "3.3.5.4: If a common dialect is not found, the server MUST fail the request with STATUS_NOT_SUPPORTED"); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_NOT_SUPPORTED); return; } ModelHelper.Log( LogType.Requirement, "3.3.5.4: If a common dialect is found, the server MUST set Connection.Dialect to \"2.002\", \"2.100\", \"3.000\", or \"3.002\"," + " and Connection.NegotiateDialect to 0x0202, 0x0210, 0x0300, or 0x0302 accordingly, to reflect the dialect selected"); NegotiateDialect = commonDialect; ModelHelper.Log( LogType.TestInfo, "Connection.Dialect is set to {0}", NegotiateDialect); ModelHelper.Log( LogType.Requirement, "3.3.5.4: The server MUST then construct an SMB2 NEGOTIATE Response, as specified in section 2.2.4, with the following specific values, and return STATUS_SUCCESS to the client."); ModelHelper.Log( LogType.Requirement, "\tDialectRevision MUST be set to the common dialect"); Condition.IsTrue(dialectRevision == commonDialect); } Condition.IsTrue(status == Smb2Status.STATUS_SUCCESS); }
public static void ComNegotiateRequest(Sequence <string> dialects) { Condition.IsTrue(State == ModelState.Connected); Condition.IsNull(Request); Request = new ModelComNegotiateRequest(dialects); if (MessageId > 0) { // Negotiate request is always expected to be the first message in a connection State = ModelState.Disconnected; return; } ModelHelper.Log( LogType.Requirement, "3.3.5.3: This request is defined in [MS-SMB] section 2.2.4.5.1, with the SMB header defined in section 2.2.3.1." + " If the request matches the format described there, and Connection.NegotiateDialect is 0xFFFF, processing MUST continue as specified in 3.3.5.3.1."); if (NegotiateDialect != DialectRevision.Smb2Unknown) //|| (!dialects.Contains(SMBDialects.SMB_2_002) && !dialects.Contains(SMBDialects.SMB_2_X))) // TODO: more comments? { ModelHelper.Log( LogType.Requirement, "3.3.5.3: Otherwise, the server MUST disconnect the connection, as specified in section 3.3.7.1, without sending a response."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); State = ModelState.Disconnected; return; } if (!(Config.MaxSmbVersionSupported == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported))) { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the server does not implement the SMB 2.1 or 3.x dialect family, processing MUST continue as specified in 3.3.5.3.2."); ComNegotiateHandleSmb2002InRequest(dialects); } else { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: Otherwise, the server MUST scan the dialects provided for the dialect string \"SMB 2.???\"."); if (!dialects.Contains(SMBDialects.SMB_2_X)) { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the string is not present, continue to section 3.3.5.3.2."); ComNegotiateHandleSmb2002InRequest(dialects); } else { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the string is present, the server MUST respond with an SMB2 NEGOTIATE Response as specified in 2.2.4"); ModelHelper.Log( LogType.TestInfo, "\"SMB 2.???\" is present in the dialects provided"); } } // After every successful call, messageId MUST be incremented by 1. // But in this model it is set to 1 to avoid to generate duplicate cases which only have different messageId. MessageId = 1; }
public static void TreeConnectResponse( ModelSmb2Status status, ShareEncryptDataType shareEncryptDataType, ModelResponseType modelResponseType, EncryptionConfig c) { Condition.IsTrue(state == ModelState.Connected); Condition.IsTrue(config.IsGlobalRejectUnencryptedAccessEnabled == c.IsGlobalRejectUnencryptedAccessEnabled); Condition.IsTrue(Session_IsExisted); ModelTreeConnectRequest treeConnectRequest = ModelHelper.RetrieveOutstandingRequest <ModelTreeConnectRequest>(ref request); if (!VerifySession(status, treeConnectRequest.modelRequestType, c)) { return; } if (ModelUtility.IsSmb3xFamily(config.MaxSmbVersionSupported) && (config.IsGlobalEncryptDataEnabled || treeConnectRequest.connectToShareType == ConnectToShareType.ConnectToEncryptedShare) && config.IsGlobalRejectUnencryptedAccessEnabled && !Connection_ServerCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION) { ModelHelper.Log(LogType.Requirement, "3.3.5.7: If the server implements the SMB 3.x dialect family, EncryptData or Share.EncryptData is TRUE, " + "RejectUnencryptedAccess is TRUE, and Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_ENCRYPTION, " + "the server MUST fail the request with STATUS_ACCESS_DENIED."); Condition.IsTrue(config.Platform == c.Platform); ModelHelper.Log(LogType.TestInfo, "The server implements {0}, EncryptData is {1}, Share.EncryptData is {2}, RejectUnencryptedAccess is TRUE, " + "Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_ENCRYPTION.", config.MaxSmbVersionSupported, config.IsGlobalEncryptDataEnabled, treeConnectRequest.connectToShareType == ConnectToShareType.ConnectToEncryptedShare ? "TRUE" : "FALSE"); ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}.", config.Platform); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_ACCESS_DENIED); return; } if (Smb2Utility.IsSmb3xFamily(negotiateDialect) && treeConnectRequest.connectToShareType == ConnectToShareType.ConnectToEncryptedShare && config.IsGlobalRejectUnencryptedAccessEnabled && !Connection_ServerCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION) { ModelHelper.Log(LogType.Requirement, "3.3.5.7: If Connection.Dialect belongs to the SMB 3.x dialect family, " + "Share.EncryptData is TRUE, RejectUnencryptedAccess is TRUE, " + "and Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_ENCRYPTION, " + "the server MUST fail the request with STATUS_ACCESS_DENIED."); ModelHelper.Log(LogType.Requirement, "\tSet the SMB2_SHAREFLAG_ENCRYPT_DATA bit."); ModelHelper.Log(LogType.TestInfo, "Connection.Dialect is {0}, and Share.EncryptData is TRUE.", negotiateDialect); Condition.IsTrue(shareEncryptDataType == ShareEncryptDataType.ShareEncryptDataSet); } //TODO: To be implemented after TRANSFORM_HEADER added into Smb2FunctionalClient if (treeConnectRequest.modelRequestType == ModelRequestType.EncryptedRequest) { Condition.IsTrue(modelResponseType == ModelResponseType.EncryptedResponse); } else { Condition.IsTrue(modelResponseType == ModelResponseType.UnEncryptedResponse); } Condition.IsTrue(status == ModelSmb2Status.STATUS_SUCCESS); Encryption_TreeId = (treeConnectRequest.connectToShareType == ConnectToShareType.ConnectToEncryptedShare) ? EncryptionTreeId.TreeIdToEncryptShare : EncryptionTreeId.TreeIdToUnEncryptShare; }
public void SetupConnection(ModelConnectionId connectionId, ModelDialectRevision clientMaxDialect) { connectionList.Add(connectionId, new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site)); if (connectionId == ModelConnectionId.MainConnection) { connectionList[connectionId].ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress, testConfig.ClientNic1IPAddress); } else { connectionList[connectionId].ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress, testConfig.ClientNic2IPAddress); } DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); uint status; NEGOTIATE_Response?negotiateResponse = null; status = connectionList[connectionId].Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, clientGuid: GetClientGuid(connectionId, dialects), checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }); DialectRevision expectedDialect; if (clientMaxDialect < sessionMgmtConfig.MaxSmbVersionSupported) { expectedDialect = ModelUtility.GetDialectRevision(clientMaxDialect); } else { expectedDialect = ModelUtility.GetDialectRevision(sessionMgmtConfig.MaxSmbVersionSupported); } Site.Assert.AreEqual( expectedDialect, negotiateResponse.Value.DialectRevision, "DialectRevision {0} is expected", expectedDialect); if (ModelUtility.IsSmb3xFamily(negotiateResponse.Value.DialectRevision) && sessionMgmtConfig.IsMultiChannelCapable) { // SMB2_GLOBAL_CAP_MULTI_CHANNEL if Connection.Dialect belongs to the SMB 3.x dialect family, // IsMultiChannelCapable is TRUE, and SMB2_GLOBAL_CAP_MULTI_CHANNEL is set in the Capabilities field of the request. Site.Assert.AreEqual( Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL & (Capabilities_Values)negotiateResponse.Value.Capabilities, ""); } else { Site.Assert.AreNotEqual( Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL & (Capabilities_Values)negotiateResponse.Value.Capabilities, ""); } }