private void InitializeClient(LeasingClientInfo clientInfo, ModelDialectRevision dialect, bool isClientSupportDirectoryLeasing = false) { #region Connect to server switch (testConfig.UnderlyingTransport) { case Smb2TransportType.Tcp: Site.Assert.IsTrue( testConfig.SutIPAddress != null && testConfig.SutIPAddress != System.Net.IPAddress.None, "Server IP should not be empty when transport type is TCP."); Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over TCP", testConfig.SutIPAddress.ToString()); clientInfo.Client.ConnectOverTCP(testConfig.SutIPAddress); break; case Smb2TransportType.NetBios: Site.Assert.IsFalse(string.IsNullOrEmpty(testConfig.SutComputerName), "Server name should not be null when transport type is NetBIOS."); Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over NetBios", testConfig.SutComputerName); clientInfo.Client.ConnectOverNetbios(testConfig.SutComputerName); break; default: Site.Assert.Fail("The transport type is {0}, but currently only Tcp and NetBIOS are supported.", testConfig.UnderlyingTransport); break; } #endregion uint status = 0; Packet_Header responseHeader = new Packet_Header(); DialectRevision selectedDialect; DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)); NEGOTIATE_Response negotiatePayload; #region Negotiate status = clientInfo.Client.Negotiate(0, 1, Packet_Header_Flags_Values.NONE, clientInfo.MessageId++, dialects, SecurityMode_Values.NONE, isClientSupportDirectoryLeasing ? Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING : Capabilities_Values.NONE, clientInfo.ClientGuid, out selectedDialect, out clientInfo.ServerGssToken, out responseHeader, out negotiatePayload); Site.Assert.AreEqual(ModelUtility.GetDialectRevision(dialect), negotiatePayload.DialectRevision, "DialectRevision 0x{0:x4} is expected.", (ushort)ModelUtility.GetDialectRevision(dialect)); Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Negotiation is expected success"); clientInfo.Dialect = selectedDialect; #region Validate Negotiate Response if (Smb2Utility.IsSmb3xFamily(selectedDialect)) { Site.Assert.AreEqual<bool>(leasingConfig.IsLeasingSupported, negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING), "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_LEASING 0x00000002.", leasingConfig.IsLeasingSupported ? "contains" : "does not contain"); Site.Assert.AreEqual<bool>(leasingConfig.IsDirectoryLeasingSupported & isClientSupportDirectoryLeasing, negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING), "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020.", leasingConfig.IsDirectoryLeasingSupported & isClientSupportDirectoryLeasing ? "contains" : "does not contain"); } else if (selectedDialect == DialectRevision.Smb21) { Site.Assert.AreEqual<bool>(leasingConfig.IsLeasingSupported, negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING), "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_LEASING 0x00000002.", leasingConfig.IsLeasingSupported ? "contains" : "does not contain"); Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING), "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020."); } else { Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING), "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_LEASING 0x00000002."); Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING), "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020."); } #endregion #endregion #region SESSION_SETUP Packet_Header header; SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( testConfig.DefaultSecurityPackage, testConfig.AccountCredential, Smb2Utility.GetCifsServicePrincipalName(testConfig.SutComputerName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); // Server GSS token is used only for Negotiate authentication when enabled if (testConfig.DefaultSecurityPackage == SecurityPackageType.Negotiate && testConfig.UseServerGssToken) sspiClientGss.Initialize(clientInfo.ServerGssToken); else sspiClientGss.Initialize(null); do { status = clientInfo.Client.SessionSetup( 1, 64, Packet_Header_Flags_Values.NONE, clientInfo.MessageId++, clientInfo.SessionId, SESSION_SETUP_Request_Flags.NONE, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, SESSION_SETUP_Request_Capabilities_Values.NONE, 0, sspiClientGss.Token, out clientInfo.SessionId, out clientInfo.ServerGssToken, out header, out sessionSetupResponse); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && clientInfo.ServerGssToken != null && clientInfo.ServerGssToken.Length > 0) { sspiClientGss.Initialize(clientInfo.ServerGssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); if (status == Smb2Status.STATUS_SUCCESS) { clientInfo.SessionKey = sspiClientGss.SessionKey; clientInfo.Client.GenerateCryptoKeys(clientInfo.SessionId, clientInfo.SessionKey, true, false); } clientInfo.GrantedCredit = header.CreditRequestResponse; Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "SessionSetup should succeed, actual status is {0}", Smb2Status.GetStatusCode(status)); #endregion #region TREE_CONNECT to share TREE_CONNECT_Response treeConnectPayload; status = clientInfo.Client.TreeConnect(1, 1, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, uncSharePath, out clientInfo.TreeId, out header, out treeConnectPayload); Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "TreeConnect to {0} should succeed, actual status is {1}", uncSharePath, Smb2Status.GetStatusCode(status)); if (treeConnectPayload.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK)) { Site.Assert.Inconclusive("This test case is not applicable for the share whose ShareFlags includes SHAREFLAG_FORCE_LEVELII_OPLOCK."); } if (treeConnectPayload.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT)) { Site.Assert.Inconclusive("This test case is not applicable for the share whose Capabilities includes SHARE_CAP_SCALEOUT."); } #endregion }
private void CreateFile(ModelDialectRevision dialect, string target, bool isDirectory) { LeasingClientInfo clientInfo = new LeasingClientInfo(testConfig.Timeout, testConfig); clientInfo.File = target; InitializeClient(clientInfo, dialect); Packet_Header header; CREATE_Response createResponse; Smb2CreateContextResponse[] serverCreateContexts; uint status = 0; status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, clientInfo.File, AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE, ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, CreateDisposition_Values.FILE_OPEN_IF, File_Attributes.NONE, ImpersonationLevel_Values.Impersonation, SecurityFlags_Values.NONE, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, null, out clientInfo.FileId, out serverCreateContexts, out header, out createResponse); clientInfo.GrantedCredit = header.CreditRequestResponse; Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Create a file {0} should succeed, actual status is {1}", clientInfo.File, Smb2Status.GetStatusCode(status)); clientInfo.Cleanup(); }
private void DeleteFile(ModelDialectRevision dialect, string target, bool isDirectory) { LeasingClientInfo clientInfo = new LeasingClientInfo(testConfig.Timeout, testConfig); InitializeClient(clientInfo, dialect); Packet_Header header; CREATE_Response createResponse; Smb2CreateContextResponse[] serverCreateContexts; uint status = 0; status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, target, AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE, ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE, (isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE) | CreateOptions_Values.FILE_DELETE_ON_CLOSE, CreateDisposition_Values.FILE_OPEN_IF, File_Attributes.NONE, ImpersonationLevel_Values.Impersonation, SecurityFlags_Values.NONE, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, null, out clientInfo.FileId, out serverCreateContexts, out header, out createResponse); clientInfo.GrantedCredit = header.CreditRequestResponse; FileDispositionInformation deleteInfo; deleteInfo.DeletePending = 1; byte[] inputBuffer; inputBuffer = TypeMarshal.ToBytes<FileDispositionInformation>(deleteInfo); SET_INFO_Response responsePayload; clientInfo.Client.SetInfo( 1, 1, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, SET_INFO_Request_InfoType_Values.SMB2_0_INFO_FILE, (byte)FileInformationClasses.FileDispositionInformation, SET_INFO_Request_AdditionalInformation_Values.NONE, clientInfo.FileId, inputBuffer, out header, out responsePayload); clientInfo.Cleanup(); }
public void SetupConnection(ModelDialectRevision dialect, ClientSupportDirectoryLeasingType clientSupportDirectoryLeasingType) { string parentDirectory = "LeasingDir_" + Guid.NewGuid().ToString(); CreateFile(dialect, parentDirectory, true); originalClient = new LeasingClientInfo(testConfig.Timeout, testConfig); originalClient.ParentDirectory = parentDirectory; originalClient.File = parentDirectory + "\\" + Guid.NewGuid().ToString(); originalClient.Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived); bool isClientSupportDirectoryLeasing = clientSupportDirectoryLeasingType == ClientSupportDirectoryLeasingType.ClientSupportDirectoryLeasing; InitializeClient(originalClient, dialect, isClientSupportDirectoryLeasing); clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig, originalClient.ClientGuid)); // SameClientId clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig, originalClient.ClientGuid)); // SameClientGuidDifferentLeaseKey clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig)); // Second client clients[(int)OperatorType.SameClientId].Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(clients[(int)OperatorType.SameClientId].OnLeaseBreakNotificationReceived); }