private void NegotiateWithSpecificDialect(DialectRevision clientMaxDialectSupported) { DialectRevision serverMaxDialectSupported = TestConfig.MaxSmbVersionSupported; DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported); if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.", TestConfig.MaxSmbVersionClientSupported, clientMaxDialectSupported); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with maximum dialect: {0}.", clientMaxDialectSupported); client.Negotiate( Packet_Header_Flags_Values.NONE, negotiateDialects, checker: (Packet_Header header, NEGOTIATE_Response response) => { DialectRevision expectedDialect = clientMaxDialectSupported < serverMaxDialectSupported ? clientMaxDialectSupported : serverMaxDialectSupported; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check negotiate response contains expected dialect."); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.AreEqual(expectedDialect, response.DialectRevision, "Selected dialect should be {0}", expectedDialect); }); }
private void NegotiateWithNegotiateContexts( DialectRevision clientMaxDialectSupported, PreauthIntegrityHashID[] preauthHashAlgs, EncryptionAlgorithm[] encryptionAlgs = null, ResponseChecker <NEGOTIATE_Response> checker = null) { // ensure clientMaxDialectSupported higher than 3.11 if (clientMaxDialectSupported < DialectRevision.Smb311) { clientMaxDialectSupported = DialectRevision.Smb311; } DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported); if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.", TestConfig.MaxSmbVersionClientSupported, clientMaxDialectSupported); } status = client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, negotiateDialects, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs, checker: checker); }
public void NegotiateRequest(ModelDialectRevision maxSmbVersionClientSupported, SigningFlagType signingFlagType, SigningEnabledType signingEnabledType, SigningRequiredType signingRequiredType) { testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported)); Packet_Header_Flags_Values headerFlags = (signingFlagType == SigningFlagType.SignedFlagSet) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE; SigningEnabledType resSigningEnabledType = SigningEnabledType.SigningEnabledNotSet; SigningRequiredType resSigningRequiredType = SigningRequiredType.SigningRequiredNotSet; uint status = testClient.Negotiate( headerFlags, dialects, GetNegotiateSecurityMode(signingEnabledType, signingRequiredType), checker: (header, response) => { resSigningEnabledType = response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED) ? SigningEnabledType.SigningEnabledSet : SigningEnabledType.SigningEnabledNotSet; resSigningRequiredType = response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED) ? SigningRequiredType.SigningRequiredSet : SigningRequiredType.SigningRequiredNotSet; }); NegotiateResponse((ModelSmb2Status)status, resSigningEnabledType, resSigningRequiredType, signingConfig); }
public void Negotiate_SMB311_WithEncryptionContextWithoutIntegrityContext() { if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, with SMB2_ENCRYPTION_CAPABILITIES context, " + "without SMB2_PREAUTH_INTEGRITY_CAPABILITIES context."); client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, Smb2Utility.GetDialects(DialectRevision.Smb311), preauthHashAlgs: null, encryptionAlgs: new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server fails the negotiate request with STATUS_INVALID_PARAMETER."); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_INVALID_PARAMETER, header.Status, "[MS-SMB2] 3.3.5.4 If the negotiate context list does not contain exactly one SMB2_PREAUTH_INTEGRITY_CAPABILITIES negotiate context, " + "then the server MUST fail the negotiate request with STATUS_INVALID_PARAMETER."); }); }
/// <summary> /// The two client connects to the two IP addresses of scaleout file server /// Negotiate, SessionSetup, TreeConnect /// </summary> private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId) { Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, this.Site); client.ConnectToServerOverTCP(ip); client.Negotiate( Smb2Utility.GetDialects(DialectRevision.Smb21), testConfig.IsSMB1NegotiateEnabled); //client.SessionSetup( // testConfig.DefaultSecurityPackage, // //testConfig.ScaleOutFileServerName, // testConfig.AccountCredential, // testConfig.UseServerGssToken); AccountCredential accountCredential = false ? TestConfig.NonAdminAccountCredential : TestConfig.AccountCredential; client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, accountCredential, false); //client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId); //uint treeId_t; string sharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); client.TreeConnect(sharePath, out treeId); return(client); }
private bool ConnectToShare(string uncSharePath, out uint treeId) { treeId = 0; string serverName = Smb2Utility.GetServerName(uncSharePath); var serverIPs = Dns.GetHostEntry(serverName).AddressList; if (serverIPs == null || serverIPs.Length == 0) { return(false); } uint status = 0; foreach (var ip in serverIPs) // Try to connect to each IP since not all of them can be connected successfully. { try { client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, Site); client.ConnectToServer(Smb2TransportType.Tcp, serverName, ip); status = client.Negotiate( Smb2Utility.GetDialects(testConfig.MaxSmbVersionSupported), true, checker: (header, response) => { }); if (status != Smb2Status.STATUS_SUCCESS) { continue; } status = client.SessionSetup(testConfig.DefaultSecurityPackage, serverName, testConfig.AccountCredential, false, checker: (header, response) => { }); if (status != Smb2Status.STATUS_SUCCESS) { client.Disconnect(); continue; } status = client.TreeConnect(uncSharePath, out treeId, checker: (header, response) => { }); if (status == Smb2Status.STATUS_SUCCESS) { return(true); } else { client.LogOff(); client.Disconnect(); } } catch { // Catch the exceptions thrown in Negotiage/SessionSetup/TreeConnect // Try next IP } } return(false); }
public void Signing_VerifyAesGmacSigning() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckSigning(); #endregion var signingAlgorithms = new SigningAlgorithm[] { SigningAlgorithm.AES_GMAC }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends NEGOTIATE with the Aes-GMAC signing algorithm and NEGOTIATE_SIGNING_REQUIRED."); client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, Smb2Utility.GetDialects(DialectRevision.Smb311), SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED, preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }, compressionFlags: SMB2_COMPRESSION_CAPABILITIES_Flags.SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE, signingAlgorithms: signingAlgorithms, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "SUT MUST return STATUS_SUCCESS if the negotiation finished successfully."); }); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends SESSION_SETUP request and expects response."); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED); string uncSharepath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT to share: {0}", uncSharepath); client.TreeConnect( uncSharepath, out treeId, (Packet_Header header, TREE_CONNECT_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "TreeConnect should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.AreEqual( Packet_Header_Flags_Values.FLAGS_SIGNED, Packet_Header_Flags_Values.FLAGS_SIGNED & header.Flags, "Server should set SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header"); }); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF"); client.TreeDisconnect(treeId); client.LogOff(); }
public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType) { // Set checkEncrypt to false to not check if the response from the server is actually encrypted. testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site, checkEncrypt: false); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); testClient.Smb2Client.Disconnected += new Action(OnServerDisconnected); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported)); //Set capabilities according to isClientSupportsEncryption Capabilities_Values commonCapability = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; Capabilities_Values encryptionCapability = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? (commonCapability | Capabilities_Values.GLOBAL_CAP_ENCRYPTION) : commonCapability; uint status; DialectRevision selectedDialect; NEGOTIATE_Response?negotiateResponse = null; status = testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled, capabilityValue: encryptionCapability, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }, ifHandleRejectUnencryptedAccessSeparately: true, ifAddGLOBAL_CAP_ENCRYPTION: false, addDefaultEncryption: true ); selectedDialect = negotiateResponse.Value.DialectRevision; if ((selectedDialect == DialectRevision.Smb30 || selectedDialect == DialectRevision.Smb302) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) { /// TD section 3.3.5.4 /// SMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect is "3.0" or "3.0.2", the server supports encryption, /// and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request Site.Assert.IsTrue( negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION), "SMB2_GLOBAL_CAP_ENCRYPTION should be set in the negotiate response."); } else { Site.Assert.IsFalse( negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION), "SMB2_GLOBAL_CAP_ENCRYPTION should not be set in the negotiate response."); } }
/// <summary> /// Negotiate, SessionSetup and TreeConnect /// </summary> public void SetupConnection(ModelDialectRevision dialect, ModelCapabilities capabilities, SecurityMode_Values securityMode) { #region Connect to server testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); #endregion // It MUST be a GUID generated by the client, if the Dialects field contains a value other than 0x0202. Otherwise, the client MUST set this to 0. Guid clientGuid = (dialect == ModelDialectRevision.Smb2002) ? Guid.Empty : Guid.NewGuid(); #region negotiate testClient.Negotiate( Packet_Header_Flags_Values.NONE, Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)), securityMode, (Capabilities_Values)capabilities, clientGuid, (header, response) => { Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }); #endregion #region session setup testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken, (SESSION_SETUP_Request_SecurityMode_Values)securityMode); #endregion #region treeconnect testClient.TreeConnect( Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId); #endregion Connection_Dialect = ModelUtility.GetModelDialectRevision(negotiateResponse.DialectRevision); Connection_ClientCapabilities = (Capabilities_Values)capabilities; if (dialect >= ModelDialectRevision.Smb30) // GLOBAL_CAP_ENCRYPTION will be added in Functional client when dialect >= SMB30 { Connection_ClientCapabilities |= Capabilities_Values.GLOBAL_CAP_ENCRYPTION; } Connection_ClientSecurityMode = securityMode; Connection_ClientGuid = clientGuid; }
/// <summary> /// The two client connects to the two IP addresses of scaleout file server /// Negotiate, SessionSetup, TreeConnect /// </summary> private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId) { Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); client.ConnectToServerOverTCP(ip); client.Negotiate( Smb2Utility.GetDialects(DialectRevision.Smb21), testConfig.IsSMB1NegotiateEnabled); client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.ScaleOutFileServerName, testConfig.AccountCredential, testConfig.UseServerGssToken); client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId); return client; }
/// <summary> /// Initialize the test client by /// ConnectToServer, Negotiate, SessionSetup and TreeConnect /// </summary> private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId) { Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, ip); client.Negotiate( // Model cases only test Dialect lower than 3.11 Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302), testConfig.IsSMB1NegotiateEnabled); client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId); return(client); }
public void BVT_PersistentHandles() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); if (!TestConfig.IsPersistentHandlesSupported) { Site.Assert.Inconclusive("Test case is applicable in servers that support persistent handles"); } #endregion DialectRevision[] requestDialect = Smb2Utility.GetDialects(DialectRevision.Smb311); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION; SecurityMode_Values clientSecuirtyMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with client capabilitites: {0}.", clientCapabilities.ToString()); smb2Functionalclient.Negotiate( Packet_Header_Flags_Values.NONE, requestDialect, clientSecuirtyMode, clientCapabilities, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check negotiate response contains {0} in Capabilities.", Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.IsTrue(response.DialectRevision >= DialectRevision.Smb30, "Select dialect is {0}, And it should be SMB 3.0 or higher dialect.", response.DialectRevision); BaseTestSite.Assert.IsTrue(response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES), "Server Capability should with flag {0} being set.", NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); } ); }
private void ConnectToShare(ModelDialectRevision dialect, Smb2FunctionalClient client, Guid guid, string share, out uint treeId) { #region Connect to server client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); #endregion client.Negotiate( Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)), testConfig.IsSMB1NegotiateEnabled, clientGuid: guid); client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, share), out treeId); }
public void SetupConnection(ModelDialectRevision dialect) { testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); testClient.Negotiate(Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)), testConfig.IsSMB1NegotiateEnabled); testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); string share = testConfig.BasicFileShare; testClient.TreeConnect( Smb2Utility.GetUncPath(testConfig.SutComputerName, share), out treeId); }
public void BVT_SMBDialect() { smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP); DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(DialectRevision.Smb30); BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "Send Negotiate request with maximum dialect: {0}.", DialectRevision.Smb30); smb2Functionalclient.Negotiate( Packet_Header_Flags_Values.NONE, negotiateDialects, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "Check dialect in negotiate response is equal to {0}.", DialectRevision.Smb30); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.AreEqual(DialectRevision.Smb30, response.DialectRevision, "Selected dialect should be {0}.", DialectRevision.Smb30); } ); }
public void SetupConnection(ModelSessionSecurityContext securityContext) { testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); // SMB2 Negotiate // Model cases only test Dialect lower than 3.11 DialectRevision[] dialects = Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302); testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled); // SMB2 SESSION SETUP AccountCredential account = null; switch (securityContext) { case ModelSessionSecurityContext.Admin: account = testConfig.AccountCredential; break; case ModelSessionSecurityContext.NonAdmin: account = testConfig.NonAdminAccountCredential; break; default: throw new InvalidOperationException(securityContext + " is not supported."); } testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, account, testConfig.UseServerGssToken); // reset TreeId this.treeId = 0; }
public void Negotiate_SMB311_Compression_InvalidSmbDialect() { CheckCompressionApplicability(); var negotiateDialects = Smb2Utility.GetDialects(DialectRevision.Smb302); var compressionAlgorithms = TestConfig.SupportedCompressionAlgorithmList.ToArray(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send NEGOTIATE request with SMB dialects less than 3.1.1."); client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, negotiateDialects, preauthHashAlgs: null, compressionAlgorithms: compressionAlgorithms, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "SUT MUST return STATUS_SUCCESS if the negotiation finished successfully."); bool isExpectedCompressionContext = client.Smb2Client.CompressionInfo.CompressionIds.Length == 0; BaseTestSite.Assert.IsTrue(isExpectedCompressionContext, "SUT MUST ignore SMB2_COMPRESSION_CAPABILITIES if negotiated SMB dialect is less than 3.1.1."); }); }
/// <summary> /// Send ValidateNegotiateInfoRequest to Server, fill in the fields according to params. /// Verify the response. /// </summary> public void ValidateNegotiateInfoRequest(DialectType dialectType, CapabilitiesType capabilitiesType, SecurityModeType securityModeType, ClientGuidType clientGuidType) { Capabilities_Values capbilities = Connection_ClientCapabilities; if (capabilitiesType == CapabilitiesType.CapabilitiesDifferentFromNegotiate) { capbilities ^= Capabilities_Values.GLOBAL_CAP_DFS; } SecurityMode_Values securityMode = Connection_ClientSecurityMode; if (securityModeType == SecurityModeType.SecurityModeDifferentFromNegotiate) { securityMode ^= SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; } Guid guid = clientGuidType == ClientGuidType.ClientGuidSameWithNegotiate ? Connection_ClientGuid : Guid.NewGuid(); DialectRevision[] dialects = null; if (DialectType.None != dialectType) { ModelDialectRevision dialect = Connection_Dialect; if (DialectType.DialectDifferentFromNegotiate == dialectType) { dialect = ModelDialectRevision.Smb30 == Connection_Dialect ? ModelDialectRevision.Smb21 : ModelDialectRevision.Smb30; } dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)); } else { dialects = new DialectRevision[] { 0 } }; VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoRequest; validateNegotiateInfoRequest.Dialects = dialects; validateNegotiateInfoRequest.DialectCount = (ushort)dialects.Length; validateNegotiateInfoRequest.Capabilities = capbilities; validateNegotiateInfoRequest.SecurityMode = securityMode; validateNegotiateInfoRequest.Guid = guid; Site.Log.Add( LogEntryKind.Debug, "Dialects in ValidateNegotiateInfoRequest: {0}", Smb2Utility.GetArrayString(validateNegotiateInfoRequest.Dialects)); Site.Log.Add( LogEntryKind.Debug, "DialectCount in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.DialectCount); Site.Log.Add( LogEntryKind.Debug, "Capabilities in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.Capabilities); Site.Log.Add( LogEntryKind.Debug, "SecurityMode in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.SecurityMode); Site.Log.Add( LogEntryKind.Debug, "Guid in ValidateNegotiateInfoRequest: {0}", validateNegotiateInfoRequest.Guid); byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoRequest); byte[] outputBuffer; try { uint status = testClient.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: CheckIoCtlResponse); if (Smb2Status.STATUS_SUCCESS == status) { VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResponse = TypeMarshal.ToStruct <VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer); Site.Assert.AreEqual(negotiateResponse.DialectRevision, validateNegotiateInfoResponse.Dialect, "Dialect in Negotiate response({0}) and ValidateNegotiateInfo response({1}) should be the same", negotiateResponse.DialectRevision.ToString(), validateNegotiateInfoResponse.Dialect.ToString()); Site.Assert.AreEqual((uint)negotiateResponse.Capabilities, (uint)validateNegotiateInfoResponse.Capabilities, "Capabilities in Negotiate response({0}) and ValidateNegotiateResponse({1}) should be the same", negotiateResponse.Capabilities.ToString(), validateNegotiateInfoResponse.Capabilities.ToString()); Site.Assert.AreEqual((ushort)negotiateResponse.SecurityMode, (ushort)validateNegotiateInfoResponse.SecurityMode, "SecurityMode in Negotiate response({0}) and ValidateNegotiateInfo response({1}) should be the same", negotiateResponse.SecurityMode.ToString(), validateNegotiateInfoResponse.SecurityMode.ToString()); Site.Assert.AreEqual(negotiateResponse.ServerGuid, validateNegotiateInfoResponse.Guid, "ClientGuid in Negotiate response({0}) and ValidateNegotiateInfo response({1}) should be the same", negotiateResponse.ServerGuid.ToString(), validateNegotiateInfoResponse.Guid.ToString()); } testClient.TreeDisconnect(treeId); testClient.LogOff(); testClient.Disconnect(); this.ValidateNegotiateInfoResponse((ModelSmb2Status)status, validateNegotiateInfoConfig); return; } catch { } Site.Assert.IsTrue(testClient.Smb2Client.IsServerDisconnected, "ValidateNegotiationInfo failure should be caused by transport connection termination"); TerminateConnection(); }
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 PrepareOpen( ModelDialectRevision clientMaxDialect, PersistentBitType persistentBit, CAShareType connectToCAShare, ModelHandleType modelHandleType, OplockLeaseType oplockLeaseType) { // Lease V2 cases only apply on the server implements SMB 3.x family. if (oplockLeaseType == OplockLeaseType.LeaseV2) { testConfig.CheckDialect(DialectRevision.Smb30); } // Lease V1 cases only apply on the server implements SMB 2.1 and 3.x family. if (oplockLeaseType == OplockLeaseType.LeaseV1) { testConfig.CheckDialect(DialectRevision.Smb21); } if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2) && !testConfig.IsLeasingSupported) { Site.Assert.Inconclusive("Test case is applicable in servers that support leasing."); } requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL; if (persistentBit == PersistentBitType.PersistentBitSet) { clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; } clientGuid = Guid.NewGuid(); requestedContext = oplockLeaseType; isCAShare = (connectToCAShare == CAShareType.CAShare); IPAddress targetIPAddress; string targetServer; #region Connect to Common Share or CA Share if (!isCAShare) { sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt"; targetIPAddress = testConfig.SutIPAddress; targetServer = testConfig.SutComputerName; } else { sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName); fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt"; targetIPAddress = testConfig.CAShareServerIP; targetServer = testConfig.CAShareServerName; } testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClientBeforeDisconnection.CreditGoal = 20; testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress); testClientBeforeDisconnection.Negotiate( requestDialect, testConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilities, clientGuid: clientGuid, checker: (header, response) => { if (Smb2Utility.IsSmb3xFamily(response.DialectRevision) && handleConfig.IsPersistentHandleSupported && persistentBit == PersistentBitType.PersistentBitSet) { Site.Assert.IsTrue( response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES), "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " + "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " + "Actual capabilities are {0}", response.Capabilities); } }); testClientBeforeDisconnection.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, testConfig.AccountCredential, testConfig.UseServerGssToken); testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection); #endregion #region Create operation according to the handle type and context Smb2CreateContextRequest[] prepareRequestContext = null; Smb2CreateContextResponse[] serverCreateContexts = null; RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; switch (oplockLeaseType) { case OplockLeaseType.LeaseV1: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE); prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE; } break; case OplockLeaseType.LeaseV2: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2); prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE; } break; case OplockLeaseType.BatchOplock: { prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH; } break; case OplockLeaseType.NoOplockOrLease: { prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; } break; } PrepareOpenCreate( testClientBeforeDisconnection, treeIdBeforeDisconnection, fileName, out fileIdBeforDisconnection, out serverCreateContexts, requestedOplockLevel, prepareRequestContext); #endregion }
/// <summary> /// Common method used to connect to target server, including the following message sequences: /// 1. Negotiate /// 2. Session Setup /// 3. Tree Connect /// </summary> /// <param name="smb2Dialect"></param> /// <param name="client"></param> /// <param name="clientGuid"></param> /// <param name="account"></param> /// <param name="connectShareType"></param> /// <param name="treeId"></param> /// <param name="clientBeforeDisconnection"></param> protected virtual void Connect(DialectRevision smb2Dialect, Smb2FunctionalClient client, Guid clientGuid, AccountCredential account, ConnectShareType connectShareType, out uint treeId, Smb2FunctionalClient clientBeforeDisconnection) { DialectRevision[] requestDialect = Smb2Utility.GetDialects(smb2Dialect); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; IPAddress targetIPAddress = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerIP : testConfig.SutIPAddress; string targetServer = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName; client.ConnectToServer(TestConfig.UnderlyingTransport, targetServer, targetIPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends NEGOTIATE request.", clientGuid); client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid); if (null != clientBeforeDisconnection) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request to reconnect to the previous session.", clientGuid); client.ReconnectSessionSetup( clientBeforeDisconnection, testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } else { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request.", clientGuid); client.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends TREE_CONNECT request.", clientGuid); client.TreeConnect( durableHandleUncSharePath, out treeId, checker: (header, response) => { BaseTestSite.Log.Add( LogEntryKind.Debug, "Capabilities in TREE_CONNECT response: {0}", response.Capabilities); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful", header.Command); if (connectShareType == ConnectShareType.CAShare) { BaseTestSite.Assert.AreEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } if (connectShareType == ConnectShareType.BasicShare) { BaseTestSite.Assert.AreNotEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should not have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } }); }
public 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, ""); } }
private void SendCreateRequestWithSpecificAppInstanceversion( Smb2FunctionalClient client, Guid appInstanceId, ulong?appInstanceVersionHigh, ulong?appInstanceVersionLow, DialectRevision dialect, uint expectedCreateResponseStatus, out uint treeId, out FILEID fileId ) { #region Client connects to Server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client connects to the file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress); client.Negotiate(Smb2Utility.GetDialects(dialect), TestConfig.IsSMB1NegotiateEnabled); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); client.TreeConnect(uncSharePath, out treeId); Smb2CreateContextResponse[] serverCreateContexts; Smb2CreateAppInstanceVersion appInstanceVersion = new Smb2CreateAppInstanceVersion(); Smb2CreateContextRequest[] clientCreateContexts; if (appInstanceVersionHigh.HasValue && appInstanceVersionLow.HasValue) { appInstanceVersion.AppInstanceVersionHigh = appInstanceVersionHigh.Value; appInstanceVersion.AppInstanceVersionLow = appInstanceVersionLow.Value; clientCreateContexts = new Smb2CreateContextRequest[] { new Smb2CreateAppInstanceId { AppInstanceId = appInstanceId }, appInstanceVersion }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with AppInstanceVersionHigh = {0}, AppInstanceVersionLow = {1}.", appInstanceVersion.AppInstanceVersionHigh, appInstanceVersion.AppInstanceVersionLow); } else { clientCreateContexts = new Smb2CreateContextRequest[] { new Smb2CreateAppInstanceId { AppInstanceId = appInstanceId } }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request without AppInstanceVersion."); } client.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, clientCreateContexts, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { BaseTestSite.Assert.AreEqual( expectedCreateResponseStatus, header.Status, (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS ? "The open will be closed. Create should succeed. Actually server returns with {0}." : "The open cannot be closed. Create should not succeed. Actually server returns with {0}."), Smb2Status.GetStatusCode(header.Status)); }); #endregion }
public void PrepareOpen(ModelDialectRevision clientMaxDialect, DurableHandle durableHandle) { prepareOpenClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); clientGuid = Guid.NewGuid(); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); // Connect to Share ConnectToShare( Site, testConfig, prepareOpenClient, dialects, clientGuid, testConfig.AccountCredential, out dialect, out treeId); Site.Assert.AreEqual( ModelUtility.GetDialectRevision(clientMaxDialect), dialect, "DialectRevision {0} is expected", ModelUtility.GetDialectRevision(clientMaxDialect)); // SMB2 Create RequestedOplockLevel_Values opLockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; Smb2CreateContextRequest[] createContextRequests = new Smb2CreateContextRequest[0]; createGuid = Guid.Empty; if (durableHandle == DurableHandle.DurableHandle) {// durable handle request context with batch opLock opLockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH; createGuid = Guid.NewGuid(); testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST); createContextRequests = new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequest { DurableRequest = createGuid } }; } // create Smb2CreateContextResponse[] createContextResponse; prepareOpenClient.Create( treeId, GetTestFileName(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare)), CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse, requestedOplockLevel_Values: opLockLevel, createContexts: createContextRequests, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); if (durableHandle == DurableHandle.DurableHandle) { Site.Assert.AreEqual <OplockLevel_Values>( OplockLevel_Values.OPLOCK_LEVEL_BATCH, response.OplockLevel, "OplockLevel should be OPLOCK_LEVEL_BATCH if Durable Handle"); } } ); if (durableHandle == DurableHandle.DurableHandle) { // check whether response contain Durable Context Site.Assert.IsTrue( ContainDurableHandleResponse(createContextResponse), "Durable Handle Response should be in the Create response."); } }
private void TestValidateNegotiateInfo(Smb2FunctionalClient client, ValidateNegotiateInfoRequestType requestType, DialectRevision[] invalidDialects = null) { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO); // Server will terminate connection if Validate Negotiate Info Request is not signed. TestConfig.CheckSigning(); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); DialectRevision[] requestDialects; if (requestType == ValidateNegotiateInfoRequestType.InvalidSMB311Dialect) { requestDialects = Smb2Utility.GetDialects(DialectRevision.Smb311); } else { // FSCTL_VALIDATE_NEGOTIATE_INFO is only supported in SMB30 and SMB302. For SMB311 and later, we use SMB30 to test the server behavior. requestDialects = (TestConfig.MaxSmbVersionClientSupported > DialectRevision.Smb302) ? Smb2Utility.GetDialects(DialectRevision.Smb30) : TestConfig.RequestDialects; } Guid clientGuid = Guid.NewGuid(); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_ENCRYPTION; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; NEGOTIATE_Response? negotiateResponse = null; client.Negotiate( requestDialects, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid, (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); negotiateResponse = response; }); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); uint treeId; string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName); client.TreeConnect(ipcPath, out treeId); VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq; switch (requestType) { case ValidateNegotiateInfoRequestType.None: case ValidateNegotiateInfoRequestType.InvalidSMB311Dialect: case ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; case ValidateNegotiateInfoRequestType.InvalidDialects: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)invalidDialects.Length; validateNegotiateInfoReq.Dialects = invalidDialects; break; case ValidateNegotiateInfoRequestType.InvalidGuid: validateNegotiateInfoReq.Guid = Guid.NewGuid(); validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; case ValidateNegotiateInfoRequestType.InvalidSecurityMode: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; case ValidateNegotiateInfoRequestType.InvalidCapabilities: validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = Capabilities_Values.NONE; validateNegotiateInfoReq.SecurityMode = clientSecurityMode; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; break; default: throw new InvalidOperationException("Unexpected ValidateNegotiateInfo request type " + requestType); } byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq); byte[] outputBuffer; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Attempt to validate negotiate info with info Guid: {0}, Capabilities: {1}, SecurityMode: {2}, DialectCount: {3}, Dialects: {4}", validateNegotiateInfoReq.Guid, validateNegotiateInfoReq.Capabilities, validateNegotiateInfoReq.SecurityMode, validateNegotiateInfoReq.DialectCount, Smb2Utility.GetArrayString(validateNegotiateInfoReq.Dialects)); if (requestType == ValidateNegotiateInfoRequestType.None) { uint status = client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: (header, response) => { }); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "ValidateNegotiateInfo should succeed "); VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResp = TypeMarshal.ToStruct <VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer); BaseTestSite.Log.Add( LogEntryKind.Debug, "Capabilities returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Capabilities); BaseTestSite.Assert.AreEqual( (Capabilities_Values)negotiateResponse.Value.Capabilities, validateNegotiateInfoResp.Capabilities, "Capabilities returned in ValidateNegotiateInfo response should be equal to server capabilities in original Negotiate response"); BaseTestSite.Log.Add( LogEntryKind.Debug, "Guid returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Guid); BaseTestSite.Assert.AreEqual( negotiateResponse.Value.ServerGuid, validateNegotiateInfoResp.Guid, "ServerGuid returned in ValidateNegotiateInfo response should be equal to server ServerGuid in original Negotiate response"); BaseTestSite.Log.Add( LogEntryKind.Debug, "SecurityMode returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.SecurityMode); BaseTestSite.Assert.AreEqual( (SecurityMode_Values)negotiateResponse.Value.SecurityMode, validateNegotiateInfoResp.SecurityMode, "SecurityMode returned in ValidateNegotiateInfo response should be equal to server SecurityMode in original Negotiate response"); BaseTestSite.Log.Add( LogEntryKind.Debug, "Dialect returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Dialect); BaseTestSite.Assert.AreEqual( negotiateResponse.Value.DialectRevision, validateNegotiateInfoResp.Dialect, "DialectRevision returned in ValidateNegotiateInfo response should be equal to server DialectRevision in original Negotiate response"); } else { string errCondition; switch (requestType) { case ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse: errCondition = "MaxOutputResponse in the request is less than the size of a VALIDATE_NEGOTIATE_INFO Response"; break; case ValidateNegotiateInfoRequestType.InvalidSMB311Dialect: errCondition = "Connection.Dialect is \"3.1.1\""; break; case ValidateNegotiateInfoRequestType.InvalidDialects: errCondition = "there is no greatest common dialect between Dialects field in VALIDATE_NEGOTIATE_INFO Request and the server implemented dialect, or the greatest common dialect is not equal to Connection.Dialect"; break; case ValidateNegotiateInfoRequestType.InvalidGuid: errCondition = "Guid field in VALIDATE_NEGOTIATE_INFO request is not equal to the ClientGuid sent in the original SMB2 NEGOTIATE request"; break; case ValidateNegotiateInfoRequestType.InvalidSecurityMode: errCondition = "SecurityMode field in VALIDATE_NEGOTIATE_INFO request is not equal to the SecurityMode sent in the original SMB2 NEGOTIATE request"; break; case ValidateNegotiateInfoRequestType.InvalidCapabilities: errCondition = "Capabilities field in VALIDATE_NEGOTIATE_INFO request is not equal to the Capabilities sent in the original SMB2 NEGOTIATE request"; break; default: throw new InvalidOperationException("Unexpected ValidateNegotiateInfo request type " + requestType); } try { uint maxOutputResponse = (requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse) ? (uint)0 : Smb2FunctionalClient.DefaultMaxOutputResponse; client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, maxOutputResponse, checker: (header, response) => { }); client.TreeDisconnect(treeId); client.LogOff(); } catch { } BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when {0}", errCondition); } }
public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ModelShareFlag shareFlag, ModelShareType shareType) { IPAddress ip; if (shareType == ModelShareType.STYPE_CLUSTER_SOFS) { server = testConfig.ScaleOutFileServerName; ip = Dns.GetHostEntry(server).AddressList[0]; if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK) { uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithForceLevel2AndSOFS); } else { uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithoutForceLevel2WithSOFS); } } else { server = testConfig.SutComputerName; ip = testConfig.SutIPAddress; if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK) { uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithForceLevel2WithoutSOFS); } else { uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithoutForceLevel2OrSOFS); } } testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.Smb2Client.OplockBreakNotificationReceived += new Action <Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnOplockBreakNotificationReceived); testClient.ConnectToServer(testConfig.UnderlyingTransport, server, ip, testConfig.ClientNic1IPAddress); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported)); NEGOTIATE_Response?negotiateResponse = null; testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }); negotiatedDialect = negotiateResponse.Value.DialectRevision; testClient.SessionSetup( testConfig.DefaultSecurityPackage, server, testConfig.AccountCredential, testConfig.UseServerGssToken); testClient.TreeConnect( uncSharePath, out treeId, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); Site.Assert.AreEqual( shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK, response.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK), "SHAREFLAG_FORCE_LEVELII_OPLOCK is{0}expected to be set", shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK ? " " : " not "); if (ModelUtility.IsSmb3xFamily(negotiateResponse.Value.DialectRevision)) { Site.Assert.AreEqual( shareType == ModelShareType.STYPE_CLUSTER_SOFS, response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT), "SHARE_CAP_SCALEOUT is{0}expected to be set", shareType == ModelShareType.STYPE_CLUSTER_SOFS ? " " : " not "); } }); }
public void ValidateNegotiateInfo_Negative_SMB311() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); // Server will terminate connection if Validate Negotiate Info Request is not signed. TestConfig.CheckSigning(); #endregion Smb2FunctionalClient testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); Guid clientGuid = Guid.NewGuid(); DialectRevision[] requestDialects = Smb2Utility.GetDialects(DialectRevision.Smb311); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; NEGOTIATE_Response? negotiateResponse = null; status = client.Negotiate( requestDialects, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid, (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb311, response); negotiateResponse = response; }); status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); uint treeId; string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName); status = client.TreeConnect(ipcPath, out treeId); VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq = new VALIDATE_NEGOTIATE_INFO_Request(); validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = clientCapabilities; validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE; validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length; validateNegotiateInfoReq.Dialects = requestDialects; byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq); byte[] outputBuffer; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Attempt to validate negotiate info with info Guid: {0}, Capabilities: {1}, SecurityMode: {2}, DialectCount: {3}, Dialects: {4}", validateNegotiateInfoReq.Guid, validateNegotiateInfoReq.Capabilities, validateNegotiateInfoReq.SecurityMode, validateNegotiateInfoReq.DialectCount, Smb2Utility.GetArrayString(validateNegotiateInfoReq.Dialects)); try { BaseTestSite.Log.Add( LogEntryKind.TestStep, "Attempt to send a request with an SMB2 header with a Command value equal to SMB2 IOCTL, and a CtlCode of FSCTL_VALIDATE_NEGOTIATE_INFO."); client.ValidateNegotiateInfo( treeId, inputBuffer, out outputBuffer ); } catch { } BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when Connection.Dialect is \"3.1.1\"."); }
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 OpenRequest( ModelDialectRevision clientMaxDialect, PersistentBitType persistentBit, CAShareType connectToCAShare, OplockLeaseType oplockLeaseType, DurableV1RequestContext durableV1RequestContext, DurableV2RequestContext durableV2RequestContext, DurableV1ReconnectContext durableV1ReconnectContext, DurableV2ReconnectContext durableV2ReconnectContext) { requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL; if (persistentBit == PersistentBitType.PersistentBitSet) { clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; } clientGuid = Guid.NewGuid(); requestedContext = oplockLeaseType; isCAShare = (connectToCAShare == CAShareType.CAShare); IPAddress targetIPAddress; string targetServer; #region Connect to Common Share or CA Share if (!isCAShare) { sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt"; targetIPAddress = testConfig.SutIPAddress; targetServer = testConfig.SutComputerName; } else { sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName); fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt"; targetIPAddress = testConfig.CAShareServerIP; targetServer = testConfig.CAShareServerName; } testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClientBeforeDisconnection.CreditGoal = 20; testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress); testClientBeforeDisconnection.Negotiate( requestDialect, testConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilities, clientGuid: clientGuid, checker: (header, response) => { if (Smb2Utility.IsSmb3xFamily(response.DialectRevision) && handleConfig.IsPersistentHandleSupported && persistentBit == PersistentBitType.PersistentBitSet) { Site.Assert.IsTrue( response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES), "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " + "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " + "Actual capabilities are {0}", response.Capabilities); } }); testClientBeforeDisconnection.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, testConfig.AccountCredential, testConfig.UseServerGssToken); testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection, delegate(Packet_Header responseHeader, TREE_CONNECT_Response response) { if (isCAShare) { if (!response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY)) { // skip test case for CA share is invalid Site.Assert.Inconclusive("This test case is applicable only when CA share is valid."); } } }); #endregion #region Construct Create Contexts Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext( durableV1RequestContext, durableV2RequestContext, durableV1ReconnectContext, durableV2ReconnectContext, oplockLeaseType, false, false); #endregion #region Send Create request according to different context combination RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; switch (oplockLeaseType) { case OplockLeaseType.NoOplockOrLease: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; } break; case OplockLeaseType.BatchOplock: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH; } break; case OplockLeaseType.LeaseV1: case OplockLeaseType.LeaseV2: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE; } break; } FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; uint status = OpenCreate( testClientBeforeDisconnection, treeIdBeforeDisconnection, fileName, out fileId, out serverCreateContexts, requestedOplockLevel, smb2CreateContextRequest); #endregion DurableHandleResponseContext durableHandleResponse; LeaseResponseContext leaseResponse; CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse); OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig); testClientBeforeDisconnection.TreeDisconnect(treeIdAfterDisconnection, (header, response) => { }); testClientBeforeDisconnection.LogOff(); }
private void TestAsymmetricShare(DialectRevision requestMaxDialect, string serverName, bool isAsymmetricShare) { int ret = 0; uint callId = 0; Guid clientGuid = Guid.NewGuid(); WITNESS_INTERFACE_INFO registerInterface; string shareName = isAsymmetricShare ? TestConfig.AsymmetricShare : TestConfig.BasicFileShare; #region Get the file server to access it through SMB2 IPAddress currentAccessIp = SWNTestUtility.GetCurrentAccessIP(serverName); BaseTestSite.Assert.IsNotNull(currentAccessIp, "IP address of the file server should NOT be empty"); BaseTestSite.Log.Add(LogEntryKind.Debug, "Got the IP {0} to access the file server", currentAccessIp.ToString()); #endregion #region Connect to the asymmetric share uncSharePath = Smb2Utility.GetUncPath(serverName, shareName); string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); testDirectory = CreateTestDirectory(uncSharePath); string file = string.Format(@"{0}\{1}", testDirectory, Guid.NewGuid().ToString()); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP"); smb2Client = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite); smb2Client.ConnectToServerOverTCP(currentAccessIp); smb2Client.Negotiate( Smb2Utility.GetDialects(requestMaxDialect), TestConfig.IsSMB1NegotiateEnabled, capabilityValue: 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, clientGuid: clientGuid, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "Negotiate should succeed."); BaseTestSite.Assert.AreEqual( requestMaxDialect, response.DialectRevision, "The server is expected to use dialect {0}. Actual dialect is {1}", requestMaxDialect, response.DialectRevision); }); smb2Client.SessionSetup( TestConfig.DefaultSecurityPackage, serverName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); uint treeId = 0; Share_Capabilities_Values shareCapabilities = Share_Capabilities_Values.NONE; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends TREE_CONNECT request to the {0} on the {1}", shareName, serverName); DoUntilSucceed( () => smb2Client.TreeConnect(uncSharePath, out treeId, (header, response) => { shareCapabilities = response.Capabilities; }), TestConfig.FailoverTimeout, "Retry TreeConnect until succeed within timeout span"); if (requestMaxDialect == DialectRevision.Smb302 && isAsymmetricShare) { BaseTestSite.Assert.IsTrue(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_ASYMMETRIC), "The capabilities of the share should contain SHARE_CAP_ASYMMETRIC. The actual capabilities is {0}.", shareCapabilities); } else { BaseTestSite.Assert.IsFalse(shareCapabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_ASYMMETRIC), "The capabilities of the share should not contain SHARE_CAP_ASYMMETRIC. The actual capabilities is {0}.", shareCapabilities); #region Disconnect current SMB2 connection smb2Client.TreeDisconnect(treeId); smb2Client.LogOff(); smb2Client.Disconnect(); #endregion return; } FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; Guid createGuid = Guid.NewGuid(); Guid leaseKey = Guid.NewGuid(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client writes to the file."); smb2Client.Create( treeId, file, CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE); smb2Client.Write(treeId, fileId, content); string readContent; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client reads from the file."); smb2Client.Read(treeId, fileId, 0, (uint)content.Length, out readContent); BaseTestSite.Assert.IsTrue( content.Equals(readContent), "Content read should be identical to that written."); #endregion #region Get register interface DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIp, TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage, TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, serverName), TestConfig.FailoverTimeout, "Retry BindServer until succeed within timeout span"); WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrGetInterfaceList."); DoUntilSucceed(() => { ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList); BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret); return(SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform)); }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span"); swnClientForInterface.SwnUnbind(TestConfig.Timeout); SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface); #endregion #region Get SHARE_MOVE_NOTIFICATION DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness, (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6), TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage, TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, serverName), TestConfig.FailoverTimeout, "Retry BindServer until succeed within timeout span"); string clientName = TestConfig.WitnessClientName; BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:"); BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", serverName); BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddress: {0}", currentAccessIp.ToString()); BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClient Name: {0}", clientName); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrRegisterEx."); ret = swnClientForWitness.WitnessrRegisterEx(SwnVersion.SWN_VERSION_2, serverName, shareName, currentAccessIp.ToString(), clientName, WitnessrRegisterExFlagsValue.WITNESS_REGISTER_IP_NOTIFICATION, 120, out pContext); BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegisterEx returns with result code = 0x{0:x8}", ret); BaseTestSite.Assert.IsNotNull(pContext, "Expect pContext is not null."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrAsyncNotify."); callId = swnClientForWitness.WitnessrAsyncNotify(pContext); BaseTestSite.Assert.AreNotEqual <uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId); // NOTICE // This comment is for current Windows Cluster test environment. // Current test environment has only two nodes and both they are optimum nodes. // So whatever the server name is, SHARE_MOVE_NOTIFICATION notification will be recieved. // The configuration items 'OptimumNodeOfAsymmetricShare' and 'NonOptimumNodeOfAsymmetricShare' are assigned the same default value. // The code in if block will be executed all the time. if (serverName == TestConfig.NonOptimumNodeOfAsymmetricShare) { #region Expect that SHARE_MOVE_NOTIFICATION notification will be received when the client connects to the asymmetric share on the non-optimum share RESP_ASYNC_NOTIFY respNotify; ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify); BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrAsyncNotify returns with result code = 0x{0:x8}", ret); SWNTestUtility.PrintNotification(respNotify); SWNTestUtility.VerifyClientMoveShareMoveAndIpChange(respNotify, SwnMessageType.SHARE_MOVE_NOTIFICATION, (uint)SwnIPAddrInfoFlags.IPADDR_V4, TestConfig.Platform); #region Get the new IpAddr IPADDR_INFO_LIST ipAddrInfoList; SwnUtility.ParseIPAddrInfoList(respNotify, out ipAddrInfoList); currentAccessIp = (ipAddrInfoList.IPAddrList[0].Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(ipAddrInfoList.IPAddrList[0].IPV4) : SWNTestUtility.ConvertIPV6(ipAddrInfoList.IPAddrList[0].IPV6); #endregion #region Unregister SWN Witness BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrUnRegister."); ret = swnClientForWitness.WitnessrUnRegister(pContext); BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret); pContext = IntPtr.Zero; swnClientForWitness.SwnUnbind(TestConfig.Timeout); #endregion #region Disconnect current SMB2 connection BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF; DISCONNECT."); smb2Client.TreeDisconnect(treeId); smb2Client.LogOff(); smb2Client.Disconnect(); #endregion #endregion } else { #region Expect that no SHARE_MOVE_NOTIFICATION notification will be received when the client connects to the asymmetric share on the optimum share bool isNotificationReceived = false; try { RESP_ASYNC_NOTIFY respNotify; ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify); isNotificationReceived = true; } catch (TimeoutException) { isNotificationReceived = false; } #region Disconnect current SMB2 connection BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending the following requests: TREE_DISCONNECT; LOG_OFF; DISCONNECT"); smb2Client.TreeDisconnect(treeId); smb2Client.LogOff(); smb2Client.Disconnect(); #endregion #region Unregister SWN Witness BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client calls WitnessrUnRegister."); ret = swnClientForWitness.WitnessrUnRegister(pContext); BaseTestSite.Assert.AreEqual <SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret); pContext = IntPtr.Zero; swnClientForWitness.SwnUnbind(TestConfig.Timeout); #endregion BaseTestSite.Assert.IsFalse(isNotificationReceived, "Expect that no notification will be received when the client has connected to asymmetric share on the optimum node."); #endregion return; } #endregion #region Connect to the share on the optimum node smb2Client = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Got the IP {0} to access the file server", currentAccessIp.ToString()); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE; SESSION_SETUP"); smb2Client.ConnectToServerOverTCP(currentAccessIp); smb2Client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: 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, clientGuid: Guid.NewGuid(), checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "Negotiate should succeed."); }); smb2Client.SessionSetup( TestConfig.DefaultSecurityPackage, serverName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client sends TREE_CONNECT and wait for a response until timeout."); DoUntilSucceed( () => smb2Client.TreeConnect(uncSharePath, out treeId, (header, response) => { }), TestConfig.FailoverTimeout, "Retry TreeConnect until succeed within timeout span"); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client writes to the file."); smb2Client.Create( treeId, file, CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE); smb2Client.Write(treeId, fileId, content); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client reads from the file."); smb2Client.Read(treeId, fileId, 0, (uint)content.Length, out readContent); BaseTestSite.Assert.IsTrue( content.Equals(readContent), "Content read should be identical to that written."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF; DISCONNECT."); smb2Client.TreeDisconnect(treeId); smb2Client.LogOff(); smb2Client.Disconnect(); #endregion }