/// <summary> /// Set up connection with server. /// Including 5 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect 5. Create an open on the vhd file /// </summary> /// <param name="serverName">server name</param> /// <param name="serverIP">server IP address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <param name="shareName">Name of the share when TreeConnect</param> /// <param name="vhdName">Name of the vhd file</param> /// <returns>Status of the create operation</returns> public uint ConnectToVHD( string serverName, IPAddress serverIP, string domain, string userName, string password, SecurityPackageType securityPackage, bool useServerToken, string shareName, string vhdName) { transport = new Smb2ClientTransport(); transport.ConnectShare(serverName, serverIP, domain, userName, password, shareName, securityPackage, useServerToken); uint status; Smb2CreateContextResponse[] serverContexts; CREATE_Response response; transport.Create( vhdName, // The desired access is set the same as Windows client's behavior FsFileDesiredAccess.GENERIC_READ | FsFileDesiredAccess.GENERIC_WRITE | FsFileDesiredAccess.DELETE, ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE, FsImpersonationLevel.Impersonation, FsFileAttribute.NONE, FsCreateDisposition.FILE_OPEN_IF, FsCreateOption.NONE, null, out status, out serverContexts, out response); return(status); }
/// <summary> /// Set up connection with server. /// Including 5 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect 5. Create an open on the vhd file /// </summary> /// <param name="serverName">server name</param> /// <param name="serverIP">server IP address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <param name="shareName">Name of the share when TreeConnect</param> /// <param name="vhdName">Name of the vhd file</param> /// <returns>Status of the create operation</returns> public uint ConnectToVHD( string serverName, IPAddress serverIP, string domain, string userName, string password, SecurityPackageType securityPackage, bool useServerToken, string shareName, string vhdName) { transport = new Smb2ClientTransport(); transport.ConnectShare(serverName, serverIP, domain, userName, password, shareName, securityPackage, useServerToken); uint status; Smb2CreateContextResponse[] serverContexts; CREATE_Response response; transport.Create( vhdName, // The desired access is set the same as Windows client's behavior FsFileDesiredAccess.GENERIC_READ | FsFileDesiredAccess.GENERIC_WRITE | FsFileDesiredAccess.DELETE, ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE, FsImpersonationLevel.Impersonation, FsFileAttribute.NONE, FsCreateDisposition.FILE_OPEN_IF, FsCreateOption.NONE, null, out status, out serverContexts, out response); return status; }
public DtlsClientSecurityContext( SecurityPackageType packageType, CertificateCredential clientCredential, string serverPrincipal, ClientSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { if (clientCredential == null) { clientCredential = new CertificateCredential(null); } this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; SspiUtility.DtlsAcquireCredentialsHandle( packageType, clientCredential, serverPrincipal, NativeMethods.SECPKG_CRED_OUTBOUND, out this.credentialHandle); bStreamSizes = false; hasMoreFragments = false; }
private uint SessionSetup( Packet_Header_Flags_Values headerFlags, SESSION_SETUP_Request_Flags sessionSetupFlags, SESSION_SETUP_Request_SecurityMode_Values securityMode, SESSION_SETUP_Request_Capabilities_Values capabilities, ulong previousSessionId, SecurityPackageType securityPackageType, string serverName, byte[] token, out byte[] serverGssToken, ushort creditRequest = 64) { Packet_Header header; SESSION_SETUP_Response sessionSetupResponse; uint status; status = client.SessionSetup( 1, creditRequest, headerFlags, messageId++, sessionId, sessionSetupFlags, securityMode, capabilities, previousSessionId, token, out sessionId, out serverGssToken, out header, out sessionSetupResponse); return(status); }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name of ip address</param> /// <param name="client">client name of ip address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception> public abstract void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken);
/// <summary> /// Constructor /// </summary> /// <param name="packageType">Specifies the name of the security package with which these credentials will be used /// </param> /// <param name="serverCredential">The credential of server, if null, use default user account.</param> /// <param name="serverPrincipal">Server principal name</param> /// <param name="contextAttributes">Bit flags that specify the attributes required by the server to establish /// the context</param> /// <param name="targetDataRep">The data representation, such as byte ordering, on the target. This parameter /// can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.</param> public SspiServerSecurityContext( SecurityPackageType packageType, CertificateCredential serverCredential, string serverPrincipal, ServerSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; this.AcquireCredentialsHandle(serverCredential); }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name</param> /// <param name="client">client name</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="InvalidOperationException">Fail to set up connection with server</exception> public override void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken) { this.internalTimeout = timeout; ConnectShare(server, 445, IpVersion.Any, domain, userName, password, IPC_SHARE, securityPackage, useServerToken); }
public DtlsServerSecurityContext( SecurityPackageType packageType, CertificateCredential serverCredential, string serverPrincipal, ServerSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; this.Context = new Sspi.DtlsServerSecurityContext(packageType, serverCredential, serverPrincipal, contextAttributes, targetDataRep); }
/// <summary> /// Constructor with client credential, principal of server, ContextAttributes and TargetDataRep. /// </summary> /// <param name="packageType">Specifies the name of the security package with which these credentials will be used /// </param> /// <param name="clientCredential">Client account credential, if null, use default user account</param> /// <param name="serverPrincipal">Server principal name</param> /// <param name="contextAttributes">Context attributes</param> /// <param name="targetDataRep">The data representation, such as byte ordering, on the target. /// This parameter can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.</param> public SspiClientSecurityContext( SecurityPackageType packageType, AccountCredential clientCredential, string serverPrincipal, ClientSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; this.AcquireCredentialsHandle(clientCredential); }
/// <summary> /// Constructor /// </summary> /// <param name="logger">Enable the log</param> /// <param name="contentServerName">The ContentServer name</param> /// <param name="hostedCacheServerName">The HostedCacheServer name</param> /// <param name="accountCredential">Account credential</param> /// <param name="securityPackageType">security package: NTLM, Negotiate, kerbrose</param> public BranchCacheDetector(Logger logger, string contentServerName, string hostedCacheServerName, AccountCredential accountCredential, SecurityPackageType securityPackageType = SecurityPackageType.Negotiate) { ContentServerName = contentServerName; HostedCacheServerName = hostedCacheServerName; Credential = accountCredential; SecurityPackageType = securityPackageType; logWriter = logger; logWriter.AddLog(LogLevel.Information, string.Format("ContentServerName: {0}", ContentServerName)); logWriter.AddLog(LogLevel.Information, string.Format("HostedCacheServerName: {0}", HostedCacheServerName)); logWriter.AddLog(LogLevel.Information, string.Format("DomainName: {0}", Credential.DomainName)); logWriter.AddLog(LogLevel.Information, string.Format("UserName: {0}", Credential.AccountName)); logWriter.AddLog(LogLevel.Information, string.Format("UserPassword: {0}", Credential.Password)); logWriter.AddLog(LogLevel.Information, string.Format("SecurityPackageType: {0}", SecurityPackageType.ToString())); logWriter.AddLineToLog(LogLevel.Information); }
public FSDetector(Logger logger, string targetSUT, AccountCredential accountCredential, SecurityPackageType securityPackageType) { SUTName = targetSUT; Credential = accountCredential; SecurityPackageType = securityPackageType; logWriter = logger; logWriter.AddLog(LogLevel.Information, string.Format("SutName: {0}", SUTName)); logWriter.AddLog(LogLevel.Information, string.Format("DomainName: {0}", Credential.DomainName)); logWriter.AddLog(LogLevel.Information, string.Format("UserName: {0}", Credential.AccountName)); logWriter.AddLog(LogLevel.Information, string.Format("UserPassword: {0}", Credential.Password)); logWriter.AddLog(LogLevel.Information, string.Format("SecurityPackageType: {0}", SecurityPackageType.ToString())); logWriter.AddLineToLog(LogLevel.Information); }
public DtlsClientSecurityContext( SecurityPackageType packageType, CertificateCredential clientCredential, string serverPrincipal, ClientSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { if (clientCredential == null) { clientCredential = new CertificateCredential(null); } this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; this.Context = new Sspi.DtlsClientSecurityContext(packageType, clientCredential, serverPrincipal, contextAttributes, targetDataRep) as IDtlsClientSecurityContext; }
/// <summary> /// Constructor /// </summary> /// <param name="packageType">Specifies the name of the security package with which these credentials will be used /// </param> /// <param name="serverCredential">The credential of server, if null, use default user account.</param> /// <param name="serverPrincipal">Server principal name</param> /// <param name="contextAttributes">Bit flags that specify the attributes required by the server to establish /// the context</param> /// <param name="targetDataRep">The data representation, such as byte ordering, on the target. This parameter /// can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.</param> public SspiServerSecurityContext( SecurityPackageType packageType, AccountCredential serverCredential, string serverPrincipal, ServerSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; SspiUtility.AcquireCredentialsHandle( packageType, serverCredential, serverPrincipal, NativeMethods.SECPKG_CRED_INBOUND, out this.credentialHandle); }
public TestConfig(ITestSite site) { ContentTransport = (ContentInformationTransport)Enum.Parse(typeof(ContentInformationTransport), site.Properties["ContentTransport"]); SupportBranchCacheV1 = bool.Parse(site.Properties["SupportBranchCacheV1"]); SupportBranchCacheV2 = bool.Parse(site.Properties["SupportBranchCacheV2"]); ContentServerComputerName = site.Properties["ContentServerComputerName"]; HostedCacheServerComputerName = site.Properties["HostedCacheServerComputerName"]; ClientPeerComputerName = site.Properties["ClientPeerComputerName"]; DomainName = site.Properties["DomainName"]; UserName = site.Properties["UserName"]; UserPassword = site.Properties["UserPassword"]; HashLevelType = (ServerHashLevel)Enum.Parse(typeof(ServerHashLevel), site.Properties["SupportedHashLevel"]); SecurityPackageType = (SecurityPackageType)Enum.Parse(typeof(SecurityPackageType), site.Properties["SecurityPackageType"]); ServerSecret = Encoding.Unicode.GetBytes(site.Properties["ServerSecret"]); Timeout = TimeSpan.FromSeconds(int.Parse(site.Properties["Timeout"])); RetryInterval = TimeSpan.FromSeconds(int.Parse(site.Properties["RetryInterval"])); NegativeTestTimeout = TimeSpan.FromSeconds(int.Parse(site.Properties["NegativeTestTimeout"])); SharedFolderName = site.Properties["SharedFolderName"]; NameOfFileWithMultipleSegments = site.Properties["NameOfFileWithMultipleSegments"]; NameOfFileWithMultipleBlocks = site.Properties["NameOfFileWithMultipleBlocks"]; NameOfFileWithSingleBlock = site.Properties["NameOfFileWithSingleBlock"]; WebsiteLocalPath = site.Properties["WebsiteLocalPath"]; FileShareLocalPath = site.Properties["FileShareLocalPath"]; SupportWebsiteForcedHashGeneration = bool.Parse(site.Properties["SupportWebsiteForcedHashGeneration"]); SupportFileShareForcedHashGeneration = bool.Parse(site.Properties["SupportFileShareForcedHashGeneration"]); ContentServerHTTPListenPort = int.Parse(site.Properties["ContentServerHTTPListenPort"]); HostedCacheServerHTTPListenPort = int.Parse(site.Properties["HostedCacheServerHTTPListenPort"]); HostedCacheServerHTTPSListenPort = int.Parse(site.Properties["HostedCacheServerHTTPSListenPort"]); ClientContentRetrievalListenPort = int.Parse(site.Properties["ClientContentRetrievalListenPort"]); }
public DtlsServerSecurityContext( SecurityPackageType packageType, CertificateCredential serverCredential, string serverPrincipal, ServerSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; SspiUtility.DtlsAcquireCredentialsHandle( packageType, serverCredential, serverPrincipal, NativeMethods.SECPKG_CRED_INBOUND, out this.credentialHandle); bStreamSizes = false; hasMoreFragments = false; }
public uint SessionSetup( SESSION_SETUP_Request_SecurityMode_Values securityMode, SESSION_SETUP_Request_Capabilities_Values capabilities, SecurityPackageType securityPackageType, string serverName, byte[] token, out byte[] serverGssToken, ushort creditRequest = 64) { return(SessionSetup( Packet_Header_Flags_Values.NONE, SESSION_SETUP_Request_Flags.NONE, securityMode, capabilities, 0, securityPackageType, serverName, token, out serverGssToken, creditRequest)); }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name of ip address</param> /// <param name="client">client name of ip address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception> public void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken, bool transportPreferredSMB) { if (transportPreferredSMB) { transport = new SmbClientTransport(); } else { transport = new Smb2ClientTransport(); } transport.Connect(server, client, domain, userName, password, timeout, securityPackage, useServerToken); }
/// <summary> /// Convert MechType to SecurityPackage enum /// </summary> /// <param name="mechType">The MechType value to be convert</param> /// <returns>The converted AuthMech enum value</returns> public static SecurityPackageType ConvertMechType(MechType mechType) { SecurityPackageType authType = SecurityPackageType.Unknown; if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.MsKerbOidInt)) { authType = SecurityPackageType.Kerberos; } else if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.NlmpOidInt)) { authType = SecurityPackageType.Ntlm; } else if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.KerbOidInt)) { authType = SecurityPackageType.Kerberos; } else if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.NegoExOidInt)) { authType = SecurityPackageType.Unknown; } return(authType); }
/// <summary> /// Bind RPC server. /// </summary> /// <param name="swnClient">SWN rpc client</param> /// <param name="networkAddress">RPC network address</param> /// <param name="domainName">Domain name</param> /// <param name="userName">User name</param> /// <param name="password">Password</param> /// <param name="securityPackage">Security package</param> /// <param name="authLevel">Authentication level</param> /// <param name="timeout">Timeout</param> /// <param name="serverComputerName">ServerComputerName</param> /// <returns>Return true if success, otherwise return false</returns> public static bool BindServer(SwnClient swnClient, IPAddress networkAddress, string domainName, string userName, string password, SecurityPackageType securityPackage, RpceAuthenticationLevel authLevel, TimeSpan timeout, string serverComputerName = null) { AccountCredential accountCredential = new AccountCredential(domainName, userName, password); string cifsServicePrincipalName = string.Empty; if (!string.IsNullOrEmpty(serverComputerName)) { cifsServicePrincipalName = "cifs/" + serverComputerName; } else { IPHostEntry hostEntry = null; try { hostEntry = Dns.GetHostEntry(networkAddress); } catch (Exception ex) { throw new Exception(string.Format("Failed to resolve network address {0} with exception: {1}", networkAddress.ToString(), ex.Message)); } if (hostEntry != null && !string.IsNullOrEmpty(hostEntry.HostName)) { cifsServicePrincipalName = "cifs/" + hostEntry.HostName; } else { throw new Exception("Failed to get HostName from network address " + networkAddress.ToString()); } } ClientSecurityContext securityContext = new SspiClientSecurityContext( securityPackage, accountCredential, cifsServicePrincipalName, ClientSecurityContextAttribute.Connection | ClientSecurityContextAttribute.DceStyle | ClientSecurityContextAttribute.Integrity | ClientSecurityContextAttribute.ReplayDetect | ClientSecurityContextAttribute.SequenceDetect | ClientSecurityContextAttribute.UseSessionKey, SecurityTargetDataRepresentation.SecurityNativeDrep); try { //Bind BaseTestSite.Log.Add(LogEntryKind.Debug, "Start to Bind RPC to {0}.", networkAddress.ToString()); swnClient.SwnBind(networkAddress.ToString(), accountCredential, securityContext, authLevel, timeout); } catch (Exception ex) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} failed. Exception: {1}", networkAddress.ToString(), ex.Message); swnClient.SwnUnbind(timeout); return(false); } BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} successfully.", networkAddress.ToString()); return(true); }
/// <summary> /// Constructor. /// </summary> /// <param name="securityPackageType">Security package type.</param> protected SecurityConfig(SecurityPackageType securityPackageType) { this.securityType = securityPackageType; }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name</param> /// <param name="client">client name</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="InvalidOperationException">Fail to set up connection with server</exception> public override void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken) { this.internalTimeout = timeout; ConnectShare(server, 445, IpVersion.Any, domain, userName, password, IPC_SHARE, securityPackage, useServerToken); }
/// <summary> /// Connect to a share indicated by shareName in server /// This will use smb over tcp as transport. Only one server /// can be connected at one time /// </summary> /// <param name="serverName">The server Name</param> /// <param name="port">The server port</param> /// <param name="ipVersion">The ip version</param> /// <param name="domain">The domain name</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception> public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken) { throw new NotImplementedException(); }
/// <summary> /// Connect to a share indicated by shareName in server /// This will use smb over tcp as transport. Only one server /// can be connected at one time /// </summary> /// <param name="serverName">The server Name</param> /// <param name="port">The server port</param> /// <param name="ipVersion">The ip version</param> /// <param name="domain">The domain name</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception> public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken) { smbClient.Connect(serverName, port, ipVersion, defaultBufferSize); InternalConnectShare(serverName, domain, userName, password, shareName, securityPackage); }
internal static void DtlsAcquireCredentialsHandle( SecurityPackageType packageType, CertificateCredential certificateCredential, string serverPrincipal, uint fCredentialUse, out SecurityHandle credentialHandle) { string stringPackage = SspiUtility.GetPackageStringName(packageType); SecurityInteger expiryTime = new SecurityInteger(); uint enabledProtocols; if (fCredentialUse == NativeMethods.SECPKG_CRED_OUTBOUND) { enabledProtocols = NativeMethods.SP_PROT_DTLS_CLIENT; } else { enabledProtocols = NativeMethods.SP_PROT_DTLS_SERVER; } SchannelCred schannelCred = new SchannelCred(certificateCredential, enabledProtocols); CredSspCred sspCred = new CredSspCred(); IntPtr pAuthData = IntPtr.Zero; if (packageType == SecurityPackageType.Schannel) { pAuthData = SspiUtility.CreateAuthData(schannelCred); } else if (packageType == SecurityPackageType.CredSsp) { sspCred.pSchannelCred = SspiUtility.CreateAuthData(schannelCred); sspCred.pSpnegoCred = IntPtr.Zero; sspCred.Type = CredSspSubmitType.CredsspSubmitBufferBoth; pAuthData = SspiUtility.CreateAuthData(sspCred); } uint result = NativeMethods.AcquireCredentialsHandle( null, stringPackage, fCredentialUse, IntPtr.Zero, pAuthData, IntPtr.Zero, IntPtr.Zero, out credentialHandle, out expiryTime); //Free memory SspiUtility.FreeSchannelCred(schannelCred); if (pAuthData != IntPtr.Zero) { if (packageType == SecurityPackageType.CredSsp) { Marshal.FreeHGlobal(sspCred.pSchannelCred); } Marshal.FreeHGlobal(pAuthData); } if (result != NativeMethods.SEC_E_OK) { throw new SspiException("AquireCredentialsHandle fails.", result); } }
/// <summary> /// Get the specific configuration from the SecurityConfig list by the security type. /// </summary> /// <param name="configList">SecurityConfig list.</param> /// <param name="securityType">The security type.</param> /// <returns>The specific security configuration.</returns> internal static SecurityConfig GetSecurityConfig(SecurityConfig[] configList, SecurityPackageType securityType) { SecurityConfig sspiConfig = null; foreach (SecurityConfig configItem in configList) { if (configItem.SecurityType == securityType) { return(configItem); } else if (configItem.SecurityType == SecurityPackageType.Unknown) { // SSPI configuration is initialized as Unknown type sspiConfig = configItem; } } return(sspiConfig); }
private void executeButton_Click(object sender, EventArgs e) { try { if (!CheckInput()) { return; } logger.Clear(); #region Read settings from UI var version = (BranchCacheVersion)branchCacheVersionComboBox.SelectedItem; var operationMode = (OperationMode)operationModeComboBox.SelectedItem; var transport = (ContentInformationTransport)transportComboBox.SelectedItem; var serverSecret = serverSecretTextBox.Text; var filePath = filePathTextBox.Text; var hashAlgoValue = (dwHashAlgo_Values)hashAlgorithmComboBox.SelectedItem; HashAlgorithm hashAlgorithm; HMAC hmacAlgorithm; int hashBlockSize; string server = null; string file = null; string sharedFolder = null; Match filePathMatch = null; switch (transport) { case ContentInformationTransport.PCCRTP: filePathMatch = Regex.Match(filePath, httpFilePathPattern); server = filePathMatch.Groups["Server"].Value; file = filePathMatch.Groups["FileName"].Value; break; case ContentInformationTransport.SMB2: filePathMatch = Regex.Match(filePath, smb2FilePathPattern); server = filePathMatch.Groups["Server"].Value; sharedFolder = filePathMatch.Groups["SharedFolder"].Value; file = filePathMatch.Groups["FileName"].Value; break; default: throw new NotImplementedException(); } SecurityPackageType securityPackageType = (SecurityPackageType)smb2AuthenticationComboBox.SelectedItem; string domainName = domainNameTextBox.Text; string userName = userNameTextBox.Text; string userPassword = userPasswordTextBox.Text; #endregion var timeout = TimeSpan.FromSeconds(60); byte[] content; byte[] contentInformation; Content_Information_Data_Structure contentInformationStructure = new Content_Information_Data_Structure(); Content_Information_Data_Structure_V2 contentInformationStructureV2 = new Content_Information_Data_Structure_V2(); #region Read content and content information if (operationMode == OperationMode.RemoteHashVerification) { switch (transport) { case ContentInformationTransport.PCCRTP: PccrtpClient pccrtpClient = new PccrtpClient(); PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest( server, 80, file, version); PccrtpResponse pccrtpResponse = pccrtpClient.SendHttpRequest( HttpVersionType.HttpVersion11, pccrtpRequest, (int)timeout.TotalMilliseconds); if (pccrtpResponse.HttpResponse.ContentEncoding == "peerdist") { contentInformation = pccrtpResponse.PayloadData; content = Utility.DownloadHTTPFile(server, file); } else { content = pccrtpResponse.PayloadData; Thread.Sleep(5000); // Wait for hash generation pccrtpResponse = pccrtpClient.SendHttpRequest( HttpVersionType.HttpVersion11, pccrtpRequest, (int)timeout.TotalMilliseconds); contentInformation = pccrtpResponse.PayloadData; } break; case ContentInformationTransport.SMB2: using (Smb2ClientTransport smb2Client = new Smb2ClientTransport(timeout)) { smb2Client.OpenFile( server, sharedFolder, file, securityPackageType, domainName, userName, userPassword, AccessMask.GENERIC_READ); content = smb2Client.ReadAllBytes(); Thread.Sleep(5000); // Wait for hash generation HASH_HEADER hashHeader; smb2Client.ReadHash( SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST, version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_1 : SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_2, version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED : SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_FILE_BASED, 0, uint.MaxValue, out hashHeader, out contentInformation); } break; default: throw new NotImplementedException(); } switch (version) { case BranchCacheVersion.V1: contentInformationStructure = PccrcUtility.ParseContentInformation(contentInformation); break; case BranchCacheVersion.V2: contentInformationStructureV2 = PccrcUtility.ParseContentInformationV2(contentInformation); break; default: throw new NotImplementedException(); } } else { content = File.ReadAllBytes(filePath); } #endregion #region Calculate hash and execute verification switch (version) { case BranchCacheVersion.V1: if (operationMode == OperationMode.RemoteHashVerification) { PccrcUtility.GetHashAlgorithm(contentInformationStructure.dwHashAlgo, out hashAlgorithm, out hmacAlgorithm, out hashBlockSize); } else { PccrcUtility.GetHashAlgorithm(hashAlgoValue, out hashAlgorithm, out hmacAlgorithm, out hashBlockSize); } hmacAlgorithm.Key = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(serverSecret)); logger.LogInfo( "Ks = Hash(ServerSecret): {0}", Utility.ToHexString(hmacAlgorithm.Key)); logger.NewLine(); int blockTotalCount = content.Length / BLOCKBYTECOUNT; if (content.Length > BLOCKBYTECOUNT * blockTotalCount) { blockTotalCount = blockTotalCount + 1; } int segmentCount = blockTotalCount / SEGMENTBLOCKCOUNT; if (blockTotalCount > SEGMENTBLOCKCOUNT * segmentCount) { segmentCount = segmentCount + 1; } for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) { logger.LogInfo("Segment{0}", segmentIndex); logger.NewLine(); logger.Indent(); List <byte> blockHashList = new List <byte>(); List <byte> tempList = new List <byte>(); int blockCount = (segmentIndex == segmentCount - 1) ? (blockTotalCount % SEGMENTBLOCKCOUNT) : (SEGMENTBLOCKCOUNT); for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) { logger.LogInfo( "Block{0} Offset {1} Length {2}", blockIndex, BLOCKBYTECOUNT * SEGMENTBLOCKCOUNT * segmentIndex + BLOCKBYTECOUNT * blockIndex, BLOCKBYTECOUNT); logger.NewLine(); logger.Indent(); var block = content.Skip(BLOCKBYTECOUNT * SEGMENTBLOCKCOUNT * segmentIndex + BLOCKBYTECOUNT * blockIndex).Take(BLOCKBYTECOUNT).ToArray(); byte[] blockHash = hashAlgorithm.ComputeHash(block); logger.LogInfo("BlockHash{0} = Hash(Block): {1}", blockIndex, Utility.ToHexString(blockHash)); if (operationMode == OperationMode.RemoteHashVerification && !blockHash.SequenceEqual(contentInformationStructure.blocks[segmentIndex].BlockHashes.Skip(blockIndex * hashBlockSize).Take(hashBlockSize))) { logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.blocks[segmentIndex].BlockHashes.Skip(blockIndex * hashBlockSize).Take(hashBlockSize).ToArray())); } blockHashList.AddRange(blockHash); logger.Unindent(); logger.NewLine(); } byte[] hod = hashAlgorithm.ComputeHash(blockHashList.ToArray()); logger.LogInfo( "HoD = Hash(BlockHash0 + BlockHash1 + ... + BlockHashN): {0}", Utility.ToHexString(hod)); if (operationMode == OperationMode.RemoteHashVerification && !hod.SequenceEqual(contentInformationStructure.segments[segmentIndex].SegmentHashOfData)) { logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.segments[segmentIndex].SegmentHashOfData)); } logger.NewLine(); byte[] kp = hmacAlgorithm.ComputeHash(hod); logger.LogInfo( "Kp = HMAC(Ks, HoD): {0}", Utility.ToHexString(kp)); if (operationMode == OperationMode.RemoteHashVerification && !kp.SequenceEqual(contentInformationStructure.segments[segmentIndex].SegmentSecret)) { logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.segments[segmentIndex].SegmentSecret)); } logger.NewLine(); tempList.AddRange(hod); tempList.AddRange(Encoding.Unicode.GetBytes(HOHODK_APPEND_STRING)); byte[] hoHoDK = hashAlgorithm.ComputeHash(tempList.ToArray()); logger.LogInfo( "hoHoDK = HMAC(HoD + \"MS_P2P_CACHING\"): {0}", Utility.ToHexString(hoHoDK)); logger.NewLine(); logger.Unindent(); } break; case BranchCacheVersion.V2: PccrcUtility.GetHashAlgorithm(dwHashAlgoV2_Values.TRUNCATED_SHA512, out hashAlgorithm, out hmacAlgorithm); hmacAlgorithm.Key = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(serverSecret)).Take(32).ToArray(); logger.LogInfo( "Ks = Hash(ServerSecret): {0}", Utility.ToHexString(hmacAlgorithm.Key)); logger.NewLine(); int segmentLength = BLOCKBYTECOUNT; int chunkCount = 1; if (operationMode == OperationMode.RemoteHashVerification) { chunkCount = contentInformationStructureV2.chunks.Length; } int segmentOffset = 0; for (int chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++) { logger.LogInfo("Chunk{0}", chunkIndex); logger.NewLine(); logger.Indent(); segmentCount = content.Length / segmentLength; if (content.Length > segmentCount * segmentLength) { segmentCount++; } if (operationMode == OperationMode.RemoteHashVerification) { segmentCount = contentInformationStructureV2.chunks[chunkIndex].chunkData.Length; } for (int segmentIndex = 0; segmentIndex < segmentCount; ++segmentIndex) { logger.LogInfo( "Segment{0} Offset {1} Length {2}", segmentIndex, segmentOffset, BLOCKBYTECOUNT); logger.NewLine(); logger.Indent(); if (operationMode == OperationMode.RemoteHashVerification) { segmentLength = (int)contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].cbSegment; } List <byte> tempList = new List <byte>(); var segment = content.Skip(segmentOffset).Take(segmentLength).ToArray(); segmentOffset += segmentLength; //TRANCATED_SHA_512 byte[] hod = hashAlgorithm.ComputeHash(segment).Take(32).ToArray(); logger.LogInfo( "HoD = Hash(Segment): {0}", Utility.ToHexString(hod)); if (operationMode == OperationMode.RemoteHashVerification && !hod.SequenceEqual(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentHashOfData)) { logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentHashOfData)); } logger.NewLine(); byte[] kp = hmacAlgorithm.ComputeHash(hod).Take(32).ToArray(); logger.LogInfo( "Kp = HMAC(Ks, HoD): {0}", Utility.ToHexString(kp)); if (operationMode == OperationMode.RemoteHashVerification && !kp.SequenceEqual(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentSecret)) { logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentSecret)); } logger.NewLine(); tempList.AddRange(hod); tempList.AddRange(Encoding.Unicode.GetBytes(HOHODK_APPEND_STRING)); byte[] hoHoDK = hashAlgorithm.ComputeHash(tempList.ToArray()); logger.LogInfo( "hoHoDK = HMAC(HoD + \"MS_P2P_CACHING\"): {0}", Utility.ToHexString(hoHoDK)); logger.NewLine(); logger.Unindent(); } } break; default: throw new NotImplementedException(); } if (operationMode == OperationMode.RemoteHashVerification) { if (logger.HasError) { Utility.ShowMessageBox("Hash verification error found!", MessageBoxIcon.Error); } else { Utility.ShowMessageBox("Hash verification passed!", MessageBoxIcon.Information); } } #endregion } catch (Exception ex) { Utility.ShowMessageBox(ex.Message + "\r\n\r\n" + ex.StackTrace, MessageBoxIcon.Error); } }
/// <summary> /// Connect to a share indicated by shareName in server /// This will use smb over tcp as transport. Only one server /// can be connected at one time /// </summary> /// <param name="serverName">The server Name</param> /// <param name="port">The server port</param> /// <param name="ipVersion">The ip version</param> /// <param name="domain">The domain name</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception> public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken) { IPHostEntry hostEntry = Dns.GetHostEntry(serverName); serverPrincipleName = Smb2Utility.GetPrincipleName(hostEntry.HostName); if (ipVersion == IpVersion.Ipv4) { foreach (var ip in hostEntry.AddressList) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { client.ConnectOverTCP(ip); break; } } } else if (ipVersion == IpVersion.Ipv6) { foreach (var ip in hostEntry.AddressList) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { client.ConnectOverTCP(ip); break; } } } else { // if specified the IpVersion.Any, try ipv4 first, if failed, try ipv6 try { foreach (var ip in hostEntry.AddressList) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { client.ConnectOverTCP(ip); break; } } } catch (InvalidOperationException) { foreach (var ip in hostEntry.AddressList) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { client.ConnectOverTCP(ip); break; } } } } if (!client.IsConnected) { throw new InvalidOperationException("No valid IP address can be used to connect to the server."); } InternalConnectShare(domain, userName, password, shareName, internalTimeout, securityPackage, useServerToken); }
internal static byte[] QuerySessionKey(SecurityPackageType packageType, ref SecurityHandle contextHandle) { IntPtr pSessionKey = IntPtr.Zero; byte[] sessionKey = null; if (packageType == SecurityPackageType.Schannel || packageType == SecurityPackageType.CredSsp) { pSessionKey = Marshal.AllocHGlobal(SchannelKeySize + SchannelIvSize); uint hResult = NativeMethods.QueryContextAttributes( ref contextHandle, NativeMethods.SECPKG_ATTR_EAP_KEY_BLOCK, pSessionKey); if (hResult == NativeMethods.SEC_E_OK) { if (pSessionKey != IntPtr.Zero) { sessionKey = new byte[SchannelKeySize]; Marshal.Copy(pSessionKey, sessionKey, 0, SchannelKeySize); } } Marshal.FreeHGlobal(pSessionKey); } else { pSessionKey = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextSessionKey))); uint hResult = NativeMethods.QueryContextAttributes( ref contextHandle, NativeMethods.SECPKG_ATTR_SESSION_KEY, pSessionKey); if (hResult == NativeMethods.SEC_E_OK) { if (pSessionKey != IntPtr.Zero) { SecurityPackageContextSessionKey contextSessionKey = (SecurityPackageContextSessionKey) Marshal.PtrToStructure(pSessionKey, typeof(SecurityPackageContextSessionKey)); sessionKey = new byte[contextSessionKey.SessionKeyLength]; Marshal.Copy(contextSessionKey.SessionKey, sessionKey, 0, sessionKey.Length); NativeMethods.FreeContextBuffer(contextSessionKey.SessionKey); } } Marshal.FreeHGlobal(pSessionKey); } return sessionKey; }
public void Smb2SessionSetup(SecurityPackageType authentication, string domain, string serverName, string userName, string password) { var sspiClientGss = new SspiClientSecurityContext( authentication, new AccountCredential(domain, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep ); if (authentication == SecurityPackageType.Negotiate) { sspiClientGss.Initialize(serverGssToken); } else { sspiClientGss.Initialize(null); } Packet_Header packetHeader; SESSION_SETUP_Response sessionSetupResponse; uint status; while (true) { status = SessionSetup( 0, RequestAndConsumeCredit(), Packet_Header_Flags_Values.NONE, GetMessageId(), sessionId, SESSION_SETUP_Request_Flags.NONE, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, SESSION_SETUP_Request_Capabilities_Values.NONE, sessionId, sspiClientGss.Token, out sessionId, out serverGssToken, out packetHeader, out sessionSetupResponse ); UpdateCredit(packetHeader); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0) { sspiClientGss.Initialize(serverGssToken); } if (status != Smb2Status.STATUS_MORE_PROCESSING_REQUIRED) { break; } } if (status != Smb2Status.STATUS_SUCCESS) { throw new InvalidOperationException(String.Format("SessionSetup failed with {0:X08}.", status)); } encryptionEnabled = sessionSetupResponse.SessionFlags.HasFlag(SessionFlags_Values.SESSION_FLAG_ENCRYPT_DATA); GenerateCryptoKeys( sessionId, sspiClientGss.SessionKey, signingRequired, encryptionEnabled ); if (!encryptionEnabled) { signingRequired = true; } EnableSessionSigningAndEncryption(sessionId, signingRequired, encryptionEnabled); }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name of ip address</param> /// <param name="client">client name of ip address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception> public abstract void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken);
/// <summary> /// Connect to a share indicated by shareName in server /// This will use smb over tcp as transport. Only one server /// can be connected at one time /// </summary> /// <param name="serverName">The server Name</param> /// <param name="port">The server port</param> /// <param name="ipVersion">The ip version</param> /// <param name="domain">The domain name</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception> public abstract void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken);
/// <summary> /// Convert SecurityPackage type to package string used by SSPI. /// </summary> /// <param name="packageType">Package type</param> /// <returns>Package string used by SSPI</returns> /// <exception cref="ArgumentException">If packageType is not supported, throw this exception.</exception> internal static string GetPackageStringName(SecurityPackageType packageType) { string package = string.Empty; switch (packageType) { case SecurityPackageType.CredSsp: package = CredSsp; break; case SecurityPackageType.Kerberos: package = Kerberos; break; case SecurityPackageType.Negotiate: package = Negotiate; break; case SecurityPackageType.Ntlm: package = Ntlm; break; case SecurityPackageType.Schannel: package = Schannel; break; default: throw new ArgumentException("Invlid packageType value.", "packageType"); } return package; }
public SspiClientSecurityContext( SecurityPackageType packageType, AccountCredential clientCredential, string serverPrincipal, ClientSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) { this.packageType = packageType; this.serverPrincipalName = serverPrincipal; this.securityContextAttributes = contextAttributes; this.targetDataRepresentaion = targetDataRep; SspiUtility.AcquireCredentialsHandle( packageType, clientCredential, serverPrincipal, NativeMethods.SECPKG_CRED_OUTBOUND, out this.credentialHandle); }
/// <summary> /// Bind RPC server. /// </summary> /// <param name="swnClient">SWN rpc client</param> /// <param name="networkAddress">RPC network address</param> /// <param name="domainName">Domain name</param> /// <param name="userName">User name</param> /// <param name="password">Password</param> /// <param name="securityPackage">Security package</param> /// <param name="authLevel">Authentication level</param> /// <param name="timeout">Timeout</param> /// <param name="serverComputerName">ServerComputerName</param> /// <returns>Return true if success, otherwise return false</returns> public static bool BindServer(SwnClient swnClient, IPAddress networkAddress, string domainName, string userName, string password, SecurityPackageType securityPackage, RpceAuthenticationLevel authLevel, TimeSpan timeout,string serverComputerName = null) { AccountCredential accountCredential = new AccountCredential(domainName, userName, password); string cifsServicePrincipalName = string.Empty; if (!string.IsNullOrEmpty(serverComputerName)) { cifsServicePrincipalName = "cifs/" + serverComputerName; } else { IPHostEntry hostEntry = null; try { hostEntry = Dns.GetHostEntry(networkAddress); } catch (Exception ex) { throw new Exception(string.Format("Failed to resolve network address {0} with exception: {1}", networkAddress.ToString(), ex.Message)); } if (hostEntry != null && !string.IsNullOrEmpty(hostEntry.HostName)) { cifsServicePrincipalName = "cifs/" + hostEntry.HostName; } else { throw new Exception("Failed to get HostName from network address " + networkAddress.ToString()); } } ClientSecurityContext securityContext = new SspiClientSecurityContext( securityPackage, accountCredential, cifsServicePrincipalName, ClientSecurityContextAttribute.Connection | ClientSecurityContextAttribute.DceStyle | ClientSecurityContextAttribute.Integrity | ClientSecurityContextAttribute.ReplayDetect | ClientSecurityContextAttribute.SequenceDetect | ClientSecurityContextAttribute.UseSessionKey, SecurityTargetDataRepresentation.SecurityNativeDrep); try { //Bind BaseTestSite.Log.Add(LogEntryKind.Debug, "Start to Bind RPC to {0}.", networkAddress.ToString()); swnClient.SwnBind(networkAddress.ToString(), accountCredential, securityContext, authLevel, timeout); } catch (Exception ex) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} failed. Exception: {1}", networkAddress.ToString(), ex.Message); swnClient.SwnUnbind(timeout); return false; } BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} successfully.", networkAddress.ToString()); return true; }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name of ip address</param> /// <param name="client">client name of ip address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception> public override void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken) { serverPrincipleName = server; IPHostEntry hostEntry = Dns.GetHostEntry(server); this.client.ConnectOverTCP(hostEntry.AddressList[0]); InternalConnectShare(domain, userName, password, IPC_CONNECT_STRING, timeout, securityPackage, useServerToken); }
internal static void AcquireCredentialsHandle( SecurityPackageType packageType, AccountCredential accountCredential, string serverPrincipal, uint fCredentialUse, out SecurityHandle credentialHandle) { string stringPackage = SspiUtility.GetPackageStringName(packageType); SecurityInteger expiryTime; SecurityWinntAuthIdentity authIdentity = new SecurityWinntAuthIdentity(accountCredential); IntPtr pAuthData = IntPtr.Zero; SchannelCred schannelCred = new SchannelCred(); schannelCred.dwVersion = NativeMethods.SCHANNEL_CRED_VERSION; schannelCred.cCreds = 0; schannelCred.paCred = IntPtr.Zero; CredSspCred credSsp = new CredSspCred(); switch (packageType) { case SecurityPackageType.Ntlm: case SecurityPackageType.Kerberos: case SecurityPackageType.Negotiate: pAuthData = SspiUtility.CreateAuthData(authIdentity); break; case SecurityPackageType.Schannel: pAuthData = SspiUtility.CreateAuthData(schannelCred); break; case SecurityPackageType.CredSsp: credSsp.Type = CredSspSubmitType.CredsspSubmitBufferBoth; credSsp.pSchannelCred = CreateAuthData(schannelCred); credSsp.pSpnegoCred = CreateAuthData(authIdentity); pAuthData = CreateAuthData(credSsp); break; //default, if other values, exception will be thrown by GetPackageStringName. default: throw new ArgumentException("Invlid packageType value.", "packageType"); } uint result = NativeMethods.AcquireCredentialsHandle( serverPrincipal, stringPackage, fCredentialUse, IntPtr.Zero, pAuthData, IntPtr.Zero, IntPtr.Zero, out credentialHandle, out expiryTime); //Free memory switch (packageType) { case SecurityPackageType.Ntlm: case SecurityPackageType.Kerberos: case SecurityPackageType.Negotiate: SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity); break; case SecurityPackageType.Schannel: stringPackage = Schannel; SspiUtility.FreeSchannelCred(schannelCred); break; case SecurityPackageType.CredSsp: SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity); SspiUtility.FreeSchannelCred(schannelCred); SspiUtility.FreeCredSspCred(credSsp); break; //default, if other values, exception will be thrown by GetPackageStringName. default: throw new ArgumentException("Invlid packageType value.", "packageType"); } Marshal.FreeHGlobal(pAuthData); if (result != NativeMethods.SEC_E_OK) { throw new SspiException("AquireCredentialsHandle failed", result); } }
private void InternalConnectShare(string domain, string userName, string password, string shareName, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken) { uint status; DialectRevision selectedDialect; Packet_Header header; byte[] serverGssToken; Array allDialects = Enum.GetValues(typeof(DialectRevision)); DialectRevision[] validDialects = new DialectRevision[allDialects.Length - 2]; int index = 0; foreach (var dialect in allDialects) { if ((DialectRevision)dialect != DialectRevision.Smb2Unknown && (DialectRevision)dialect != DialectRevision.Smb2Wildcard) { validDialects[index++] = (DialectRevision)dialect; } } PreauthIntegrityHashID[] preauthIntegrityHashIDArray = null; EncryptionAlgorithm[] encryptionAlgorithmArray = null; if (validDialects.Contains(DialectRevision.Smb311)) { preauthIntegrityHashIDArray = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; encryptionAlgorithmArray = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; } // Negotiate: NEGOTIATE_Response negotiateResponse; CheckStatusCode( client.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, // Will negotiate highest dialect server supports validDialects, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_LARGE_MTU, clientGuid, out selectedDialect, out serverGssToken, out header, out negotiateResponse, preauthHashAlgs: preauthIntegrityHashIDArray, encryptionAlgs: encryptionAlgorithmArray)); negotiatedDialect = selectedDialect; serverCapabilities = (Capabilities_Values)negotiateResponse.Capabilities; // 3.2.5.2: If the SecurityMode field in the SMB2 header of the response has the SMB2_NEGOTIATE_SIGNING_REQUIRED bit set, // the client MUST set Connection.RequireSigning to TRUE. // 3.2.5.3.1: If the global setting RequireMessageSigning is set to TRUE or // Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE bool session_SigningRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); if (session_SigningRequired) { // 3.2.4.1.1: If the client signs the request, it MUST set the SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header. headerFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED; } // Session setup: SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( securityPackage, new AccountCredential(domain, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverPrincipleName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); if (securityPackage == SecurityPackageType.Negotiate) sspiClientGss.Initialize(serverGssToken); else sspiClientGss.Initialize(null); do { status = client.SessionSetup( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, sessionId, SESSION_SETUP_Request_Flags.NONE, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS, 0, sspiClientGss.Token, out sessionId, out serverGssToken, out header, out sessionSetupResponse); CheckStatusCode(status); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0) { sspiClientGss.Initialize(serverGssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); // 3.2.4.1.1 If Connection.Dialect is "3.1.1" and the message being sent is a TREE_CONNECT Request and the session identified by SessionId has Session.EncryptData equal to FALSE bool treeconnect_SigningRequired = session_SigningRequired || (selectedDialect >= DialectRevision.Smb311); client.GenerateCryptoKeys(sessionId, sspiClientGss.SessionKey, treeconnect_SigningRequired, false); this.sessionId = header.SessionId; // Session Key will be used in the MS-LSA SDK, see LsaClient.cs Line 179 SessionKey // Insert the session key to the global context Smb2ClientSession smb2CliSession = new Smb2ClientSession(); smb2CliSession.SessionKey = client.GetSessionKeyForAuthenticatedContext(sessionId); Smb2ClientConnection smb2CliConn = new Smb2ClientConnection(); smb2CliConn.SessionTable = new Dictionary<ulong, Smb2ClientSession>(); smb2CliConn.SessionTable.Add(sessionId, smb2CliSession); context.ConnectionTable = new Dictionary<string, Smb2ClientConnection>(); context.ConnectionTable.Add("Smb2ClientConnection", smb2CliConn); // Tree connect: TREE_CONNECT_Response treeConnectResponse; status = client.TreeConnect( 1, 1, treeconnect_SigningRequired? headerFlags| Packet_Header_Flags_Values.FLAGS_SIGNED:headerFlags, messageId++, sessionId, "\\\\" + serverPrincipleName + "\\" + shareName, out treeId, out header, out treeConnectResponse); this.treeId = header.TreeId; // For the messages followed by TREE_CONNECT, set them as signed/not signed following the normal proces client.EnableSessionSigningAndEncryption(sessionId, session_SigningRequired, false); }
/// <summary> /// Connect share specified by shareName, this function does not issue tcp or netbios /// connect, it does Negotiate -> SessionSetup -> TreeConnect /// </summary> /// <param name="serverName">The server name</param> /// <param name="domain">The domain</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> private void InternalConnectShare(string serverName, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage) { SmbPacket request; SmbPacket response; uint status; // Negotiate: request = this.smbClient.CreateNegotiateRequest( defaultSignState, new string[] { DialectNameString.NTLANMAN }); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); if (status != 0) { throw new InvalidOperationException("Negotiate Failed. ErrorCode: " + status); } SecurityModes securityMode = (response as SmbNegotiateResponsePacket).SmbParameters.SecurityMode; this.isSignRequired = (securityMode & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) == SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; SmbSecurityPackage secPkg; switch (securityPackage) { case SecurityPackageType.Ntlm: secPkg = SmbSecurityPackage.NTLM; break; case SecurityPackageType.Kerberos: secPkg = SmbSecurityPackage.Kerberos; break; case SecurityPackageType.Negotiate: secPkg = SmbSecurityPackage.Negotiate; break; default: throw new ArgumentException("Unsupported securityPackage: " + securityPackage.ToString()); } // Session setup: request = this.smbClient.CreateFirstSessionSetupRequest(secPkg, serverName, domain, userName, password); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); while (status != 0) { if ((int)status == (int)SmbStatus.STATUS_MORE_PROCESSING_REQUIRED) { this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid; request = this.smbClient.CreateSecondSessionSetupRequest(this.uid, secPkg); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); } else { throw new InvalidOperationException("Session Setup Failed. ErrorCode: " + status); } } this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid; if (isSignRequired) { CifsClientPerSession session = this.smbClient.Context.GetSession( this.smbClient.Context.Connection.ConnectionId, this.uid); this.sessionKey = session.SessionKey; } // Tree connect: string sharePath = "\\\\" + serverName + '\\' + shareName; request = this.smbClient.CreateTreeConnectRequest(this.uid, sharePath); if (this.isSignRequired) { request.Sign(this.NextSequenceNumber, this.sessionKey); } response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); if (status != 0) { throw new InvalidOperationException("Tree Connect Failed. ErrorCode: " + status); } this.treeId = (response as SmbTreeConnectAndxResponsePacket).SmbHeader.Tid; }
/// <summary> /// Connect to a share indicated by shareName in server /// This will use smb over tcp as transport. Only one server /// can be connected at one time /// </summary> /// <param name="serverName">The server Name</param> /// <param name="serverIP">The ip of server</param> /// <param name="domain">The domain name</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> public void ConnectShare(string serverName, IPAddress serverIP, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken) { serverPrincipleName = serverName; client.ConnectOverTCP(serverIP); InternalConnectShare(domain, userName, password, shareName, internalTimeout, securityPackage, useServerToken); }
public uint Smb2SessionSetup( SecurityPackageType securityPackageType, string domainName, string userName, string password, string serverName) { uint status; SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( securityPackageType, new AccountCredential(domainName, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep ); // Server GSS token is used only for Negotiate authentication if (securityPackageType == SecurityPackageType.Negotiate) { sspiClientGss.Initialize(this.gssToken); } else { sspiClientGss.Initialize(null); } this.sessionId = 0; do { status = SessionSetup( 1, 64, Packet_Header_Flags_Values.NONE, this.messageId, this.sessionId, SESSION_SETUP_Request_Flags.NONE, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS, 0, sspiClientGss.Token, out sessionId, out this.gssToken, out packetHeader, out sessionSetupResponse ); CalculateSmb2AvailableCredits(1, packetHeader.CreditRequestResponse); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && this.gssToken != null && this.gssToken.Length > 0) { sspiClientGss.Initialize(this.gssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); if (status == Smb2Status.STATUS_SUCCESS) { sessionKey = sspiClientGss.SessionKey; GenerateCryptoKeys(sessionId, sessionKey, true, false); } return(status); }
public void OpenFile( string server, string share, string file, SecurityPackageType securityPackageType, string domainName, string userName, string password, AccessMask accessMask) { IPHostEntry hostEntry = Dns.GetHostEntry(server); client.ConnectOverTCP(hostEntry.AddressList[0]); serverPrincipleName = Smb2Utility.GetPrincipleName(hostEntry.HostName); Packet_Header header; NEGOTIATE_Response negotiateResponse; DialectRevision selectedDialect; byte[] serverGssToken; CheckStatusCode( Negotiate( 1, 1, messageId++, clientGuid, out selectedDialect, out serverGssToken, out header, out negotiateResponse)); // 3.2.5.2: If the SecurityMode field in the SMB2 header of the response has the SMB2_NEGOTIATE_SIGNING_REQUIRED bit set, // the client MUST set Connection.RequireSigning to TRUE. // 3.2.5.3.1: If the global setting RequireMessageSigning is set to TRUE or // Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE bool session_SigningRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); if (session_SigningRequired) { // 3.2.4.1.1: If the client signs the request, it MUST set the SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header. headerFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED; } SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( securityPackageType, new AccountCredential(domainName, userName, password), Smb2Utility.GetCifsServicePrincipalName(server), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); if (securityPackageType == SecurityPackageType.Negotiate) sspiClientGss.Initialize(serverGssToken); else sspiClientGss.Initialize(null); uint status; do { status = client.SessionSetup( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, sessionId, SESSION_SETUP_Request_Flags.NONE, SESSION_SETUP_Request_SecurityMode_Values.NONE, SESSION_SETUP_Request_Capabilities_Values.NONE, 0, sspiClientGss.Token, out sessionId, out serverGssToken, out header, out sessionSetupResponse); CheckStatusCode(status); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0) { sspiClientGss.Initialize(serverGssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); client.GenerateCryptoKeys(sessionId, sspiClientGss.SessionKey, session_SigningRequired, false); TREE_CONNECT_Response treeConnectResponse; CheckStatusCode( TreeConnect( 1, 1, headerFlags, messageId++, sessionId, server, share, out header, out treeConnectResponse)); CREATE_Response createResponse; Smb2CreateContextResponse[] serverCreateContexts; CheckStatusCode( client.Create( 1, 1, headerFlags, messageId++, sessionId, treeId, file, accessMask, ShareAccess_Values.FILE_SHARE_READ, CreateOptions_Values.NONE, CreateDisposition_Values.FILE_OPEN_IF, File_Attributes.NONE, ImpersonationLevel_Values.Impersonation, SecurityFlags_Values.NONE, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, null, out fileId, out serverCreateContexts, out header, out createResponse)); }
public void Connect( string protocolSequence, string networkAddress, string endpoint, AccountCredential transportCredential, TimeSpan timeout, SecurityPackageType securityPackage) { if (protocolSequence == null) { throw new ArgumentNullException("protocolSequence"); } if (networkAddress == null) { throw new ArgumentNullException("networkAddress"); } if (endpoint == null) { throw new ArgumentNullException("endpoint"); } if (context.tcpTransport != null || context.fileServiceTransport != null) { throw new InvalidOperationException("RPCE is already connected."); } if (string.Compare(protocolSequence, RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE, true) == 0) { IPAddress[] addresses = Dns.GetHostAddresses(networkAddress); if (addresses == null || addresses.Length == 0) { throw new ArgumentException( "Cannot resolve network address.", "networkAddress"); } IPAddress addr = addresses[0]; int port; if (!int.TryParse(endpoint, out port)) { throw new ArgumentException("Invalid endpoint.", "endpoint"); } SocketTransportConfig config = new SocketTransportConfig(); config.BufferSize = Math.Max(context.MaxTransmitFragmentSize, context.MaxReceiveFragmentSize); config.RemoteIpAddress = addr; config.RemoteIpPort = port; config.Role = Role.Client; config.Type = StackTransportType.Tcp; context.tcpTransport = new TransportStack(config, RpceDecodePduCallback); context.tcpTransport.Connect(); } else if (string.Compare(protocolSequence, RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, true) == 0) { if (!endpoint.StartsWith( RpceUtility.NAMED_PIPE_ENDPOINT_PREFIX, StringComparison.InvariantCultureIgnoreCase)) { throw new ArgumentException("endpoint format is incorrect.", "endpoint"); } if (transportCredential == null) { throw new ArgumentNullException("transportCredential"); } timeoutForFsTransport = timeout; pipeTransceiveResponseQueue = new Queue<byte[]>(); if (!RpceUtility.DisableSmb2) { try { context.fileServiceTransport = new Smb2ClientTransport(timeout); context.fileServiceTransport.ConnectShare( networkAddress, RpceUtility.NAMED_PIPE_PORT, IpVersion.Any, transportCredential.DomainName, transportCredential.AccountName, transportCredential.Password, RpceUtility.NAMED_PIPE_SHARENAME, securityPackage, false); } catch { context.fileServiceTransport.Dispose(); context.fileServiceTransport = null; } } if (context.fileServiceTransport == null) { // Remote doesn't support SMB2, use SMB. context.fileServiceTransport = new SmbClientTransport(); context.fileServiceTransport.ConnectShare( networkAddress, RpceUtility.NAMED_PIPE_PORT, IpVersion.Any, transportCredential.DomainName, transportCredential.AccountName, transportCredential.Password, RpceUtility.NAMED_PIPE_SHARENAME, securityPackage, false); } context.fileServiceTransport.Create( endpoint.Substring(RpceUtility.NAMED_PIPE_ENDPOINT_PREFIX.Length), FsFileDesiredAccess.FILE_READ_DATA | FsFileDesiredAccess.FILE_WRITE_DATA | FsFileDesiredAccess.FILE_APPEND_DATA | FsFileDesiredAccess.FILE_READ_EA | FsFileDesiredAccess.FILE_WRITE_EA | FsFileDesiredAccess.FILE_READ_ATTRIBUTES | FsFileDesiredAccess.FILE_WRITE_ATTRIBUTES | FsFileDesiredAccess.READ_CONTROL | FsFileDesiredAccess.SYNCHRONIZE, FsImpersonationLevel.Impersonation, FsFileAttribute.NONE, FsCreateDisposition.FILE_OPEN, FsCreateOption.FILE_NON_DIRECTORY_FILE | FsCreateOption.FILE_OPEN_NO_RECALL); } else { throw new NotSupportedException("Specified protocol sequence is not supported."); } context.ProtocolSequence = protocolSequence; context.NetworkAddress = networkAddress; context.Endpoint = endpoint; // Make handle always different. handle = new IntPtr(Environment.TickCount); }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name of ip address</param> /// <param name="client">client name of ip address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception> public override void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage = SecurityPackageType.Ntlm, bool useServerToken = false) { this.cifsClient.Connect(server, client); SmbPacket request, response; uint status; // Negotiate: SMB_Dialect dialectLM21 = new SMB_Dialect(); dialectLM21.BufferFormat = dialectBufferFormat; dialectLM21.DialectString = dialectLanMan21; SMB_Dialect dialectNTLM = new SMB_Dialect(); dialectNTLM.BufferFormat = dialectBufferFormat; dialectNTLM.DialectString = dialectNtLanMan; request = this.cifsClient.CreateNegotiateRequest(new SMB_Dialect[] { dialectLM21, dialectNTLM }); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); status = (response as SmbNegotiateResponsePacket).SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Negotiate Failed. ErrorCode: " + status); } // Session setup: CifsUserAccount userAccount = new CifsUserAccount(domain, userName, password); request = this.cifsClient.CreateSessionSetupRequest(userAccount, nativeOS, nativeLanMan); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); SmbSessionSetupAndxResponsePacket sessionSetupResponse = response as SmbSessionSetupAndxResponsePacket; status = sessionSetupResponse.SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Session Setup Failed. ErrorCode: " + status); } this.uid = sessionSetupResponse.SmbHeader.Uid; // Tree connect: string ipcAddress = "\\\\" + server + '\\' + ipcConnectString; request = this.cifsClient.CreateTreeConnectAndxRequest(this.uid, TreeConnectAndxFlags.NONE, ipcAddress, treeConnectService, null, null); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); SmbTreeConnectAndxResponsePacket treeConnectResponse = response as SmbTreeConnectAndxResponsePacket; status = treeConnectResponse.SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Tree Connect Failed. ErrorCode: " + status); } this.treeId = treeConnectResponse.SmbHeader.Tid; }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name of ip address</param> /// <param name="client">client name of ip address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception> public override void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage = SecurityPackageType.Ntlm, bool useServerToken = false) { this.cifsClient.Connect(server, client); SmbPacket request, response; uint status; // Negotiate: SMB_Dialect dialectLM21 = new SMB_Dialect(); dialectLM21.BufferFormat = dialectBufferFormat; dialectLM21.DialectString = dialectLanMan21; SMB_Dialect dialectNTLM = new SMB_Dialect(); dialectNTLM.BufferFormat = dialectBufferFormat; dialectNTLM.DialectString = dialectNtLanMan; request = this.cifsClient.CreateNegotiateRequest(new SMB_Dialect[] { dialectLM21, dialectNTLM }); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); status = (response as SmbNegotiateResponsePacket).SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Negotiate Failed. ErrorCode: " + status); } // Session setup: CifsUserAccount userAccount = new CifsUserAccount(domain, userName, password); request = this.cifsClient.CreateSessionSetupRequest(userAccount, nativeOS, nativeLanMan); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); SmbSessionSetupAndxResponsePacket sessionSetupResponse = response as SmbSessionSetupAndxResponsePacket; status = sessionSetupResponse.SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Session Setup Failed. ErrorCode: " + status); } this.uid = sessionSetupResponse.SmbHeader.Uid; // Tree connect: string ipcAddress = "\\\\" + server + '\\' + ipcConnectString; request = this.cifsClient.CreateTreeConnectAndxRequest(this.uid, TreeConnectAndxFlags.NONE, ipcAddress, treeConnectService, null, null); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); SmbTreeConnectAndxResponsePacket treeConnectResponse = response as SmbTreeConnectAndxResponsePacket; status = treeConnectResponse.SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Tree Connect Failed. ErrorCode: " + status); } this.treeId = treeConnectResponse.SmbHeader.Tid; }
/// <summary> /// Connect to a share indicated by shareName in server /// This will use smb over tcp as transport. Only one server /// can be connected at one time /// </summary> /// <param name="serverName">The server Name</param> /// <param name="port">The server port</param> /// <param name="ipVersion">The ip version</param> /// <param name="domain">The domain name</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception> public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken) { smbClient.Connect(serverName, port, ipVersion, defaultBufferSize); InternalConnectShare(serverName, domain, userName, password, shareName, securityPackage); }
/// <summary> /// Constructor. /// </summary> /// <param name="securityPackageType">Security package type.</param> protected SecurityConfig(SecurityPackageType securityPackageType) { this.securityType = securityPackageType; }
/// <summary> /// Connect to a share indicated by shareName in server /// This will use smb over tcp as transport. Only one server /// can be connected at one time /// </summary> /// <param name="serverName">The server Name</param> /// <param name="port">The server port</param> /// <param name="ipVersion">The ip version</param> /// <param name="domain">The domain name</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> /// <param name="useServerToken">Whether to use token from server</param> /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception> public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken) { throw new NotImplementedException(); }
/// <summary> /// Connect share specified by shareName, this function does not issue tcp or netbios /// connect, it does Negotiate -> SessionSetup -> TreeConnect /// </summary> /// <param name="serverName">The server name</param> /// <param name="domain">The domain</param> /// <param name="userName">The user name</param> /// <param name="password">The password</param> /// <param name="shareName">The share name</param> /// <param name="securityPackage">The security package</param> private void InternalConnectShare(string serverName, string domain, string userName, string password, string shareName, SecurityPackageType securityPackage) { SmbPacket request; SmbPacket response; uint status; // Negotiate: request = this.smbClient.CreateNegotiateRequest( defaultSignState, new string[] { DialectNameString.NTLANMAN }); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); if (status != 0) { throw new InvalidOperationException("Negotiate Failed. ErrorCode: " + status); } SecurityModes securityMode = (response as SmbNegotiateResponsePacket).SmbParameters.SecurityMode; this.isSignRequired = (securityMode & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) == SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; SmbSecurityPackage secPkg; switch (securityPackage) { case SecurityPackageType.Ntlm: secPkg = SmbSecurityPackage.NTLM; break; case SecurityPackageType.Kerberos: secPkg = SmbSecurityPackage.Kerberos; break; case SecurityPackageType.Negotiate: secPkg = SmbSecurityPackage.Negotiate; break; default: throw new ArgumentException("Unsupported securityPackage: " + securityPackage.ToString()); } // Session setup: request = this.smbClient.CreateFirstSessionSetupRequest(secPkg, serverName, domain, userName, password); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); while (status != 0) { if ((int)status == (int)SmbStatus.STATUS_MORE_PROCESSING_REQUIRED) { this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid; request = this.smbClient.CreateSecondSessionSetupRequest(this.uid, secPkg); response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); } else { throw new InvalidOperationException("Session Setup Failed. ErrorCode: " + status); } } this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid; if (isSignRequired) { CifsClientPerSession session = this.smbClient.Context.GetSession( this.smbClient.Context.Connection.ConnectionId, this.uid); this.sessionKey = session.SessionKey; } // Tree connect: string sharePath = "\\\\" + serverName + '\\' + shareName; request = this.smbClient.CreateTreeConnectRequest(this.uid, sharePath); if (this.isSignRequired) { request.Sign(this.NextSequenceNumber, this.sessionKey); } response = this.SendAndExpectSmbPacket(request, internalTimeout, out status); if (status != 0) { throw new InvalidOperationException("Tree Connect Failed. ErrorCode: " + status); } this.treeId = (response as SmbTreeConnectAndxResponsePacket).SmbHeader.Tid; }