public static void SetupConnection(ModelConnectionId connectionId, ModelDialectRevision clientMaxDialect) { // Restrict model contains 2 connections at most Condition.IsTrue(!ConnectionList.ContainsKey(connectionId)); // Reduce states Combination.NWise(1, connectionId, clientMaxDialect); DialectRevision dialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, config.MaxSmbVersionSupported); // Establish new connection ConnectionList.Add( connectionId, new ModelConnection(dialect)); ConnectionList[connectionId].ConnectionState = ModelState.Connected; ModelHelper.Log(LogType.Requirement, "3.3.5.1: Connection.ConstrainedConnection is set to TRUE."); ConnectionList[connectionId].ConstrainedConnection = true; }
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); }