/// <summary> /// Constructor /// </summary> /// <param name="account">Client account credential.</param> /// <param name="target">Target name.</param> public NlmpClientSecurityConfig( AccountCredential account, string target) : base(SecurityPackageType.Ntlm) { this.clientCredential = account; this.targetName = target; }
/// <summary> /// Constructor /// </summary> /// <param name="clientCredential">Client account credential.</param> /// <param name="serverPrincipal">Server principal.</param> /// <param name="contextAttributes">Client security context attributes.</param> /// <param name="targetDataRep">The data representation, such as byte ordering, on the target.</param> public SspiClientSecurityConfig( AccountCredential clientCredential, string serverPrincipal, ClientSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) : base(SecurityPackageType.Unknown) { this.clientCredential = clientCredential; this.serverPrincipal = serverPrincipal; this.securityAttributes = contextAttributes; this.targetDataRep = targetDataRep; }
/// <summary> /// Constructor /// </summary> /// <param name="clientCredential">Client account credential.</param> /// <param name="serverPrincipal">Server principal.</param> /// <param name="contextAttributes">Client security context attributes.</param> /// <param name="targetDataRep">The data representation, such as byte ordering, on the target.</param> public SspiClientSecurityConfig( AccountCredential clientCredential, string serverPrincipal, ClientSecurityContextAttribute contextAttributes, SecurityTargetDataRepresentation targetDataRep) : base(SecurityPackageType.Unknown) { this.clientCredential = clientCredential; this.serverPrincipal = serverPrincipal; this.securityAttributes = contextAttributes; this.targetDataRep = targetDataRep; }
/// <summary> /// Constructor /// </summary> /// <param name="flags">Negotiation flags.</param> /// <param name="clientCredential">Client account credential.</param> /// <param name="isDomainJoined">Joined in a domain or not</param> /// <param name="netbiosDomainName">Netbios domain name.</param> /// <param name="netbiosMachineName">Netbios machine name.</param> public NlmpServerSecurityConfig( NegotiateTypes flags, NlmpClientCredential clientCredential, bool isDomainJoined, string netbiosDomainName, string netbiosMachineName) : base(SecurityPackageType.Ntlm) { this.negotiateflags = flags; this.clientCredential = clientCredential; this.isDomainJoined = isDomainJoined; this.netbiosDomainName = netbiosDomainName; this.netbiosMachineName = netbiosMachineName; this.targetName = clientCredential.TargetName; }
/// <summary> /// Set up an RPC session with a specific server. /// </summary> /// <param name="serverName">Server computer name</param> /// <param name="credential">User account used to setup this session</param> /// <param name="securityContext">Security context of session</param> public void Bind( string serverName, AccountCredential credential, ClientSecurityContext securityContext) { if (string.IsNullOrEmpty(serverName)) { throw new ArgumentNullException("serverName"); } InnerBind( RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, serverName, SrvsUtility.SRVS_NAMED_PIPE, credential, securityContext); }
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); }
/// <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); }
/// <summary> /// Initialize RpceServerContext. /// </summary> /// <param name="protocolSequence">The RPC protocol sequence strings.</param> /// <param name="endpoint">The endpoint of server.</param> /// <param name="namedPipeTransportCredential">Credential for namepiped transport.</param> internal RpceServerContext( String protocolSequence, String endpoint, AccountCredential namedPipeTransportCredential) { this.protocolSequence = protocolSequence; this.endpoint = endpoint; this.namedPipeTransportCredential = namedPipeTransportCredential; this.sessions = new Dictionary<string, RpceServerSessionContext>(); this.tempSessions = new Dictionary<string, RpceServerSessionContext>(); //set default value this.maxReceiveFragmentSize = RpceUtility.DEFAULT_MAX_RECEIVE_FRAGMENT_SIZE; this.maxTransmitFragmentSize = RpceUtility.DEFAULT_MAX_TRANSMIT_FRAGMENT_SIZE; this.rpcVersionMajor = 5; this.rpcVersionMinor = 1; this.ndrVersion = RpceNdrVersion.NDR; }
/// <summary> /// Constructor. Convert account /// </summary> /// <param name="credential">Account credential</param> public SecurityWinntAuthIdentity(AccountCredential credential) { this.User = IntPtr.Zero; this.UserLength = 0; this.Domain = IntPtr.Zero; this.DomainLength = 0; this.Password = IntPtr.Zero; this.PasswordLength = 0; this.Flags = NativeMethods.SEC_WINNT_AUTH_IDENTITY_UNICODE; if (credential != null) { if (credential.AccountName != null) { this.UserLength = credential.AccountName.Length; if (this.UserLength != 0) { this.User = Marshal.StringToHGlobalUni(credential.AccountName); } } if (credential.DomainName != null) { this.DomainLength = credential.DomainName.Length; if (this.DomainLength != 0) { this.Domain = Marshal.StringToHGlobalUni(credential.DomainName); } } if (credential.Password != null) { this.PasswordLength = credential.Password.Length; if (this.PasswordLength != 0) { this.Password = Marshal.StringToHGlobalUni(credential.Password); } } } }
/// <summary> /// Bind to SAMR RPC server. /// </summary> /// <param name="protocolSequence"> /// RPC protocol sequence. /// </param> /// <param name="networkAddress"> /// RPC network address. /// </param> /// <param name="endpoint"> /// RPC endpoint. /// </param> /// <param name="transportCredential"> /// If connect by SMB/SMB2, it's the security credential /// used by under layer transport (SMB/SMB2). /// If connect by TCP, this parameter is ignored. /// </param> /// <param name="securityContext"> /// RPC security provider. /// </param> /// <param name="authenticationLevel"> /// RPC authentication level. /// </param> /// <param name="timeout"> /// Timeout /// </param> public void Bind( string protocolSequence, string networkAddress, string endpoint, AccountCredential transportCredential, ClientSecurityContext securityContext, RpceAuthenticationLevel authenticationLevel, TimeSpan timeout) { if (rpceClientTransport != null) { throw new InvalidOperationException("SAMR has already been binded."); } rpceTimeout = timeout; rpceClientTransport = new RpceClientTransport(); rpceClientTransport.Bind( protocolSequence, networkAddress, endpoint, transportCredential, SamrUtility.SAMR_RPC_INTERFACE_UUID, SamrUtility.SAMR_RPC_INTERFACE_MAJOR_VERSION, SamrUtility.SAMR_RPC_INTERFACE_MINOR_VERSION, securityContext, authenticationLevel, false, rpceTimeout); }
/// <summary> /// to start the smbserver, tcp transport. /// </summary> /// <param name="serverAddress">the address of server</param> /// <param name="localPort">the local port to bind for server</param> /// <param name="maxConnections">the max connections of server capability</param> /// <param name="bufferSize">the buffer size of transport </param> /// <param name="accountCredential">the credential to authenticate client, spn is always cifs/machine</param> public virtual void Start(IPAddress serverAddress, int localPort, int maxConnections, int bufferSize, AccountCredential accountCredential) { this.credential = accountCredential; SocketTransportConfig config = new SocketTransportConfig(); config.Type = StackTransportType.Tcp; config.Role = Role.Server; config.LocalIpAddress = serverAddress; config.LocalIpPort = localPort; config.MaxConnections = maxConnections; config.BufferSize = bufferSize; SmbServerDecodePacket decoder = new SmbServerDecodePacket(); decoder.Context = this.context; this.transport = new TransportStack(config, decoder.DecodePacket); this.transport.Start(); this.transportType = TransportType.TCP; }
public virtual void Start( string localNetbiosName, int adapterIndex, int bufferSize, int maxSessions, int maxNames, AccountCredential credential) { if (localNetbiosName == null) { throw new ArgumentNullException("localNetbiosName"); } NetbiosTransportConfig config = new NetbiosTransportConfig(); config.Type = StackTransportType.Netbios; config.Role = Role.Server; config.AdapterIndex = (byte)adapterIndex; config.BufferSize = bufferSize; config.MaxSessions = maxSessions; config.MaxNames = maxNames; config.LocalNetbiosName = localNetbiosName; SmbServerDecodePacket decoder = new SmbServerDecodePacket(); decoder.Context = this.context; this.transport = new TransportStack(config, decoder.DecodePacket); this.transport.Start(); this.transportType = TransportType.NetBIOS; }
/// <summary> /// <para>does not support this method.</para> /// start server and prepare to accept the connection from client. /// the under-layer transport is tcp/ip. /// </summary> /// <param name="listenPort">the port for serverto listen </param> /// <param name="credential">Credential to accept a connection.</param> /// <param name="ipAddress">server's ipAddress</param> /// <exception cref="NotSupportedException">does not support this method.</exception> public override void Start(ushort listenPort, AccountCredential credential, IPAddress ipAddress) { throw new NotSupportedException("does not support this method."); }
/// <summary> /// Performs CredSSP authentication. /// </summary> /// <exception cref="IOException">Raised when attempting to read from/write to the remote connection which /// has been closed</exception> /// <exception cref="EndOfStreamException">Raised when the username or password doesn't match or authentication /// fails</exception> public void Authenticate() { // Authenticated already, do nothing if (isAuthenticated) { return; } credential = new AccountCredential(domain, userName, password); byte[] receivedBuffer = new byte[MaxBufferSize]; int bytesReceived = 0; // Dispose the context as it may be timed out if (context != null) { context.Dispose(); } context = new SspiClientSecurityContext( SecurityPackageType.CredSsp, credential, serverPrincipal, attribute, SecurityTargetDataRepresentation.SecurityNativeDrep); context.Initialize(null); // Get first token byte[] token = context.Token; // SSL handshake while (context.NeedContinueProcessing) { // Send handshake request clientStream.Write(token, 0, token.Length); // Get handshake resopnse bytesReceived = clientStream.Read(receivedBuffer, 0, receivedBuffer.Length); // The remote connection has been closed if (bytesReceived == 0) { throw new EndOfStreamException("Authentication failed: remote connection has been closed."); } byte[] inToken = new byte[bytesReceived]; Array.Copy(receivedBuffer, inToken, bytesReceived); // Get next token from response context.Initialize(inToken); token = context.Token; } // Send the last token, handshake over, CredSSP is established // Note if there're errors during authentication, an SSPIException will be raised // and isAuthentication will not be true. clientStream.Write(token, 0, token.Length); isAuthenticated = true; }
/// <summary> /// start server and prepare to accept the connection from client.<para/> /// the under-layer transport is netbios. /// </summary> /// <param name="localNetbiosName">the local Netbios name. It is only used in NetBios tranport.</param> /// <param name="credential">Credential to accept a connection.</param> public abstract void Start(string localNetbiosName, AccountCredential credential);
/// <summary> /// RPC bind to interface, using specified endpoint and authenticate provider. /// </summary> /// <param name="protocolSequence">RPC protocol sequence.</param> /// <param name="networkAddress">RPC network address.</param> /// <param name="endpoint">RPC endpoint.</param> /// <param name="transportCredential"> /// If connect by SMB/SMB2, it's the security credential /// used by underlayer transport (SMB/SMB2). /// If connect by TCP, this parameter is ignored. /// </param> /// <param name="securityContext">RPC security provider.</param> /// <param name="authenticationLevel">RPC authentication level.</param> /// <param name="timeout">Timeout for bind and all future requests.</param> /// <exception cref="InvalidOperationException"> /// Thrown when rpceClientTransport is not null. /// </exception> public void Bind( string protocolSequence, string networkAddress, string endpoint, AccountCredential transportCredential, ClientSecurityContext securityContext, RpceAuthenticationLevel authenticationLevel, TimeSpan timeout) { if (rpceClientTransport != null) { throw new InvalidOperationException("FSRVP has already been bind."); } rpceTimeout = timeout; rpceClientTransport = new RpceClientTransport(); try { rpceClientTransport.Bind( protocolSequence, networkAddress, endpoint, transportCredential, FsrvpUtility.FSRVP_INTERFACE_UUID, FsrvpUtility.FSRVP_INTERFACE_MAJOR_VERSION, FsrvpUtility.FSRVP_INTERFACE_MINOR_VERSION, securityContext, authenticationLevel, true, rpceTimeout); } catch { rpceClientTransport = null; throw; } }
/// <summary> /// Bind to SAMR RPC server. /// </summary> /// <param name="protocolSequence"> /// RPC protocol sequence. /// </param> /// <param name="networkAddress"> /// RPC network address. /// </param> /// <param name="endpoint"> /// RPC endpoint. /// </param> /// <param name="transportCredential"> /// If connect by SMB/SMB2, it's the security credential /// used by under layer transport (SMB/SMB2). /// If connect by TCP, this parameter is ignored. /// </param> /// <param name="securityContext"> /// RPC security provider. /// </param> /// <param name="authenticationLevel"> /// RPC authentication level. /// </param> /// <param name="timeout"> /// Timeout /// </param> public void Bind( string protocolSequence, string networkAddress, string endpoint, AccountCredential transportCredential, ClientSecurityContext securityContext, RpceAuthenticationLevel authenticationLevel, TimeSpan timeout) { rpc.Bind(protocolSequence, networkAddress, endpoint, transportCredential, securityContext, authenticationLevel, timeout); }
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); } }
/// <summary> /// Start to listen on a named pipe. /// </summary> /// <param name="namedPipe">The name of named pipe to listen on.</param> /// <param name="credential">Credential to be used by underlayer SMB/SMB2 transport.</param> /// <exception cref="InvalidOperationException"> /// Thrown when the server with the named pipe has been started. /// </exception> /// <param name="ipAddress">server's ipAddress</param> public virtual RpceServerContext StartNamedPipe(string namedPipe, AccountCredential credential, IPAddress ipAddress) { namedPipe = namedPipe.ToUpper(); lock (this.smbThreadLocker) { RpceServerContext serverContext = this.serverContextManager.LookupServerContext( RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, namedPipe); if (serverContext != null) { throw new InvalidOperationException("The server with the named pipe has been started. Please try other port."); } serverContext = new RpceServerContext( RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, namedPipe, credential); this.serverContextManager.AddServerContext(serverContext); if (this.openedNamedPipeList == null) { this.openedNamedPipeList = new List<string>(); } this.openedNamedPipeList.Add(namedPipe); try { if (this.smbTransport == null) { this.smbTransport = new Smb.SmbServerTransport(); this.smbTransport.Start(RpceUtility.NAMED_PIPE_PORT, credential, ipAddress); } } catch { this.serverContextManager.RemoveServerContext(serverContext); this.openedNamedPipeList.Remove(namedPipe); throw; } if (this.smbReceiveThread == null) { this.smbReceiveThread = new Thread(SmbReceiveLoop); this.smbReceiveThread.Start(); } return serverContext; } }
protected bool AccessShare(AccountCredential user, string sharePath) { bool accessSucceed = true; Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); try { BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message."); client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled); BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", user.AccountName, user.DomainName); client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, user, false); uint treeId; BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", sharePath); client.TreeConnect(sharePath, out treeId, checker: (header, response) => { if (header.Status == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Access succeeded in TREE_CONNECT phase."); accessSucceed = true; } else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Access denied in TREE_CONNECT phase."); accessSucceed = false; } else { BaseTestSite.Assert.Fail("Unexpected error code in TREE_CONNECT response: {0}", Smb2Status.GetStatusCode(header.Status)); } }); if (!accessSucceed) { client.LogOff(); return false; } FILEID fileId; Smb2CreateContextResponse[] createContexResponse; BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends CREATE request."); uint status = client.Create( treeId, null, CreateOptions_Values.FILE_DIRECTORY_FILE, out fileId, out createContexResponse, accessMask: AccessMask.FILE_READ_DATA | AccessMask.FILE_READ_ATTRIBUTES, createDisposition: CreateDisposition_Values.FILE_OPEN, checker: (header, response) => { if (header.Status == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Access succeeded in CREATE phase."); accessSucceed = true; } else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Access denied in CREATE phase."); accessSucceed = false; } else { BaseTestSite.Assert.Fail("Unexpected error code in CREATE response: {0}", Smb2Status.GetStatusCode(header.Status)); } }); if (status == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF."); client.Close(treeId, fileId); } client.TreeDisconnect(treeId); client.LogOff(); } finally { client.Disconnect(); } return accessSucceed; }
protected bool ShareExists(AccountCredential user, string sharePath) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Test whether the specific share exists: {0}", sharePath); Smb2FunctionalClient clientAdmin; clientAdmin = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientAdmin.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); uint treeId; bool connected = ConnectToShare(clientAdmin, user, sharePath, out treeId); if (connected) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Share exists: {0}", sharePath); clientAdmin.TreeDisconnect(treeId); clientAdmin.LogOff(); } else { BaseTestSite.Log.Add(LogEntryKind.Debug, "Share does not exist: {0}", sharePath); } clientAdmin.Disconnect(); return connected; }
protected bool ConnectToShare(Smb2FunctionalClient client, AccountCredential user, string sharePath, out uint treeId) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message."); client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled); AccountCredential accountCredential = user; BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", accountCredential.AccountName, accountCredential.DomainName); client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, accountCredential, false); BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", sharePath); uint status = client.TreeConnect(sharePath, out treeId, checker: (header, response) => { }); if (status == Smb2Status.STATUS_SUCCESS) { return true; } if (status == Smb2Status.STATUS_BAD_NETWORK_NAME) { return false; } throw new Exception(string.Format("Share detection failed with unexpected error: {0}", Smb2Status.GetStatusCode(status))); }
/// <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> /// start server and prepare to accept the connection from client.<para/> /// the under-layer transport is tcp/ip. /// </summary> /// <param name="listenPort">the port for serverto listen </param> /// <param name="credential">Credential to accept a connection.</param> /// <param name="ipAddress">server's ipAddress</param> public abstract void Start(ushort listenPort, AccountCredential credential, IPAddress ipAddress);
/// <summary> /// <para>Start the server, use NetBIOS Extended User Interface as transport.</para> /// <para>Please customize Context before start this service. All of those properties will be used.</para> /// <para>If config.serverNetbiosName is null or empty, Context.ServerName will be used, /// which by default is the NetBIOS name of this local computer.</para> /// </summary> /// <param name="credential">Credential to accept a connection.</param> public virtual void Start(AccountCredential credential) { this.context.AccountCredentials.Add(credential); this.transport.Start(); this.isRunning = true; }
/// <summary> /// RPC bind over named pipe, using well-known endpoint "\\pipe\\FssagentRpc". /// </summary> /// <param name="serverName">FSRVP server machine name.</param> /// <param name="transportCredential"> /// If connect by SMB/SMB2, it's the security credential /// used by underlayer transport (SMB/SMB2). /// If connect by TCP, this parameter is ignored. /// </param> /// <param name="securityContext"> /// Security provider for RPC. /// Set the value to null to disable authentication. /// </param> /// <param name="timeout">Timeout for bind and all future requests.</param> /// <returns>Return true if success, otherwise return false.</returns> /// <exception cref="ArgumentNullException"> /// Thrown when serverName is null. /// </exception> public void BindOverNamedPipe( string serverName, AccountCredential transportCredential, ClientSecurityContext securityContext, TimeSpan timeout) { if (serverName == null) { throw new ArgumentNullException("serverName"); } Bind( RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, serverName, FsrvpUtility.FSRVP_NAMED_PIPE, transportCredential, securityContext, context.AuthenticationLevel, timeout); }
/// <summary> /// Constructor. Convert account /// </summary> /// <param name="credential">Account credential</param> public SecurityWinntAuthIdentity(AccountCredential credential) { this.User = IntPtr.Zero; this.UserLength = 0; this.Domain = IntPtr.Zero; this.DomainLength = 0; this.Password = IntPtr.Zero; this.PasswordLength = 0; this.Flags = NativeMethods.SEC_WINNT_AUTH_IDENTITY_UNICODE; if (credential != null) { if (credential.AccountName != null) { this.UserLength = credential.AccountName.Length; if (this.UserLength != 0) { this.User = Marshal.StringToHGlobalUni(credential.AccountName); } } if (credential.DomainName != null) { this.DomainLength = credential.DomainName.Length; if (this.DomainLength != 0) { this.Domain = Marshal.StringToHGlobalUni(credential.DomainName); } } if (credential.Password != null) { this.PasswordLength = credential.Password.Length; if (this.PasswordLength != 0) { this.Password = Marshal.StringToHGlobalUni(credential.Password); } } } }
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> /// start server and prepare to accept the connection from client.<para/> /// the under-layer transport is netbios. /// </summary> /// <param name="localNetbiosName">the local Netbios name. It is only used in NetBios transport.</param> /// <param name="credential">Credential to accept a connection.</param> public override void Start(string localNetbiosName, AccountCredential credential) { this.cifsServer.Context.ServerName = localNetbiosName; this.cifsServer.Start(credential); }
/// <summary> /// Common method used to connect to target server, including the following message sequences: /// 1. Negotiate /// 2. Session Setup /// 3. Tree Connect /// </summary> /// <param name="smb2Dialect"></param> /// <param name="client"></param> /// <param name="clientGuid"></param> /// <param name="account"></param> /// <param name="connectShareType"></param> /// <param name="treeId"></param> /// <param name="clientBeforeDisconnection"></param> protected virtual void Connect(DialectRevision smb2Dialect, Smb2FunctionalClient client, Guid clientGuid, AccountCredential account, ConnectShareType connectShareType, out uint treeId, Smb2FunctionalClient clientBeforeDisconnection) { DialectRevision[] requestDialect = Smb2Utility.GetDialects(smb2Dialect); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; IPAddress targetIPAddress = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerIP : testConfig.SutIPAddress; string targetServer = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName; client.ConnectToServer(TestConfig.UnderlyingTransport, targetServer, targetIPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends NEGOTIATE request.", clientGuid); client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid); if (null != clientBeforeDisconnection) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request to reconnect to the previous session.", clientGuid); client.ReconnectSessionSetup( clientBeforeDisconnection, testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } else { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request.", clientGuid); client.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends TREE_CONNECT request.", clientGuid); client.TreeConnect( durableHandleUncSharePath, out treeId, checker: (header, response) => { BaseTestSite.Log.Add( LogEntryKind.Debug, "Capabilities in TREE_CONNECT response: {0}", response.Capabilities); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful", header.Command); if (connectShareType == ConnectShareType.CAShare) { BaseTestSite.Assert.AreEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } if (connectShareType == ConnectShareType.BasicShare) { BaseTestSite.Assert.AreNotEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should not have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } }); }
private void InnerBind( string protocolSequence, string networkAddress, string endpoint, AccountCredential transportCredential, ClientSecurityContext securityContext) { if (RpceClientTransport != null) { throw new InvalidOperationException("SRVS has already been bind"); } RpceClientTransport = new RpceClientTransport(); try { RpceClientTransport.Bind( protocolSequence, networkAddress, endpoint, transportCredential, SrvsUtility.SRVS_INTERFACE_UUID, SrvsUtility.SRVS_INTERFACE_MAJOR_VERSION, SrvsUtility.SRVS_INTERFACE_MINOR_VERSION, securityContext, AuthenticationLevel, true, RpceTimeout); } catch { RpceClientTransport = null; throw; } }
/// <summary> /// Connect to server. /// </summary> /// <param name="client">Fsrvp client.</param> /// <param name="server">The name of server.</param> /// <returns>Return true if success, otherwise return false.</returns> private bool ConnectServer(ref FsrvpClient client, string server) { AccountCredential accountCredential = new AccountCredential(TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword); ClientSecurityContext securityContext = new SspiClientSecurityContext( TestConfig.DefaultSecurityPackage, accountCredential, Smb2Utility.GetCifsServicePrincipalName(server), ClientSecurityContextAttribute.Connection | ClientSecurityContextAttribute.DceStyle | ClientSecurityContextAttribute.Integrity | ClientSecurityContextAttribute.ReplayDetect | ClientSecurityContextAttribute.SequenceDetect | ClientSecurityContextAttribute.UseSessionKey, SecurityTargetDataRepresentation.SecurityNativeDrep); // This indicates that the RPC message is just integrity-protected. client.Context.AuthenticationLevel = TestConfig.DefaultRpceAuthenticationLevel; try { BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to server {0}.", server); client.BindOverNamedPipe(server, accountCredential, securityContext, new TimeSpan(0, 0, (int)FsrvpUtility.FSRVPTimeoutInSeconds)); } catch (Exception ex) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to server {0} failed. Exception: {1}", server, ex.Message); client.Unbind(TestConfig.Timeout); return false; } BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to server {0} successfully.", server); return true; }
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); }