/// <summary> /// Acquire an existing Windows security context. /// </summary> /// <param name="username">Target username for this security context.</param> /// <param name="credentials">Credentials handle.</param> /// <param name="securityPackage">Security package.</param> /// <param name="fContextReq">Bit flags that indicate requests for the context.</param> /// <param name="targetDataRep">Target data representation.</param> public WindowsSecurityContext(string username, WindowsCredentialsHandle credentials, string securityPackage, int fContextReq, int targetDataRep) { _username = username; _credentials = credentials.Handle; _securityPackage = securityPackage; _token = new Secur32.SecBufferDesc(Secur32.MAX_TOKEN_SIZE); int rc = Secur32.InitializeSecurityContext( ref credentials.Handle, IntPtr.Zero, username, // service principal name fContextReq, 0, targetDataRep, IntPtr.Zero, 0, ref _context, ref _token, out _contextAttributes, out _contextLifetime); switch (rc) { case Secur32.SEC_E_OK: break; case Secur32.SEC_I_CONTINUE_NEEDED: _continue = true; break; default: throw new Win32Exception(rc); } }
/// <summary> /// Acquire an existing Windows security context. /// </summary> /// <param name="targetName">Target name for this security context.</param> /// <param name="credentials">Credentials handle.</param> /// <param name="securityPackage">Security package.</param> /// <param name="fContextReq">Bit flags that indicate requests for the context.</param> /// <param name="targetDataRep">Target data representation.</param> public WindowsSecurityContext(string targetName, WindowsCredentialsHandle credentials, string securityPackage, int fContextReq, int targetDataRep) { _targetName = targetName; _credentials = credentials.Handle; _securityPackage = securityPackage; Initialize(credentials.Handle, _targetName, fContextReq, targetDataRep); }
/// <summary> /// Returns the security context of the currently logged on user for a given package. /// </summary> /// <param name="package"></param> /// <param name="targetName"></param> /// <param name="fContextReq"></param> /// <param name="targetDataRep"></param> /// <returns></returns> public static WindowsSecurityContext GetCurrent(string package, string targetName, int fContextReq, int targetDataRep) { using (WindowsCredentialsHandle credentialsHandle = new WindowsCredentialsHandle( string.Empty, Secur32.SECPKG_CRED_OUTBOUND, package)) { return(new WindowsSecurityContext( targetName, credentialsHandle, package, fContextReq, targetDataRep)); } }
/// <summary> /// Validate a security token and return the windows account of the user that generated the token. /// Implementation of <see cref="T:Waffle.Windows.AuthProvider.IWindowsAuthProvider.ValidateNegotiateToken" />. /// </summary> /// <remarks> /// This function supports AcceptSecurityToken continuation on the same thread. /// </remarks> /// <param name="connectionId">Connection id.</param> /// <param name="token">Security token.</param> /// <param name="securityPackage">Security package, eg. "Negotiate".</param> /// <param name="fContextReq"></param> /// <param name="targetDataRep"></param> /// <returns></returns> public IWindowsSecurityContext AcceptSecurityToken(string connectionId, byte[] token, string securityPackage, int fContextReq, int targetDataRep) { Secur32.SecHandle newContext = Secur32.SecHandle.Zero; Secur32.SecBufferDesc serverToken = Secur32.SecBufferDesc.Zero; Secur32.SecBufferDesc clientToken = Secur32.SecBufferDesc.Zero; Secur32.SECURITY_INTEGER serverLifetime = Secur32.SECURITY_INTEGER.Zero; WindowsCredentialsHandle credentialsHandle = new WindowsCredentialsHandle( string.Empty, Secur32.SECPKG_CRED_INBOUND, securityPackage); // AcceptSecurityContext serverToken = new Secur32.SecBufferDesc(Secur32.MAX_TOKEN_SIZE); clientToken = new Secur32.SecBufferDesc(token); uint serverContextAttributes = 0; Secur32.SecHandle continueSecHandle = Secur32.SecHandle.Zero; lock (_continueSecHandles) { _continueSecHandles.TryGetValue(connectionId, out continueSecHandle); } int rc = 0; if (continueSecHandle == Secur32.SecHandle.Zero) { rc = Secur32.AcceptSecurityContext( ref credentialsHandle.Handle, IntPtr.Zero, ref clientToken, fContextReq, targetDataRep, ref newContext, ref serverToken, out serverContextAttributes, out serverLifetime); } else { rc = Secur32.AcceptSecurityContext( ref credentialsHandle.Handle, ref continueSecHandle, ref clientToken, fContextReq, targetDataRep, ref newContext, ref serverToken, out serverContextAttributes, out serverLifetime); } switch (rc) { case Secur32.SEC_E_OK: lock (_continueSecHandles) { _continueSecHandles.Remove(connectionId); } return new WindowsSecurityContext( newContext, serverContextAttributes, serverLifetime, serverToken, securityPackage, false); case Secur32.SEC_I_CONTINUE_NEEDED: lock (_continueSecHandles) { _continueSecHandles[connectionId] = newContext; } return new WindowsSecurityContext( newContext, serverContextAttributes, serverLifetime, serverToken, securityPackage, true); default: lock (_continueSecHandles) { _continueSecHandles.Remove(connectionId); } throw new Win32Exception(rc); } }
/// <summary> /// Returns the security context of the currently logged on user for a given package. /// </summary> /// <param name="package"></param> /// <param name="targetName"></param> /// <param name="fContextReq"></param> /// <param name="targetDataRep"></param> /// <returns></returns> public static WindowsSecurityContext GetCurrent(string package, string targetName, int fContextReq, int targetDataRep) { using (WindowsCredentialsHandle credentialsHandle = new WindowsCredentialsHandle( string.Empty, Secur32.SECPKG_CRED_OUTBOUND, package)) { return new WindowsSecurityContext( targetName, credentialsHandle, package, fContextReq, targetDataRep); } }
/// <summary> /// Validate a security token and return the windows account of the user that generated the token. /// Implementation of <see cref="T:Waffle.Windows.AuthProvider.IWindowsAuthProvider.ValidateNegotiateToken" />. /// </summary> /// <remarks> /// This function supports AcceptSecurityToken continuation on the same thread. /// </remarks> /// <param name="connectionId">Connection id.</param> /// <param name="token">Security token.</param> /// <param name="securityPackage">Security package, eg. "Negotiate".</param> /// <param name="fContextReq"></param> /// <param name="targetDataRep"></param> /// <returns></returns> public IWindowsSecurityContext AcceptSecurityToken(string connectionId, byte[] token, string securityPackage, int fContextReq, int targetDataRep) { Secur32.SecHandle newContext = Secur32.SecHandle.Zero; Secur32.SecBufferDesc serverToken = Secur32.SecBufferDesc.Zero; Secur32.SecBufferDesc clientToken = Secur32.SecBufferDesc.Zero; Secur32.SECURITY_INTEGER serverLifetime = Secur32.SECURITY_INTEGER.Zero; WindowsCredentialsHandle credentialsHandle = new WindowsCredentialsHandle( string.Empty, Secur32.SECPKG_CRED_INBOUND, securityPackage); var tokenSize = Secur32.MAX_TOKEN_SIZE; var rc = 0; do { serverToken = new Secur32.SecBufferDesc(tokenSize); clientToken = new Secur32.SecBufferDesc(token); uint serverContextAttributes = 0; Secur32.SecHandle continueSecHandle = Secur32.SecHandle.Zero; lock (_continueSecHandles) { _continueSecHandles.TryGetValue(connectionId, out continueSecHandle); } if (continueSecHandle == Secur32.SecHandle.Zero) { rc = Secur32.AcceptSecurityContext( ref credentialsHandle.Handle, IntPtr.Zero, ref clientToken, fContextReq, targetDataRep, ref newContext, ref serverToken, out serverContextAttributes, out serverLifetime); } else { rc = Secur32.AcceptSecurityContext( ref credentialsHandle.Handle, ref continueSecHandle, ref clientToken, fContextReq, targetDataRep, ref newContext, ref serverToken, out serverContextAttributes, out serverLifetime); } switch (rc) { case Secur32.SEC_E_INSUFFICIENT_MEMORY: tokenSize += Secur32.MAX_TOKEN_SIZE; break; case Secur32.SEC_E_OK: lock (_continueSecHandles) { _continueSecHandles.Remove(connectionId); } return(new WindowsSecurityContext( newContext, serverContextAttributes, serverLifetime, serverToken, securityPackage, false)); case Secur32.SEC_I_CONTINUE_NEEDED: lock (_continueSecHandles) { _continueSecHandles[connectionId] = newContext; } return(new WindowsSecurityContext( newContext, serverContextAttributes, serverLifetime, serverToken, securityPackage, true)); default: lock (_continueSecHandles) { _continueSecHandles.Remove(connectionId); } throw new Win32Exception(rc); } } while (rc == Secur32.SEC_E_INSUFFICIENT_MEMORY); return(null); }