AcceptSecurityContext() static private méthode

static private AcceptSecurityContext ( System.Net.Security.SSPIInterface secModule, SafeFreeCredentials &credential, SafeDeleteContext &context, System.Net.Interop inFlags, System.Net.Interop datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, System.Net.Interop &outFlags ) : int
secModule System.Net.Security.SSPIInterface
credential SafeFreeCredentials
context SafeDeleteContext
inFlags System.Net.Interop
datarep System.Net.Interop
inputBuffer SecurityBuffer
outputBuffer SecurityBuffer
outFlags System.Net.Interop
Résultat int
        public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
        {
            Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags);

            int errorCode = SSPIWrapper.AcceptSecurityContext(
                GlobalSSPI.SSPISecureChannel,
                ref credentialsHandle,
                ref context,
                ServerRequiredFlags | (remoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero),
                Interop.SspiCli.Endianness.Native,
                inputBuffer,
                outputBuffer,
                ref unusedAttributes);

            return(SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode));
        }
Exemple #2
0
        // Accepts an incoming binary security blob and returns an outgoing binary security blob.
        internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out Interop.SecurityStatus statusCode)
        {
            GlobalLog.Enter("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString(NumberFormatInfo.InvariantInfo)) + " bytes");

            var list = new List <SecurityBuffer>(2);

            if (incomingBlob != null)
            {
                list.Add(new SecurityBuffer(incomingBlob, SecurityBufferType.Token));
            }

            if (_channelBinding != null)
            {
                list.Add(new SecurityBuffer(_channelBinding));
            }

            SecurityBuffer[] inSecurityBufferArray = null;
            if (list.Count > 0)
            {
                inSecurityBufferArray = list.ToArray();
            }

            var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.Token);

            bool firstTime = _securityContext == null;

            try
            {
                if (!_isServer)
                {
                    // client session
                    statusCode = (Interop.SecurityStatus)SSPIWrapper.InitializeSecurityContext(
                        GlobalSSPI.SSPIAuth,
                        _credentialsHandle,
                        ref _securityContext,
                        _spn,
                        _requestedContextFlags,
                        Interop.SspiCli.Endianness.Network,
                        inSecurityBufferArray,
                        outSecurityBuffer,
                        ref _contextFlags);

                    GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");

                    if (statusCode == Interop.SecurityStatus.CompleteNeeded)
                    {
                        var inSecurityBuffers = new SecurityBuffer[1];
                        inSecurityBuffers[0] = outSecurityBuffer;

                        statusCode = (Interop.SecurityStatus)SSPIWrapper.CompleteAuthToken(
                            GlobalSSPI.SSPIAuth,
                            ref _securityContext,
                            inSecurityBuffers);

                        GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
                        outSecurityBuffer.token = null;
                    }
                }
                else
                {
                    // Server session.
                    statusCode = (Interop.SecurityStatus)SSPIWrapper.AcceptSecurityContext(
                        GlobalSSPI.SSPIAuth,
                        _credentialsHandle,
                        ref _securityContext,
                        _requestedContextFlags,
                        Interop.SspiCli.Endianness.Network,
                        inSecurityBufferArray,
                        outSecurityBuffer,
                        ref _contextFlags);

                    GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
                }
            }
            finally
            {
                //
                // Assuming the ISC or ASC has referenced the credential on the first successful call,
                // we want to decrement the effective ref count by "disposing" it.
                // The real dispose will happen when the security context is closed.
                // Note if the first call was not successful the handle is physically destroyed here.
                //
                if (firstTime && _credentialsHandle != null)
                {
                    _credentialsHandle.Dispose();
                }
            }


            if (((int)statusCode & unchecked ((int)0x80000000)) != 0)
            {
                CloseContext();
                _isCompleted = true;
                if (throwOnError)
                {
                    var exception = new Win32Exception((int)statusCode);
                    GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "Win32Exception:" + exception);
                    throw exception;
                }

                GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "null statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
                return(null);
            }
            else if (firstTime && _credentialsHandle != null)
            {
                // Cache until it is pushed out by newly incoming handles.
                SSPIHandleCache.CacheCredential(_credentialsHandle);
            }

            // The return value from SSPI will tell us correctly if the
            // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm
            // we also have to consider the case in which SSPI formed a new context, in this case we're done as well.
            if (statusCode == Interop.SecurityStatus.OK)
            {
                // Success.
                if ((statusCode == Interop.SecurityStatus.OK) && GlobalLog.IsEnabled)
                {
                    GlobalLog.AssertFormat("NTAuthentication#{0}::GetOutgoingBlob()|statusCode:[0x{1:x8}] ({2}) m_SecurityContext#{3}::Handle:[{4}] [STATUS != OK]", LoggingHash.HashString(this), (int)statusCode, statusCode, LoggingHash.HashString(_securityContext), LoggingHash.ObjectToString(_securityContext));
                }

                _isCompleted = true;
            }
            else
            {
                // We need to continue.
                GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob() need continue statusCode:[0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + LoggingHash.HashString(_securityContext) + "::Handle:" + LoggingHash.ObjectToString(_securityContext) + "]");
            }

            GlobalLog.Leave("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob", "IsCompleted:" + IsCompleted.ToString());
            return(outSecurityBuffer.token);
        }
        internal string GetOutgoingDigestBlob(string incomingBlob, string requestMethod, string requestedUri, string realm, bool isClientPreAuth, bool throwOnError, out SecurityStatus statusCode)
        {
            SecurityBuffer[] inputBuffers = null;
            SecurityBuffer   outputBuffer = new SecurityBuffer(this.m_TokenSize, isClientPreAuth ? BufferType.Parameters : BufferType.Token);
            bool             flag         = this.m_SecurityContext == null;

            try
            {
                if (!this.m_IsServer)
                {
                    if (!isClientPreAuth)
                    {
                        if (incomingBlob != null)
                        {
                            List <SecurityBuffer> list = new List <SecurityBuffer>(5)
                            {
                                new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(incomingBlob), 2),
                                new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), 3),
                                new SecurityBuffer(null, 3),
                                new SecurityBuffer(Encoding.Unicode.GetBytes(this.m_Spn), 0x10)
                            };
                            if (this.m_ChannelBinding != null)
                            {
                                list.Add(new SecurityBuffer(this.m_ChannelBinding));
                            }
                            inputBuffers = list.ToArray();
                        }
                        statusCode = (SecurityStatus)SSPIWrapper.InitializeSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, requestedUri, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags);
                    }
                    else
                    {
                        statusCode = SecurityStatus.OK;
                    }
                }
                else
                {
                    List <SecurityBuffer> list2 = new List <SecurityBuffer>(6)
                    {
                        (incomingBlob == null) ? new SecurityBuffer(0, BufferType.Token) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(incomingBlob), BufferType.Token),
                        (requestMethod == null) ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters),
                        (requestedUri == null) ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestedUri), BufferType.Parameters),
                        new SecurityBuffer(0, BufferType.Parameters),
                        (realm == null) ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(Encoding.Unicode.GetBytes(realm), BufferType.Parameters)
                    };
                    if (this.m_ChannelBinding != null)
                    {
                        list2.Add(new SecurityBuffer(this.m_ChannelBinding));
                    }
                    inputBuffers = list2.ToArray();
                    statusCode   = (SecurityStatus)SSPIWrapper.AcceptSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags);
                    if (statusCode == SecurityStatus.CompleteNeeded)
                    {
                        inputBuffers[4]    = outputBuffer;
                        statusCode         = (SecurityStatus)SSPIWrapper.CompleteAuthToken(GlobalSSPI.SSPIAuth, ref this.m_SecurityContext, inputBuffers);
                        outputBuffer.token = null;
                    }
                }
            }
            finally
            {
                if (flag && (this.m_CredentialsHandle != null))
                {
                    this.m_CredentialsHandle.Close();
                }
            }
            if ((statusCode & ((SecurityStatus)(-2147483648))) != SecurityStatus.OK)
            {
                this.CloseContext();
                if (throwOnError)
                {
                    Win32Exception exception = new Win32Exception((int)statusCode);
                    throw exception;
                }
                return(null);
            }
            if (flag && (this.m_CredentialsHandle != null))
            {
                SSPIHandleCache.CacheCredential(this.m_CredentialsHandle);
            }
            if (statusCode == SecurityStatus.OK)
            {
                this.m_IsCompleted = true;
            }
            byte[] token = outputBuffer.token;
            string str   = null;

            if ((token != null) && (token.Length > 0))
            {
                str = WebHeaderCollection.HeaderEncoding.GetString(token, 0, outputBuffer.size);
            }
            return(str);
        }
        internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatus statusCode)
        {
            List <SecurityBuffer> list = new List <SecurityBuffer>(2);

            if (incomingBlob != null)
            {
                list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
            }
            if (this.m_ChannelBinding != null)
            {
                list.Add(new SecurityBuffer(this.m_ChannelBinding));
            }
            SecurityBuffer[] inputBuffers = null;
            if (list.Count > 0)
            {
                inputBuffers = list.ToArray();
            }
            SecurityBuffer outputBuffer = new SecurityBuffer(this.m_TokenSize, BufferType.Token);
            bool           flag         = this.m_SecurityContext == null;

            try
            {
                if (!this.m_IsServer)
                {
                    statusCode = (SecurityStatus)SSPIWrapper.InitializeSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_Spn, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags);
                    if (statusCode == SecurityStatus.CompleteNeeded)
                    {
                        SecurityBuffer[] bufferArray2 = new SecurityBuffer[] { outputBuffer };
                        statusCode         = (SecurityStatus)SSPIWrapper.CompleteAuthToken(GlobalSSPI.SSPIAuth, ref this.m_SecurityContext, bufferArray2);
                        outputBuffer.token = null;
                    }
                }
                else
                {
                    statusCode = (SecurityStatus)SSPIWrapper.AcceptSecurityContext(GlobalSSPI.SSPIAuth, this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_RequestedContextFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.m_ContextFlags);
                }
            }
            finally
            {
                if (flag && (this.m_CredentialsHandle != null))
                {
                    this.m_CredentialsHandle.Close();
                }
            }
            if ((statusCode & ((SecurityStatus)(-2147483648))) != SecurityStatus.OK)
            {
                this.CloseContext();
                this.m_IsCompleted = true;
                if (throwOnError)
                {
                    Win32Exception exception = new Win32Exception((int)statusCode);
                    throw exception;
                }
                return(null);
            }
            if (flag && (this.m_CredentialsHandle != null))
            {
                SSPIHandleCache.CacheCredential(this.m_CredentialsHandle);
            }
            if (statusCode == SecurityStatus.OK)
            {
                this.m_IsCompleted = true;
            }
            return(outputBuffer.token);
        }
        //
        // NTAuth::GetOutgoingBlob()
        // Created:   12-01-1999: L.M.
        // Description:
        // Accepts an incoming binary security blob  and returns
        // an outgoing binary security blob
        //
        private byte[] GetOutgoingBlob(byte[] incomingBlob, out bool handshakeComplete)
        {
            GlobalLog.Enter("NTAuthentication::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString()) + " bytes");

            // default to true in case of failure
            handshakeComplete = true;

            if (m_SecurityContext.Handle != -1 && incomingBlob == null)
            {
                // we tried auth previously, now we got a null blob, we're done. this happens
                // with Kerberos & valid credentials on the domain but no ACLs on the resource
                // the handle for m_SecurityContext will be collected at GC time.
                GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() null blob AND m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:[0x" + m_SecurityContext.Handle.ToString("x8") + "]");
                m_SecurityContext.Close();
                IsCompleted = true;
                return(null);
            }

            int requestedFlags =
                (int)ContextFlags.Delegate |
                (int)ContextFlags.MutualAuth |
                (int)ContextFlags.ReplayDetect |
                (int)ContextFlags.SequenceDetect |
                (int)ContextFlags.Confidentiality |
                (int)ContextFlags.Connection;

            SecurityBufferClass inSecurityBuffer = null;

            if (incomingBlob != null)
            {
                GlobalLog.Print("in blob = ");
                GlobalLog.Dump(incomingBlob);
                inSecurityBuffer = new SecurityBufferClass(incomingBlob, BufferType.Token);
            }

            SecurityBufferClass outSecurityBuffer = new SecurityBufferClass(m_TokenSize, BufferType.Token);

            int status;

#if SERVER_SIDE_SSPI
            if (m_SecureSessionType == SecureSessionType.ClientSession)
            {
#endif
            //
            // client session
            //
            requestedFlags |= (int)ContextFlags.ClientIntegrity;

            status = SSPIWrapper.InitializeSecurityContext(
                GlobalSSPI.SSPIAuth,
                m_CredentialsHandle.Handle,
                m_SecurityContext.Handle,
                m_RemotePeerId,
                requestedFlags,
                m_Endianness,
                inSecurityBuffer,
                ref m_SecurityContext.Handle,
                outSecurityBuffer,
                ref m_ContextFlags,
                ref m_SecurityContext.TimeStamp
                );

            GlobalLog.Print("SSPIWrapper.InitializeSecurityContext() returns 0x" + string.Format("{0:x}", status));
#if SERVER_SIDE_SSPI
        }

        else
        {
            //
            // server session
            //
            requestedFlags |= (int)ContextFlags.ServerIntegrity;

            status = SSPIWrapper.AcceptSecurityContext(
                GlobalSSPI.SSPIAuth,
                m_CredentialsHandle.Handle,
                m_SecurityContext.Handle,
                requestedFlags,
                m_Endianness,
                inSecurityBuffer,
                ref m_SecurityContext.Handle,
                outSecurityBuffer,
                out m_ContextFlags,
                out m_SecurityContext.TimeStamp
                );

            GlobalLog.Print("SSPIWrapper.AcceptSecurityContext() returns 0x" + string.Format("{0:x}", status));
        }
#endif // SERVER_SIDE_SSPI

            int errorCode = status & unchecked ((int)0x80000000);
            if (errorCode != 0)
            {
                throw new Win32Exception(status);
            }

            //
            // the return value from SSPI will tell us correctly if the
            // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm
            // we also have to consider the case in which SSPI formed a new context, in this case we're done as well.
            //
            if (status != (int)SecurityStatus.OK && m_SecurityContext.Handle != -1)
            {
                // we need to continue
                GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() need continue status:[0x" + status.ToString("x8") + "] m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:[0x" + m_SecurityContext.Handle.ToString("x8") + "]");
                handshakeComplete = false;
            }
            else
            {
                // we're done, cleanup
                GlobalLog.Assert(status == (int)SecurityStatus.OK, "NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() status:[0x" + status.ToString("x8") + "] m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:[0x" + m_SecurityContext.Handle.ToString("x8") + "]", "[STATUS != OK]");
                m_SecurityContext.Close();
                IsCompleted = true;
            }

#if TRAVE
            if (handshakeComplete)
            {
                //
                // Kevin Damour says:
                // You should not query the securitycontext until you have actually formed one (
                // with a success return form ISC).  It is only a partially formed context and
                // no info is available to user applications (at least for digest).
                //
                SecurityPackageInfoClass securityPackageInfo = (SecurityPackageInfoClass)SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, m_SecurityContext, ContextAttribute.PackageInfo);
                GlobalLog.Print("SecurityPackageInfoClass: using:[" + ((securityPackageInfo == null)?"null":securityPackageInfo.ToString()) + "]");
            }
#endif // #if TRAVE

            GlobalLog.Print("out token = " + m_TokenSize.ToString());
            GlobalLog.Dump(outSecurityBuffer.token);

            GlobalLog.Leave("NTAuthentication::GetOutgoingBlob", "handshakeComplete:" + handshakeComplete.ToString());

            return(outSecurityBuffer.token);
        }