/// <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> /// A continuation Windows Security Context. /// </summary> /// <param name="init"> /// Initial context that contains a handle to the credentials returned by /// AcquireCredentialsHandle. This handle is used to build the security context. /// </param> /// <param name="continueToken"> /// Token returned by the remote computer. /// </param> /// <param name="fContextReq"> /// Bit flags that indicate requests for the context. Not all packages can support all requirements. /// Flags used for this parameter are prefixed with ISC_REQ_, for example, ISC_REQ_DELEGATE. /// </param> /// <param name="targetDataRep"> /// </param> public WindowsSecurityContext(WindowsSecurityContext init, byte[] continueToken, int fContextReq, int targetDataRep) { _targetName = init._targetName; _credentials = init._credentials; _securityPackage = init._securityPackage; using (var continueTokenBuffer = new Secur32.SecBufferDesc(continueToken)) { Initialize(_credentials, _targetName, fContextReq, targetDataRep, init._context, continueTokenBuffer); } }
/// <summary> /// Acquire an existing Windows security context. /// </summary> /// <param name="context"></param> /// <param name="contextAttributes"></param> /// <param name="contextLifetime"></param> /// <param name="continueNeeded"></param> /// <param name="securityPackage"></param> /// <param name="token"></param> public WindowsSecurityContext( Secur32.SecHandle context, uint contextAttributes, Secur32.SECURITY_INTEGER contextLifetime, Secur32.SecBufferDesc token, string securityPackage, bool continueNeeded) { _context = context; _contextAttributes = contextAttributes; _contextLifetime = contextLifetime; _securityPackage = securityPackage; _token = token; _continue = continueNeeded; }
/// <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); }
private void Initialize(Secur32.SecHandle credentials, string targetName, int fContextReq, int targetDataRep, Secur32.SecHandle context, Secur32.SecBufferDesc continueTokenBuffer) { var tokenSize = Secur32.MAX_TOKEN_SIZE; var rc = 0; var hasContextAndContinue = context != Secur32.SecHandle.Zero && continueTokenBuffer != Secur32.SecBufferDesc.Zero; do { _token.Dispose(); _token = new Secur32.SecBufferDesc(tokenSize); if (hasContextAndContinue) { rc = Secur32.InitializeSecurityContext( ref credentials, ref context, targetName, fContextReq, 0, targetDataRep, ref continueTokenBuffer, 0, ref _context, ref _token, out _contextAttributes, out _contextLifetime); } else { rc = Secur32.InitializeSecurityContext( ref credentials, IntPtr.Zero, targetName, fContextReq, 0, targetDataRep, IntPtr.Zero, 0, ref _context, ref _token, out _contextAttributes, out _contextLifetime); } switch (rc) { case Secur32.SEC_E_INSUFFICIENT_MEMORY: tokenSize += Secur32.MAX_TOKEN_SIZE; break; case Secur32.SEC_E_OK: break; case Secur32.SEC_I_CONTINUE_NEEDED: _continue = true; break; default: throw new Win32Exception(rc); } } while (rc == Secur32.SEC_E_INSUFFICIENT_MEMORY); }
private void Initialize(Secur32.SecHandle credentials, string targetName, int fContextReq, int targetDataRep) { this.Initialize(credentials, targetName, fContextReq, targetDataRep, Secur32.SecHandle.Zero, Secur32.SecBufferDesc.Zero); }