/// <summary>
        /// Performs and/or continues the authentication cycle.
        /// </summary>
        /// <param name="clientToken">The most recent token from the client.</param>
        /// <returns>The client's next authentication token in the cycle.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="clientToken" /> is null.</exception>
        /// <exception cref="SspiException">
        /// This method was called after this context was fully initialized.
        /// <para>or</para>
        /// The underlying SSPI operation failed.
        /// </exception>
        /// <remarks>
        /// This method is performed iteratively to start, continue, and end the authentication cycle with the server.
        /// Each stage works by acquiring a token from one side and presenting it to the other side, which in turn may generate a new token.
        /// The cycle continues until the client and server both indicate that they are done.
        /// </remarks>
        public SspiToken AcceptToken(SspiToken clientToken)
        {
            if (clientToken == null)
            {
                throw new ArgumentNullException(nameof(clientToken));
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(SecurityContext));
            }
            else if (Initialized)
            {
                throw new SspiException("Attempted to call Initialize on a server context that was already initialized.");
            }

            SecureBuffer clientBuffer = new SecureBuffer(clientToken.Token, SecureBufferType.Token);
            SecureBuffer outputBuffer = new SecureBuffer(new byte[Credential.PackageInfo.MaxTokenLength], SecureBufferType.Token);

            SecurityStatus status = Handle.AcceptSecurityContext(outputBuffer, clientBuffer, Credential.Handle, _requestedAttributes);

            if (!status.IsError())
            {
                if (status == SecurityStatus.Ok)
                {
                    Initialized = true;
                }

                return(new SspiToken(outputBuffer));
            }
            else
            {
                throw new SspiException("Failed to initialize security context for a server.");
            }
        }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SspiToken" /> class.
 /// </summary>
 /// <param name="tokenBuffer">The token buffer.</param>
 internal SspiToken(SecureBuffer tokenBuffer)
 {
     if (tokenBuffer.Length > 0)
     {
         Token = new byte[tokenBuffer.Length];
         Array.Copy(tokenBuffer.Buffer, Token, Token.Length);
     }
 }
Пример #3
0
        private SspiToken Initialize(byte[] serverToken)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(ClientSecurityContext));
            }
            else if (Initialized)
            {
                throw new SspiException("Attempted to call Initialize on a client context that was already initialized.");
            }

            // The security package tells us how long its biggest token will be.
            // Allocate a buffer that size, and it will tell us how much it used.
            SecureBuffer outputBuffer = new SecureBuffer(new byte[Credential.PackageInfo.MaxTokenLength], SecureBufferType.Token);

            SecurityStatus status;

            if (serverToken == null)
            {
                // First time calling initialize - no server token yet
                status = Handle.InitializeSecurityContext(outputBuffer, Credential.Handle, _serverPrinciple, _requestedAttributes);
            }
            else
            {
                // Subsequent calls - server token has been provided
                SecureBuffer serverBuffer = new SecureBuffer(serverToken, SecureBufferType.Token);
                status = Handle.InitializeSecurityContext(outputBuffer, serverBuffer, Credential.Handle, _serverPrinciple, _requestedAttributes);
            }

            if (!status.IsError())
            {
                if (status == SecurityStatus.Ok)
                {
                    Initialized = true;
                }

                return(new SspiToken(outputBuffer));
            }
            else
            {
                throw new SspiException("Failed to initialize security context for a client.");
            }
        }
Пример #4
0
        /// <summary>
        /// Establishes a security context between the server and a remote client.
        /// </summary>
        /// <param name="outputBuffer">The buffer that will hold the output token.</param>
        /// <param name="clientBuffer">The buffer containing the input data from the client.</param>
        /// <param name="credential">The credential handle.</param>
        /// <param name="requestedAttributes">The requested attributes.</param>
        /// <returns>A <see cref="SecurityStatus" /> representing the result of the operation.</returns>
        public SecurityStatus AcceptSecurityContext(SecureBuffer outputBuffer, SecureBuffer clientBuffer, SafeCredentialHandle credential, SecurityContextAttributes requestedAttributes)
        {
            SecurityContextAttributes finalAttributes = SecurityContextAttributes.None;
            Timestamp expiry = new Timestamp();

            using (SecureBufferAdapter outputAdapter = new SecureBufferAdapter(outputBuffer))
            {
                using (SecureBufferAdapter clientAdapter = new SecureBufferAdapter(clientBuffer))
                {
                    if (this.IsInvalid)
                    {
                        return(NativeMethods.AcceptSecurityContext_1
                               (
                                   ref credential.RawHandle,
                                   IntPtr.Zero,
                                   clientAdapter.Handle,
                                   requestedAttributes,
                                   NativeMethods.SecureBufferDataRep.Network,
                                   ref RawHandle,
                                   outputAdapter.Handle,
                                   ref finalAttributes,
                                   ref expiry
                               ));
                    }
                    else
                    {
                        return(NativeMethods.AcceptSecurityContext_2
                               (
                                   ref credential.RawHandle,
                                   ref RawHandle,
                                   clientAdapter.Handle,
                                   requestedAttributes,
                                   NativeMethods.SecureBufferDataRep.Network,
                                   ref RawHandle,
                                   outputAdapter.Handle,
                                   ref finalAttributes,
                                   ref expiry
                               ));
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Initializes the client-side security context from a credental handle.
        /// </summary>
        /// <param name="outputBuffer">The buffer that will hold the output token.</param>
        /// <param name="credential">The credential handle.</param>
        /// <param name="serverPrincipal">The server principal.</param>
        /// <param name="requestedAttributes">The requested attributes.</param>
        /// <returns>A <see cref="SecurityStatus" /> representing the result of the operation.</returns>
        public SecurityStatus InitializeSecurityContext(SecureBuffer outputBuffer, SafeCredentialHandle credential, string serverPrincipal, SecurityContextAttributes requestedAttributes)
        {
            SecurityContextAttributes finalAttributes = SecurityContextAttributes.None;
            Timestamp expiry = new Timestamp();

            using (SecureBufferAdapter outputAdapter = new SecureBufferAdapter(outputBuffer))
            {
                return(NativeMethods.InitializeSecurityContext_1
                       (
                           ref credential.RawHandle,
                           IntPtr.Zero,
                           serverPrincipal,
                           requestedAttributes,
                           0,
                           NativeMethods.SecureBufferDataRep.Network,
                           IntPtr.Zero,
                           0,
                           ref RawHandle,
                           outputAdapter.Handle,
                           ref finalAttributes,
                           ref expiry
                       ));
            }
        }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SecureBufferAdapter" /> class.
 /// </summary>
 /// <param name="buffer">The buffer.</param>
 public SecureBufferAdapter(SecureBuffer buffer)
     : this(new List <SecureBuffer> {
     buffer
 })
 {
 }