private void ConnectToShare( Smb2FunctionalClient client, Guid clientGuid, out uint treeId) { client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); // Negotiate client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb21, response); }); // SMB2 SESSION SETUP client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); // SMB2 Tree Connect client.TreeConnect( Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId); }
/// <summary> /// Attempt to trigger LeaseBreakNotification from a separate client /// </summary> /// <param name="client">Client to trigger LeaseBreakNotification</param> /// <param name="requestDialect">Negotiate dialects</param> /// <param name="serverName">Name of file server to access</param> /// <param name="isDirectory">True value indicating to open a directory, false for a file</param> /// <param name="requestedLeaseState">LeaseState when open the directory or file</param> /// <param name="accessMask">AccessMask when open the directory or file</param> private void TriggerBreakFromClient( Smb2FunctionalClient client, DialectRevision[] requestDialect, string serverName, bool isDirectory, LeaseStateValues requestedLeaseState, AccessMask accessMask) { BaseTestSite.Log.Add(LogEntryKind.Debug, "AfterFailover: Attempt to access same file/directory to trigger LeaseBreakNotification from a separate client with LeaseState {0} and AccessMask {1}", requestedLeaseState, accessMask); #region Negotiate status = client.Negotiate( requestDialect, 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, checker: (Packet_Header header, NEGOTIATE_Response response) => { TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); }); #endregion #region SESSION_SETUP status = client.SessionSetup( TestConfig.DefaultSecurityPackage, serverName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share uint treeId; status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE Smb2CreateContextResponse[] serverCreateContexts; FILEID fileId; status = client.Create( treeId, // To break lease on directory, create a new child item isDirectory ? testDirectory + @"\child.txt" : fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = requestedLeaseState } }, accessMask: accessMask, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { }); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "AfterFailover: Finish triggering a LeaseBreakNotification from a separate client."); }
private void PrepareFileForTrimming(out uint treeId, out FILEID fileId) { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_FILE_LEVEL_TRIM); #endregion string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); string fileName = GetTestFileName(uncSharePath); string contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); uint status = smb2Functionalclient.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); }); status = smb2Functionalclient.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); status = smb2Functionalclient.TreeConnect(uncSharePath, out treeId); Smb2CreateContextResponse[] serverCreateContexts; status = smb2Functionalclient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); status = smb2Functionalclient.Write(treeId, fileId, contentWrite); status = smb2Functionalclient.Close(treeId, fileId); status = smb2Functionalclient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); }
/// <summary> /// Establish alternative channel, which includes NEGOTIATE, SESSION_SETUP /// </summary> /// <param name="requestDialect">Dialects in request</param> /// <param name="serverIp">Ip address on server side</param> /// <param name="clientIp">Ip address on client side</param> /// <param name="treeId">Tree id that is used to set encryption</param> /// <param name="enableEncryptionPerShare">Set true if enable encryption on share, otherwise set false</param> private void EstablishAlternativeChannel( DialectRevision[] requestDialect, IPAddress serverIp, IPAddress clientIp, uint treeId, bool enableEncryptionPerShare = false) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Establish alternative channel to connect share {0}", uncSharePath); alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp); #region Negotiate Capabilities_Values alternativeChannelClientCapabilities = 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; status = alternativeChannelClient.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid, capabilityValue: alternativeChannelClientCapabilities, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response); } ); #endregion #region SESSION_SETUP status = alternativeChannelClient.AlternativeChannelSessionSetup( mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion alternativeChannelClient.SetTreeEncryption(treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Establish alternative channel to connect share {0}", uncSharePath); }
private void ConnectToShare( Smb2FunctionalClient client, Guid clientGuid, out uint treeId) { client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.CAShareServerName, TestConfig.CAShareServerIP); // Negotiate client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, clientGuid: clientGuid, checker: (header, response) => { BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, (NtStatus)header.Status, "Negotiate should be successfully"); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, response); } ); // SMB2 SESSION SETUP client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.CAShareServerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); // SMB2 Tree Connect client.TreeConnect( Smb2Utility.GetUncPath(TestConfig.CAShareServerName, TestConfig.CAShareName), out treeId, checker: (header, response) => { BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, (NtStatus)header.Status, "TreeConnect should be successfully"); // Check IsCA BaseTestSite.Assert.IsTrue( response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY), "Share should support capabilities of SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY "); }); }
private void NewTestFile(Smb2FunctionalClient client, string fileName, string content, out uint treeId, out FILEID fileId) { client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "NEGOTIATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); }); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.ShareServerName, //TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); //string uncSharePath = Smb2Utility.GetUncPath(TestConfig.HvrsSutComputerName, TestConfig.ShareName); client.TreeConnect(TestConfig.SharePath, out treeId); //string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); //client.TreeConnect(uncSharePath, out treeId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client writes to the file."); Smb2CreateContextResponse[] serverCreateContexts; client.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); client.Write(treeId, fileId, content); // Flush written content to backend storage to avoid cache. client.Flush(treeId, fileId); }
private void ConnectToShare(Smb2FunctionalClient smbClient, Guid clientGuid, out uint treeId) { smbClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP); smbClient.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, clientGuid: clientGuid, checker: (header, response) => { BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, (NtStatus)header.Status, "Negotiate should be successfully"); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, response); }); smbClient.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.ShareServerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); smbClient.TreeConnect( TestConfig.SharePath, out treeId, checker: (header, response) => { BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, (NtStatus)header.Status, "TreeConnect should be successfully"); } // TODO: Check IsCA ); }
/// <summary> /// Reconnect to share on clustered file server after failover happens, include NEGOTIATE, SESSION_SETUP, TREE_CONNECT /// </summary> /// <param name="server">Name of clustered file server</param> /// <param name="fsType">Type of clustered file server</param> /// <param name="treeId">Out param for tree Id that connected</param> /// <param name="enableEncryptionPerShare">Set true if enable encryption on share, otherwise set false</param> private void ReconnectServerAfterFailover(string server, FileServerType fsType, out uint treeId, bool enableEncryptionPerShare = false) { BaseTestSite.Log.Add( LogEntryKind.Debug, "AfterFailover: Connect share {0} on server {1} with following steps.", uncSharePath, server); if (fsType == FileServerType.ScaleOutFileServer) { // For scale-out file server case, retrieve and use another access IP for connection IPAddress oldAccessIp = currentAccessIp; currentAccessIp = null; foreach (var ip in accessIpList) { if (!ip.Equals(oldAccessIp)) { currentAccessIp = ip; break; } } } else if (fsType == FileServerType.GeneralFileServer) { currentAccessIp = null; DoUntilSucceed(() => { foreach (IPAddress ipAddress in accessIpList) { Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite); try { pingClient.ConnectToServerOverTCP(ipAddress); pingClient.Disconnect(); pingClient = null; currentAccessIp = ipAddress; return(true); } catch { } } return(false); }, TestConfig.FailoverTimeout, "Retry to ping to server until succeed within timeout span"); } BaseTestSite.Assert.AreNotEqual( null, currentAccessIp, "Access IP to the file server should not be empty"); BaseTestSite.Log.Add( LogEntryKind.Debug, "Got IP {0} to access the file server", currentAccessIp.ToString()); DoUntilSucceed(() => clientAfterFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, currentAccessIp), TestConfig.FailoverTimeout, "Retry to connect to server until succeed within timeout span"); #region Negotiate Capabilities_Values clientCapabilitiesAfterFailover = 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; status = clientAfterFailover.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilitiesAfterFailover, clientGuid: clientGuid, checker: (Packet_Header header, NEGOTIATE_Response response) => { TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); }); #endregion #region SESSION_SETUP status = clientAfterFailover.ReconnectSessionSetup( clientBeforeFailover, TestConfig.DefaultSecurityPackage, server, TestConfig.AccountCredential, TestConfig.UseServerGssToken); BaseTestSite.Log.Add( LogEntryKind.Debug, "Global encryption disabled"); #endregion #region TREE_CONNECT to share uint innerTreeId = 0; //Retry TreeConnect until succeed within timeout span status = DoUntilSucceed( () => clientAfterFailover.TreeConnect(uncSharePath, out innerTreeId, (header, response) => { }), TestConfig.FailoverTimeout, "Retry TreeConnect until succeed within timeout span"); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "TreeConnect to {0} should succeed, actual status is {1}", uncSharePath, Smb2Status.GetStatusCode(status)); treeId = innerTreeId; clientAfterFailover.SetTreeEncryption(innerTreeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "AfterFailover: Finish connecting to share {0} on server {1}", uncSharePath, server); }
/// <summary> /// Establish main channel, which includes NEGOTIATE, SESSION_SETUP and TREE_CONNECT /// </summary> /// <param name="requestDialect">Dialects in request</param> /// <param name="serverIp">Ip address on server side</param> /// <param name="clientIp">Ip address on client side</param> /// <param name="treeId">Out param for tree Id that connected</param> /// <param name="enableEncryptionPerShare">Set true if enable encryption on share, otherwise set false</param> private void EstablishMainChannel( DialectRevision[] requestDialect, IPAddress serverIp, IPAddress clientIp, out uint treeId, bool enableEncryptionPerShare = false) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Establish main channel to connect share {0} with following steps.", uncSharePath); mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp); #region Negotiate Capabilities_Values mainChannelClientCapabilities = 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; status = mainChannelClient.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid, capabilityValue: mainChannelClientCapabilities, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response); } ); #endregion #region SESSION_SETUP status = mainChannelClient.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); BaseTestSite.Log.Add( LogEntryKind.Debug, "Global encryption disabled"); #endregion #region Retrieve 2nd IP on server for alternative channel if there is #region TREE_CONNECT to IPC$ string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName); status = mainChannelClient.TreeConnect(ipcPath, out treeId); #endregion if (TestConfig.UnderlyingTransport == Smb2TransportType.Tcp) { #region IOCTL FSCTL_QUERY_NETWORK_INTERFACE_INFO NETWORK_INTERFACE_INFO_Response[] networkInfoResponses; string interfaceAddress; bool secondAddressQueried = false; status = mainChannelClient.QueryNetworkInterfaceInfo(treeId, out networkInfoResponses); foreach (NETWORK_INTERFACE_INFO_Response netInfoResp in networkInfoResponses) { interfaceAddress = netInfoResp.AddressStorage.Address; if (interfaceAddress != null) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Get NETWORK_INTERFACE_INFO: " + interfaceAddress); if (interfaceAddress == serverIps[1].ToString()) { secondAddressQueried = true; BaseTestSite.Log.Add( LogEntryKind.Debug, "Address queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO matches server second address {0}", serverIps[1].ToString()); break; } } } BaseTestSite.Assert.IsTrue( secondAddressQueried, "Second address {0} should be queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO", serverIps[1].ToString()); #endregion } #endregion #region TREE_CONNECT to share status = mainChannelClient.TreeConnect( uncSharePath, out treeId, (Packet_Header header, TREE_CONNECT_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "TreeConnect should succeed."); if (enableEncryptionPerShare) { BaseTestSite.Assert.AreEqual( ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA, ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA & response.ShareFlags, "Server should set SMB2_SHAREFLAG_ENCRYPT_DATA for ShareFlags field in TREE_CONNECT response"); } }); mainChannelClient.SetTreeEncryption(treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "Finish establishing main channel to connect share {0}", uncSharePath); }
private void DirecotryLeasing( DialectRevision[] requestDialect, DialectRevision expectedDialect, LeaseStateValues leaseState, LeaseBreakAckType leaseBreakAckType = LeaseBreakAckType.None) { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING); TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2); #endregion BaseTestSite.Log.Add( LogEntryKind.Comment, @"Start to create a directory on share \\{0}\{1} with lease state {2}", TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState); string testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare); client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); #region Negotiate BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); Capabilities_Values capabilities = 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; status = client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: capabilities, checker: (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(expectedDialect, response); if (expectedDialect >= DialectRevision.Smb30) { TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response); } }); #endregion #region SESSION_SETUP status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); uint treeId; status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client sends CREATE request for the directory with the LeaseState set to {0} in SMB2_CREATE_REQUEST_LEASE_V2.", leaseState); status = client.Create( treeId, testDirectory, CreateOptions_Values.FILE_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = leaseState } }, checker: (Packet_Header header, CREATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); if (expectedDialect == DialectRevision.Smb2002 || expectedDialect == DialectRevision.Smb21) { BaseTestSite.Assert.AreEqual( OplockLevel_Values.OPLOCK_LEVEL_NONE, response.OplockLevel, "The expected oplock level is OPLOCK_LEVEL_NONE."); } }); #endregion if (expectedDialect >= DialectRevision.Smb30) { // Break the lease with creating another file in the directory sutProtocolController.CreateFile(Path.Combine(Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare), testDirectory), CurrentTestCaseName, string.Empty); // Wait until LEASE_BREAK_Notification is received BaseTestSite.Assert.IsTrue( // Wait 5 seconds for notification arrival notificationReceived.WaitOne(SMB2TestConfig.WAIT_TIMEOUT_IN_MILLISECONDS), "LeaseBreakNotification should be raised."); if (receivedLeaseBreakNotify.Flags == LEASE_BREAK_Notification_Packet_Flags_Values.SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Server requires an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY"); #region LEASE_BREAK_ACK switch (leaseBreakAckType) { case LeaseBreakAckType.None: status = client.LeaseBreakAcknowledgment(treeId, receivedLeaseBreakNotify.LeaseKey, receivedLeaseBreakNotify.NewLeaseState); break; case LeaseBreakAckType.InvalidLeaseState: LeaseStateValues newLeaseState = LeaseStateValues.SMB2_LEASE_WRITE_CACHING; BaseTestSite.Log.Add( LogEntryKind.Comment, "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseState {0} on this LEASE_BREAK_NOTIFY", newLeaseState); status = client.LeaseBreakAcknowledgment( treeId, receivedLeaseBreakNotify.LeaseKey, newLeaseState, checker: (header, response) => { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "LEASE_BREAK_ACK with invalid LeaseState is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); BaseTestSite.CaptureRequirementIfAreEqual( Smb2Status.STATUS_REQUEST_NOT_ACCEPTED, header.Status, RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Id, RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Description); }); break; case LeaseBreakAckType.InvalidLeaseKey: Guid invalidLeaseKey = Guid.NewGuid(); BaseTestSite.Log.Add( LogEntryKind.Debug, "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseKey {0} on this LEASE_BREAK_NOTIFY", invalidLeaseKey); status = client.LeaseBreakAcknowledgment( treeId, invalidLeaseKey, receivedLeaseBreakNotify.NewLeaseState, checker: (header, response) => { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "LEASE_BREAK_ACK with invalid LeaseKey is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); BaseTestSite.CaptureRequirementIfAreEqual( Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND, header.Status, RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id, RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description); }); break; case LeaseBreakAckType.InvalidClientGuid: BaseTestSite.Log.Add(LogEntryKind.Debug, "Initialize a new different client to attempts to send LEASE_BREAK_ACK"); Smb2FunctionalClient newClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); newClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); #region Negotiate status = newClient.Negotiate( requestDialect, 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); #endregion #region SESSION_SETUP status = newClient.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share uint newTreeId; status = newClient.TreeConnect(uncSharePath, out newTreeId); #endregion status = newClient.LeaseBreakAcknowledgment( newTreeId, receivedLeaseBreakNotify.LeaseKey, receivedLeaseBreakNotify.NewLeaseState, checker: (header, response) => { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "LEASE_BREAK_ACK is not expected to SUCCESS when the open is closed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); BaseTestSite.CaptureRequirementIfAreEqual( Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND, header.Status, RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id, RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description); }); status = newClient.TreeDisconnect(newTreeId); status = newClient.LogOff(); BaseTestSite.Log.Add( LogEntryKind.Comment, "Initialize a new different client to attempts to send LEASE_BREAK_ACK"); break; default: throw new InvalidOperationException("Unexpected LeaseBreakAckType " + leaseBreakAckType); } #endregion } else { BaseTestSite.Log.Add( LogEntryKind.Debug, "Server does not require an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY"); } } BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF"); #region TREE_DISCONNECT status = client.TreeDisconnect(treeId); #endregion #region LOGOFF status = client.LogOff(); #endregion BaseTestSite.Log.Add( LogEntryKind.Comment, @"Complete creating a directory on share \\{0}\{1} with lease state {2}", TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState); }
private void ReadFromAlternativeChannel( DialectRevision[] requestDialect, DialectRevision expectedDialect, IPAddress serverIp, IPAddress clientIp, uint lengthRead, uint treeId, FILEID fileId, out string contentRead) { contentRead = ""; alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp); #region Negotiate status = alternativeChannelClient.Negotiate( requestDialect, 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, "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(expectedDialect, response); if (Smb2Utility.IsSmb3xFamily(expectedDialect)) { TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response); } }); #endregion #region SESSION_SETUP status = alternativeChannelClient.AlternativeChannelSessionSetup( mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken, checker: (header, response) => { }); #endregion if (expectedDialect == DialectRevision.Smb2002 || expectedDialect == DialectRevision.Smb21) { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_REQUEST_NOT_ACCEPTED, status, "SessionSetup is expected to fail with STATUS_REQUEST_NOT_ACCEPTED."); BaseTestSite.Log.Add( LogEntryKind.Debug, "Dialect " + expectedDialect + " is not supported for multiple channel and fail as expected with STATUS_REQUEST_NOT_ACCEPTED."); } else { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "SessionSetup should succeed"); #region READ status = alternativeChannelClient.Read(treeId, fileId, 0, lengthRead, out contentRead); #endregion #region CLOSE file status = alternativeChannelClient.Close(treeId, fileId); #endregion #region TREE_DISCONNECT status = alternativeChannelClient.TreeDisconnect(treeId); #endregion #region LOGOFF status = alternativeChannelClient.LogOff(); #endregion } alternativeChannelClient.Disconnect(); }
private void WriteFromMainChannel( DialectRevision[] requestDialect, DialectRevision expectedDialect, IPAddress serverIp, IPAddress clientIp, string contentWrite, bool isNicRedundantOnServer, out uint treeId, out FILEID fileId) { mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp); #region Negotiate mainChannelClient.Negotiate( requestDialect, 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, "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(expectedDialect, response); if (Smb2Utility.IsSmb3xFamily(expectedDialect)) { TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response); } }); #endregion #region SESSION_SETUP mainChannelClient.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region Retrieve 2nd IP on server for alternative channel if there is if (TestConfig.UnderlyingTransport == Smb2TransportType.Tcp && isNicRedundantOnServer && TestConfig.IsIoCtlCodeSupported(CtlCode_Values.FSCTL_QUERY_NETWORK_INTERFACE_INFO)) { #region TREE_CONNECT to IPC$ string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName); mainChannelClient.TreeConnect(ipcPath, out treeId); #endregion #region IOCTL FSCTL_QUERY_NETWORK_INTERFACE_INFO NETWORK_INTERFACE_INFO_Response[] networkInfoResponses; string interfaceAddress; bool secondAddressQueried = false; mainChannelClient.QueryNetworkInterfaceInfo(treeId, out networkInfoResponses); foreach (NETWORK_INTERFACE_INFO_Response netInfoResp in networkInfoResponses) { interfaceAddress = netInfoResp.AddressStorage.Address; if (interfaceAddress != null) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Get NETWORK_INTERFACE_INFO: " + interfaceAddress); if (interfaceAddress == serverIps[1].ToString()) { secondAddressQueried = true; BaseTestSite.Log.Add(LogEntryKind.Debug, "Address queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO matches server second address {0}", serverIps[1].ToString()); break; } } } BaseTestSite.Assert.IsTrue( secondAddressQueried, "Second address {0} should be queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO", serverIps[1].ToString()); #endregion } #endregion #region TREE_CONNECT to share string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); mainChannelClient.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE Smb2CreateContextResponse[] serverCreateContexts; mainChannelClient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE, out fileId, out serverCreateContexts); #endregion if (Smb2Utility.IsSmb3xFamily(expectedDialect)) { #region WRITE mainChannelClient.Write(treeId, fileId, contentWrite); #endregion } }
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\"."); }
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); TestConfig.CheckDialectIOCTLCompatibility(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"); Guid clientGuid = Guid.NewGuid(); DialectRevision[] requestDialects = TestConfig.RequestDialects; 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.Smb30, 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; switch (requestType) { case ValidateNegotiateInfoRequestType.None: 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; VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResp; 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) { status = client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: (header, response) => { }); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "ValidateNegotiateInfo should succeed "); 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"); client.TreeDisconnect(treeId); client.LogOff(); return; } uint maxOutputResponse = (requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse) ? (uint)0: 64 * 1024; try { client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, maxOutputResponse, (header, response) => { }); client.TreeDisconnect(treeId); client.LogOff(); return; } catch { } string errCondition = requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse ? "MaxOutputResponse in the request is less than the size of a VALIDATE_NEGOTIATE_INFO Response" : "there's invalid info in the request"; BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when {0}", errCondition); }
public void MultipleChannel_SecondChannelSessionSetupFailAtFirstTime() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL); #endregion string contentWrite; string contentRead; uint treeId; FILEID fileId; contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); BaseTestSite.Assert.IsTrue( clientIps.Count > 0, "Client should have at least one IP address"); BaseTestSite.Assert.IsTrue( serverIps.Count > 0, "Server should have more than one IP address"); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Start to write content to file from main channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[0].ToString()); WriteFromMainChannel( serverIps[0], clientIps[0], contentWrite, false, out treeId, out fileId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Set up alternative channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[0].ToString()); alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIps[1], clientIps[1]); alternativeChannelClient.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: clientGuid, checker: (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); if (Smb2Utility.IsSmb3xFamily(DialectRevision.Smb311)) { TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response); } }); status = alternativeChannelClient.AlternativeChannelSessionSetup( mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken, checker: (header, response) => { }, invalidToken: true); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_INVALID_PARAMETER, status, "The first SessionSetup from alternative channel should return STATUS_INVALID_PARAMETER since the token in buffer field is set to an invalid value."); status = alternativeChannelClient.AlternativeChannelSessionSetup( mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken, checker: (header, response) => { }); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "The second SessionSetup from alternative channel should succeed"); contentRead = ""; status = alternativeChannelClient.Read(treeId, fileId, 0, (uint)contentWrite.Length, out contentRead); // Read should succeed. // If Read response returns STATUS_ACCESS_DEINIED, it means signingkey used by server is wrong, and so that the PreauthIntegrityHashValue (which is used to generate the signingkey) calculated by server is wrong. // It is very possible that server uses the first failed session setup request/response (alternative channel) to calculate PreauthIntegrityHashValue, which is wrong. BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Read from the alternative channel should succeed"); alternativeChannelClient.Close(treeId, fileId); alternativeChannelClient.TreeDisconnect(treeId); alternativeChannelClient.LogOff(); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Verify the contents read from alternative channel are the same as the one written by main channel."); BaseTestSite.Assert.IsTrue( contentWrite.Equals(contentRead), "Content read should be identical to content written."); }
/// <summary> /// Connect share on file server /// </summary> /// <param name="serverIp">Server IP address used for connection</param> /// <param name="clientIp">Client IP address used for connection</param> /// <param name="client">Client object to initialize the connection</param> /// <param name="treeId">Out param tree id connected</param> /// <param name="enableEncryptionPerShare">True indicates encryption enabled per share, otherwise disabled</param> private void ConnectShare(IPAddress serverIp, IPAddress clientIp, Smb2FunctionalClient client, out uint treeId, bool enableEncryptionPerShare = false) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Connect to share {0} with following steps.", uncSharePath); BaseTestSite.Log.Add( LogEntryKind.Debug, "Connect to server via Nic with Ip {0}", clientIp.ToString()); client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp); #region Negotiate 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; status = client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilities, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); }); #endregion #region SESSION_SETUP status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); BaseTestSite.Log.Add( LogEntryKind.Debug, "Global encryption disabled"); #endregion #region TREE_CONNECT to share status = client.TreeConnect( uncSharePath, out treeId, (Packet_Header header, TREE_CONNECT_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "TreeConnect should succeed."); if (enableEncryptionPerShare) { BaseTestSite.Assert.AreEqual( ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA, ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA & response.ShareFlags, "Server should set SMB2_SHAREFLAG_ENCRYPT_DATA for ShareFlags field in TREE_CONNECT response"); } }); client.SetTreeEncryption(treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "Finish connecting to share {0}", uncSharePath); }
/// <summary> /// Connect to share on general clustered file server before failover happens, include NEGOTIATE, SESSION_SETUP, TREE_CONNECT /// </summary> /// <param name="server">Name of clustered file server</param> /// <param name="fsType">Type of clustered file server</param> /// <param name="treeId">Out param for tree Id that connected</param> /// <param name="enableEncryptionPerShare">Set true if enable encryption on share, otherwise set false</param> private void ConnectGeneralFileServerBeforeFailover(string server, out uint treeId, bool enableEncryptionPerShare = false) { BaseTestSite.Log.Add( LogEntryKind.Debug, "BeforeFailover: Connect share {0} on server {1} with following steps.", uncSharePath, server); GetGeneralFileServerClusterOwner(server); clientBeforeFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, currentAccessIp); #region Negotiate Capabilities_Values clientCapabilitiesBeforeFAilover = 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; status = clientBeforeFailover.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilitiesBeforeFAilover, clientGuid: clientGuid, checker: (Packet_Header header, NEGOTIATE_Response response) => { TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); } ); #endregion #region SESSION_SETUP status = clientBeforeFailover.SessionSetup( TestConfig.DefaultSecurityPackage, server, TestConfig.AccountCredential, TestConfig.UseServerGssToken); BaseTestSite.Log.Add( LogEntryKind.Debug, "Global encryption disabled"); #endregion #region TREE_CONNECT to share status = clientBeforeFailover.TreeConnect( uncSharePath, out treeId, (Packet_Header header, TREE_CONNECT_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "TreeConnect should succeed."); if (enableEncryptionPerShare) { BaseTestSite.Assert.AreEqual( ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA, ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA & response.ShareFlags, "Server should set SMB2_SHAREFLAG_ENCRYPT_DATA for ShareFlags field in TREE_CONNECT response"); } BaseTestSite.Assert.IsTrue(response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY), "CA Share should have SHARE_CAP_CONTINUOUS_AVAILABILITY bit set for Capabilities in TreeConnect response."); }); clientBeforeFailover.SetTreeEncryption(treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "BeforeFailover: Finish connecting to share {0} on server {1}", uncSharePath, server); }
public void FileServerFailover_BlockCreateFromDifferentClient() { uncSharePath = Smb2Utility.GetUncPath(TestConfig.ClusteredFileServerName, TestConfig.ClusteredFileShare); #region From one client open a file and request persistent handle before failover BaseTestSite.Log.Add(LogEntryKind.TestStep, "From one client open a file and request persistent handle before failover"); FILEID fileIdBeforeFailover; uint treeIdBeforeFailover; BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: Connect to general file server {0}.", TestConfig.ClusteredFileServerName); ConnectGeneralFileServerBeforeFailover(TestConfig.ClusteredFileServerName, out treeIdBeforeFailover); #region CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT."); Smb2CreateContextResponse[] serverCreateContexts; createGuid = Guid.NewGuid(); status = clientBeforeFailover.Create( treeIdBeforeFailover, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdBeforeFailover, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid, Flags = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT, Timeout = 3600000, }, }); #endregion #endregion BaseTestSite.Log.Add( LogEntryKind.TestStep, "Disable owner node to simulate failover"); FailoverServer(currentAccessIp, TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer); #region From a different client try to open the same file after failover BaseTestSite.Log.Add( LogEntryKind.TestStep, "AfterFailover: From a different client try to open the same file"); DoUntilSucceed(() => clientAfterFailover.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ClusteredFileServerName, currentAccessIp), TestConfig.FailoverTimeout, "Retry to connect to server until succeed within timeout span"); #region Connect to the same share of the same general file server BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Connect to the same share of the same general file server."); #region Negotiate Capabilities_Values clientCapabilitiesAfterFailover = 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; status = clientAfterFailover.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilitiesAfterFailover, checker: (Packet_Header header, NEGOTIATE_Response response) => { TestConfig.CheckNegotiateDialect(DialectRevision.Smb21, response); }); #endregion #region SESSION_SETUP status = clientAfterFailover.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.ClusteredFileServerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share uint treeIdAfterFailover = 0; //Retry TreeConnect until succeed within timeout span status = DoUntilSucceed( () => clientAfterFailover.TreeConnect(uncSharePath, out treeIdAfterFailover, (header, response) => { }), TestConfig.FailoverTimeout, "Retry TreeConnect until succeed within timeout span"); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "TreeConnect to {0} should succeed, actual status is {1}", uncSharePath, Smb2Status.GetStatusCode(status)); #endregion #endregion #region CREATE to open the same file BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Send CREATE request using incompatible share access with previous CREATE and this should result violation"); FILEID fileIdAfterFailover; status = clientAfterFailover.Create( treeIdAfterFailover, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdAfterFailover, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, null, // Incompatible share access with previous CREATE request and will result violation shareAccess: ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_DELETE, checker: (header, response) => { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "From a different client try to open the same file after failover should not success"); }); #endregion #endregion }
public void BVT_SetGetIntegrityInfo() { #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_SET_INTEGRITY_INFORMATION, CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION); #endregion client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client creates a file by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE"); status = client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, checker: (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); }); status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); uint treeId; string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.FileShareSupportingIntegrityInfo); status = client.TreeConnect(uncSharePath, out treeId); FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; status = client.Create( treeId, GetTestFileName(uncSharePath), CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); FSCTL_GET_INTEGRITY_INFO_OUTPUT getIntegrityInfo; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_GET_INTEGRITY_INFORMATION."); status = client.GetIntegrityInfo(treeId, fileId, out getIntegrityInfo); BaseTestSite.Log.Add( LogEntryKind.Debug, "Integrity info returned in FSCTL_GET_INTEGRITY_INFO request: ChecksumAlgorithm {0}, Flags {1}, ChecksumChunkSizeInBytes {2}, ClusterSizeInBytes {3}", getIntegrityInfo.ChecksumAlgorithm, getIntegrityInfo.Flags, getIntegrityInfo.ChecksumChunkSizeInBytes, getIntegrityInfo.ClusterSizeInBytes); FSCTL_SET_INTEGRIY_INFO_INPUT setIntegrityInfo; setIntegrityInfo.ChecksumAlgorithm = FSCTL_SET_INTEGRITY_INFO_INPUT_CHECKSUMALGORITHM.CHECKSUM_TYPE_CRC64; setIntegrityInfo.Flags = FSCTL_SET_INTEGRITY_INFO_INPUT_FLAGS.FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF; setIntegrityInfo.Reserved = FSCTL_SET_INTEGRITY_INFO_INPUT_RESERVED.V1; byte[] buffer = TypeMarshal.ToBytes <FSCTL_SET_INTEGRIY_INFO_INPUT>(setIntegrityInfo); BaseTestSite.Log.Add( LogEntryKind.Debug, "Attempt to set integrity info with ChecksumAlgrithm {0}, Flags {1}", setIntegrityInfo.ChecksumAlgorithm, setIntegrityInfo.Flags); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_SET_INTEGRITY_INFORMATION after changed the value of the following fields in FSCTL_SET_INTEGRIY_INFO_INPUT: ChecksumAlgorithm, Flags, Reserved."); status = client.SetIntegrityInfo(treeId, fileId, buffer); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_GET_INTEGRITY_INFORMATION."); status = client.GetIntegrityInfo(treeId, fileId, out getIntegrityInfo); BaseTestSite.Log.Add( LogEntryKind.Debug, "Current ChecksumAlgorithm is " + getIntegrityInfo.ChecksumAlgorithm); BaseTestSite.Assert.AreEqual( (ushort)setIntegrityInfo.ChecksumAlgorithm, (ushort)getIntegrityInfo.ChecksumAlgorithm, "ChecksumAlgorithm field after set should be {0}, actual value is {1}", setIntegrityInfo.ChecksumAlgorithm, getIntegrityInfo.ChecksumAlgorithm); BaseTestSite.Log.Add( LogEntryKind.Debug, "Current Flags is " + getIntegrityInfo.Flags); BaseTestSite.Assert.AreEqual( (uint)setIntegrityInfo.Flags, (uint)getIntegrityInfo.Flags, "Flags field after set should be {0}, actual value is {1}", setIntegrityInfo.Flags, getIntegrityInfo.Flags); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF."); status = client.Close(treeId, fileId); status = client.TreeDisconnect(treeId); status = client.LogOff(); }