Example #1
0
        private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Enter(this, package, spn, requestedContextFlags);

            _tokenSize = NegotiateStreamPal.QueryMaxTokenSize(package);
            _isServer = isServer;
            _spn = spn;
            _securityContext = null;
            _requestedContextFlags = requestedContextFlags;
            _package = package;
            _channelBinding = channelBinding;

            if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Peer SPN-> '{_spn}'");

            //
            // Check if we're using DefaultCredentials.
            //

            Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials);
            if (credential == CredentialCache.DefaultCredentials)
            {
                if (NetEventSource.IsEnabled) NetEventSource.Info(this, "using DefaultCredentials");
                _credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(package, _isServer);
            }
            else
            {
                _credentialsHandle = NegotiateStreamPal.AcquireCredentialsHandle(package, _isServer, credential);
            }
        }
 public void AcceptSecurityContext(SafeFreeCredentials credential, SafeDeleteContext context, Interop.SspiCli.ContextFlags inFlags)
 {
     if (IsEnabled())
     {
         AcceptSecurityContext(IdOf(credential), IdOf(context), inFlags);
     }
 }
 public void InitializeSecurityContext(SafeFreeCredentials credential, SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags)
 {
     if (IsEnabled())
     {
         InitializeSecurityContext(IdOf(credential), IdOf(context), targetName, inFlags);
     }
 }
        public SecurityStatus InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer)
        {
            Interop.Secur32.ContextFlags outFlags = Interop.Secur32.ContextFlags.Zero;

            var retStatus = (SecurityStatus)SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, RequiredFlags | Interop.Secur32.ContextFlags.InitManualCredValidation, Interop.Secur32.Endianness.Native, inputBuffer, null, outputBuffer, ref outFlags);

            return MapToSecurityStatus((Interop.SecurityStatus)retStatus);
        }
Example #5
0
 internal static SecurityStatus AcceptSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
 {
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.Web,
             "AcceptSecurityContext(" +
             "credential = " + credential.ToString() + ", " +
             "context = " + Logging.ObjectToString(context) + ", " +
             "remoteCertRequired = " + remoteCertRequired);
     }
     return SecModule.AcceptSecurityContext(ref credential, ref context, inputBuffer, outputBuffer, remoteCertRequired);
 }
 public SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate,
     SslProtocols protocols, EncryptionPolicy policy, bool isServer)
 {
     SafeFreeCredentials retVal = new SafeFreeCredentials(certificate, protocols, policy);
     if (null != retVal)
     {
         // Caller does a ref count decrement
         bool ignore = false;
         retVal.DangerousAddRef(ref ignore);
         // TODO (Issue #3362) retVal is not getting released now, need to be fixed.
     }
     return retVal;
 }
Example #7
0
 public int AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
 {
     Interop.Secur32.ContextFlags outFlags = Interop.Secur32.ContextFlags.Zero;
     return SafeDeleteContext.AcceptSecurityContext(
                                 ref credential,
                                 ref context,
                                 ServerRequiredFlags | (remoteCertRequired ? Interop.Secur32.ContextFlags.MutualAuth : Interop.Secur32.ContextFlags.Zero),
                                 Interop.Secur32.Endianness.Native,
                                 inputBuffer,
                                 null,
                                 outputBuffer,
                                 ref outFlags
                                 );
 }
Example #8
0
        internal static SecurityStatus InitializeSecurityContext(SSPIInterface SecModule, SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer)
        {
            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web,
                    "InitializeSecurityContext(" +
                    "credential = " + credential.ToString() + ", " +
                    "context = " + Logging.ObjectToString(context) + ", " +
                    "targetName = " + targetName);
            }

            SecurityStatus errorCode = SecModule.InitializeSecurityContext(credential, ref context, targetName, inputBuffers, outputBuffer);
           
            return errorCode;
        }
        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 GetSecurityStatusPalFromWin32Int(errorCode);
        }
        public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer)
        {
            Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags);

            int errorCode = SSPIWrapper.InitializeSecurityContext(
                            GlobalSSPI.SSPISecureChannel,
                            credentialsHandle,
                            ref context,
                            targetName,
                            RequiredFlags | Interop.SspiCli.ContextFlags.InitManualCredValidation,
                            Interop.SspiCli.Endianness.Native,
                            inputBuffers,
                            outputBuffer,
                            ref unusedAttributes);

            return GetSecurityStatusPalFromWin32Int(errorCode);
        }
 internal static void CacheCredential(SafeFreeCredentials creds, byte[] thumbPrint, SchProtocols allowedProtocols, EncryptionPolicy encryptionPolicy)
 {
     if (!creds.IsInvalid)
     {
         object obj2 = new SslCredKey(thumbPrint, allowedProtocols, encryptionPolicy);
         SafeCredentialReference reference = s_CachedCreds[obj2] as SafeCredentialReference;
         if (((reference == null) || reference.IsClosed) || reference._Target.IsInvalid)
         {
             lock (s_CachedCreds)
             {
                 reference = s_CachedCreds[obj2] as SafeCredentialReference;
                 if ((reference == null) || reference.IsClosed)
                 {
                     reference = SafeCredentialReference.CreateReference(creds);
                     if (reference != null)
                     {
                         s_CachedCreds[obj2] = reference;
                         if ((s_CachedCreds.Count % 0x20) == 0)
                         {
                             DictionaryEntry[] array = new DictionaryEntry[s_CachedCreds.Count];
                             s_CachedCreds.CopyTo(array, 0);
                             for (int i = 0; i < array.Length; i++)
                             {
                                 reference = array[i].Value as SafeCredentialReference;
                                 if (reference != null)
                                 {
                                     creds = reference._Target;
                                     reference.Close();
                                     if ((!creds.IsClosed && !creds.IsInvalid) && ((reference = SafeCredentialReference.CreateReference(creds)) != null))
                                     {
                                         s_CachedCreds[array[i].Key] = reference;
                                     }
                                     else
                                     {
                                         s_CachedCreds.Remove(array[i].Key);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
 internal static void CacheCredential(SafeFreeCredentials newHandle)
 {
       try {
           SafeCredentialReference newRef = SafeCredentialReference.CreateReference(newHandle);
           if (newRef == null)
               return;
           unchecked
           {
               int index = Interlocked.Increment(ref _Current) & c_MaxCacheSize;
               newRef = Interlocked.Exchange<SafeCredentialReference>(ref _CacheSlots[index], newRef);
           }
           if (newRef != null)
               newRef.Close();
       }
       catch(Exception e) {
           if (!NclUtilities.IsFatal(e)){
               GlobalLog.Assert("SSPIHandlCache", "Attempted to throw: " + e.ToString());
           }
       }
 }
 internal static void CacheCredential(SafeFreeCredentials newHandle)
 {
     try
     {
         SafeCredentialReference reference = SafeCredentialReference.CreateReference(newHandle);
         if (reference != null)
         {
             int index = Interlocked.Increment(ref _Current) & 0x1f;
             reference = Interlocked.Exchange<SafeCredentialReference>(ref _CacheSlots[index], reference);
             if (reference != null)
             {
                 reference.Close();
             }
         }
     }
     catch (Exception exception)
     {
         NclUtilities.IsFatal(exception);
     }
 }
 WindowsSspiNegotiation(bool isServer, string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled)
 {
     this.tokenSize = SspiWrapper.GetVerifyPackageInfo(package).MaxToken;
     this.isServer = isServer;
     this.servicePrincipalName = servicePrincipalName;
     this.securityContext = null;
     if (isServer)
     {
         this.impersonationLevel = TokenImpersonationLevel.Delegation;
         this.doMutualAuth = false;
     }
     else
     {
         this.impersonationLevel = impersonationLevel;
         this.doMutualAuth = doMutualAuth;
         this.interactiveNegoLogonEnabled = interactiveLogonEnabled;
         this.clientPackageName = package;
         this.allowNtlm = ntlmEnabled;
     }
     this.credentialsHandle = credentialsHandle;
 }
 WindowsSspiNegotiation(bool isServer, string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled)
 {
     this.tokenSize            = SspiWrapper.GetVerifyPackageInfo(package).MaxToken;
     this.isServer             = isServer;
     this.servicePrincipalName = servicePrincipalName;
     this.securityContext      = null;
     if (isServer)
     {
         this.impersonationLevel = TokenImpersonationLevel.Delegation;
         this.doMutualAuth       = false;
     }
     else
     {
         this.impersonationLevel          = impersonationLevel;
         this.doMutualAuth                = doMutualAuth;
         this.interactiveNegoLogonEnabled = interactiveLogonEnabled;
         this.clientPackageName           = package;
         this.allowNtlm = ntlmEnabled;
     }
     this.credentialsHandle = credentialsHandle;
 }
Example #16
0
        internal static SecurityStatus InitializeSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer)
        {
            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web,
                    "InitializeSecurityContext(" +
                    "credential = " + credential.ToString() + ", " +
                    "context = " + Logging.ObjectToString(context) + ", " +
                    "targetName = " + targetName);
            }


            SecurityStatus errorCode = SecModule.InitializeSecurityContext(ref credential, ref context, targetName, inputBuffer, outputBuffer);

            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_security_context_input_buffer, "InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (SecurityStatus)errorCode));
            }

            return errorCode;
        }
Example #17
0
        private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context,
            SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired)
        {
            Debug.Assert(!credential.IsInvalid);

            try
            {
                if ((null == context) || context.IsInvalid)
                {
                    context = new SafeDeleteContext(credential, isServer, remoteCertRequired);
                }

                byte[] output = null;
                int outputSize;
                bool done;

                if (null == inputBuffer)
                {
                    done = Interop.OpenSsl.DoSslHandshake(context.SslContext, null, 0, 0, out output, out outputSize);
                }
                else
                {
                    done = Interop.OpenSsl.DoSslHandshake(context.SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, out output, out outputSize);
                }

                outputBuffer.size = outputSize;
                outputBuffer.offset = 0;
                outputBuffer.token = outputSize > 0 ? output : null;

                return done ? SecurityStatusPal.OK : SecurityStatusPal.ContinueNeeded;
            }
            catch
            {
                // TODO: This Debug.Fail is triggering on Linux in many test cases #4317
                // Debug.Fail("Exception Caught. - " + ex);
                return SecurityStatusPal.InternalError;             
            }
        }
Example #18
0
 public int AcquireDefaultCredential(string moduleName, Interop.SspiCli.CredentialUse usage, out SafeFreeCredentials outCredential)
 {
     return SafeFreeCredentials.AcquireDefaultCredential(moduleName, usage, out outCredential);
 }
Example #19
0
 public SecuritySessionSecurityTokenProvider(SafeFreeCredentials credentialsHandle)
 {
     this.credentialsHandle = credentialsHandle;
     this.standardsManager  = SecurityStandardsManager.DefaultInstance;
     this.keyEntropyMode    = SecurityKeyEntropyMode.CombinedEntropy;
 }
Example #20
0
 public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context,
     string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer)
 {        
     return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, false, false);
 }
Example #21
0
        internal static int InitializeSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags)
        {
            if (SecurityEventSource.Log.IsEnabled())
            {
                SecurityEventSource.Log.InitializeSecurityContext(credential.ToString(),
                    LoggingHash.ObjectToString(context),
                    targetName,
                    inFlags);
            }

            int errorCode = secModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffer, outputBuffer, ref outFlags);

            if (SecurityEventSource.Log.IsEnabled())
            {
                SecurityEventSource.Log.SecurityContextInputBuffer("InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SecurityStatus)errorCode);
            }

            return errorCode;
        }
Example #22
0
        /// <summary>
        /// Generate SSPI context
        /// </summary>
        /// <param name="sspiClientContextStatus">SSPI client context status</param>
        /// <param name="receivedBuff">Receive buffer</param>
        /// <param name="sendBuff">Send buffer</param>
        /// <param name="serverName">Service Principal Name buffer</param>
        public void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[] serverName)
        {
            SafeDeleteContext   securityContext   = sspiClientContextStatus.SecurityContext;
            ContextFlagsPal     contextFlags      = sspiClientContextStatus.ContextFlags;
            SafeFreeCredentials credentialsHandle = sspiClientContextStatus.CredentialsHandle;

            string securityPackage = NegotiationInfoClass.Negotiate;

            if (securityContext == null)
            {
                credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(securityPackage, false);
            }

            int tokenSize = NegotiateStreamPal.QueryMaxTokenSize(securityPackage);

            byte[] resultToken = new byte[tokenSize];

            ContextFlagsPal requestedContextFlags = ContextFlagsPal.Connection
                                                    | ContextFlagsPal.Confidentiality
                                                    | ContextFlagsPal.Delegate
                                                    | ContextFlagsPal.MutualAuth;

            string serverSPN = System.Text.Encoding.UTF8.GetString(serverName);

            SecurityStatusPal statusCode = NegotiateStreamPal.InitializeSecurityContext(
                ref credentialsHandle,
                ref securityContext,
                serverSPN,
                requestedContextFlags,
                receivedBuff,
                null,
                ref resultToken,
                ref contextFlags);

            if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded ||
                statusCode.ErrorCode == SecurityStatusPalErrorCode.CompAndContinue)
            {
                statusCode  = NegotiateStreamPal.CompleteAuthToken(ref securityContext, resultToken);
                resultToken = null;
            }

            sendBuff = resultToken;
            if (sendBuff == null)
            {
                sendBuff = Array.Empty <byte>();
            }

            sspiClientContextStatus.SecurityContext   = securityContext;
            sspiClientContextStatus.ContextFlags      = contextFlags;
            sspiClientContextStatus.CredentialsHandle = credentialsHandle;

            if (IsErrorStatus(statusCode.ErrorCode))
            {
                // Could not access Kerberos Ticket.
                //
                // SecurityStatusPalErrorCode.InternalError only occurs in Unix and always comes with a GssApiException,
                // so we don't need to check for a GssApiException here.
                if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError)
                {
                    throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode);
                }
                else
                {
                    throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + "\n" + statusCode);
                }
            }
        }
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            ThrowIfDisposed();
            int statusCode = 0;

            // use the confidentiality option to ensure we can encrypt messages
            SspiContextFlags requestedFlags = SspiContextFlags.Confidentiality
                                              | SspiContextFlags.ReplayDetect
                                              | SspiContextFlags.SequenceDetect;

            if (this.doMutualAuth)
            {
                requestedFlags |= SspiContextFlags.MutualAuth;
            }

            if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
            {
                requestedFlags |= SspiContextFlags.Delegate;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Identification)
            {
                requestedFlags |= SspiContextFlags.InitIdentify;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Anonymous)
            {
                requestedFlags |= SspiContextFlags.InitAnonymous;
            }

            ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);

            if (isServer)
            {
                if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing)));
                }

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }

                if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                }
            }

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

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

            // when deciding if the channel binding should be added to the security buffer
            // it is necessary to differentiate between  client and server.
            // Server rules were added to policyHelper as they are shared with Kerb and I want them consistent
            // Client adds if not null.
            if (this.isServer)
            {
                if (policyHelper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }
            else
            {
                if (policyHelper.ChannelBinding != null)
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }

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

            SecurityBuffer outSecurityBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);

            if (!this.isServer)
            {
                //client session
                statusCode = SspiWrapper.InitializeSecurityContext(this.credentialsHandle,
                                                                   ref this.securityContext,
                                                                   this.servicePrincipalName,
                                                                   requestedFlags,
                                                                   Endianness.Network,
                                                                   inSecurityBuffer,
                                                                   outSecurityBuffer,
                                                                   ref this.contextFlags);
            }
            else
            {
                // server session
                //This check is to save an unnecessary ASC call.
                bool             isServerSecurityContextNull = this.securityContext == null;
                SspiContextFlags serverContextFlags          = this.contextFlags;

                statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                               ref this.securityContext,
                                                               requestedFlags,
                                                               Endianness.Network,
                                                               inSecurityBuffer,
                                                               outSecurityBuffer,
                                                               ref this.contextFlags);

                if (statusCode == (int)SecurityStatus.InvalidToken && !isServerSecurityContextNull)
                {
                    // Call again into ASC after deleting the Securitycontext. If this securitycontext is not deleted
                    // then when the client sends NTLM blob the service will treat it as Nego2blob and will fail to authenticate the client.
                    this.contextFlags = serverContextFlags;
                    CloseContext();
                    statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                                   ref this.securityContext,
                                                                   requestedFlags,
                                                                   Endianness.Network,
                                                                   inSecurityBuffer,
                                                                   outSecurityBuffer,
                                                                   ref this.contextFlags);
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                IMD.SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, this.isServer, channelbinding);
            }

            if ((statusCode & unchecked ((int)0x80000000)) != 0)
            {
                if (!this.isServer &&
                    this.interactiveNegoLogonEnabled &&
                    SecurityUtils.IsOSGreaterThanOrEqualToWin7() &&
                    SspiWrapper.IsSspiPromptingNeeded((uint)statusCode) &&
                    SspiWrapper.IsNegotiateExPackagePresent())
                {
                    // If we have prompted enough number of times (DefaultMaxPromptAttempts) with wrong credentials, then we do not prompt again and throw.
                    if (MaxPromptAttempts >= DefaultMaxPromptAttempts)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidClientCredentials)));
                    }

                    IntPtr ppAuthIdentity = IntPtr.Zero;
                    uint   errorCode      = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out ppAuthIdentity, ref this.saveClientCredentialsOnSspiUi);
                    if (errorCode == (uint)CredentialStatus.Success)
                    {
                        IntPtr ppNewAuthIdentity = IntPtr.Zero;

                        if (!this.allowNtlm)
                        {
                            // When Ntlm is  explicitly disabled we don't want the collected
                            //creds from the Kerb/NTLM tile to be used for NTLM auth.

                            uint status = UnsafeNativeMethods.SspiExcludePackage(ppAuthIdentity, "NTLM", out ppNewAuthIdentity);
                        }
                        else
                        {
                            ppNewAuthIdentity = ppAuthIdentity;
                        }

                        this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);

                        if (IntPtr.Zero != ppNewAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                        }

                        CloseContext();

                        MaxPromptAttempts++;
                        return(this.GetOutgoingBlob(null, channelbinding, protectionPolicy));
                    }
                    else
                    {
                        // Call into SspiPromptForCredential had an error. Time to throw.
                        if (IntPtr.Zero != ppAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppAuthIdentity);
                        }

                        CloseContext();
                        this.isCompleted = true;
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)errorCode, SR.GetString(SR.SspiErrorOrInvalidClientCredentials)));
                    }
                }

                CloseContext();
                this.isCompleted = true;
                if (!this.isServer && (statusCode == (int)SecurityStatus.TargetUnknown ||
                                       statusCode == (int)SecurityStatus.WrongPrincipal))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.IncorrectSpnOrUpnSpecified, this.servicePrincipalName)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidSspiNegotiation)));
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                if (this.isServer)
                {
                    SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
                }
                else
                {
                    SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
                }
            }

            if (statusCode == (int)SecurityStatus.OK)
            {
                // we're done
                this.isCompleted = true;

                // These must all be true to check service binding
                // 1. we are the service (listener)
                // 2. caller is not anonymous
                // 3. protocol is not Kerberos
                // 4. policy is set to check service binding
                //
                if (isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == 0) && (string.Compare(this.ProtocolName, NegotiationInfoClass.Kerberos, StringComparison.OrdinalIgnoreCase) != 0) && policyHelper.ShouldCheckServiceBinding)
                {
                    // in the server case the servicePrincipalName is the defaultServiceBinding

                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        string serviceBindingNameSentByClient;
                        SspiWrapper.QuerySpecifiedTarget(securityContext, out serviceBindingNameSentByClient);
                        IMD.SecurityTraceRecordHelper.TraceServiceNameBindingOnServer(serviceBindingNameSentByClient, this.servicePrincipalName, policyHelper.ServiceNameCollection);
                    }

                    policyHelper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
                }
            }
            else
            {
                // we need to continue
            }

            return(outSecurityBuffer.token);
        }
Example #24
0
        internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
        {
            if (!this.isAuthenticated)
            {
                bool flag = false;
                SafeDeleteContext refContext = null;
                SafeCloseHandle   token      = null;
                byte[]            request    = this.request;
                try
                {
                    if (credentialsHandle == null)
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound, new string[0]);
                        flag = true;
                    }
                    SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
                    ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy);
                    if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SecurityChannelBindingMissing")));
                    }
                    if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                    {
                        inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                    }
                    if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                    {
                        inFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                    }
                    SspiContextFlags      zero         = SspiContextFlags.Zero;
                    SecurityBuffer        outputBuffer = new SecurityBuffer(0, BufferType.Token);
                    List <SecurityBuffer> list         = new List <SecurityBuffer>(2)
                    {
                        new SecurityBuffer(request, 2)
                    };
                    if (helper.ShouldAddChannelBindingToASC())
                    {
                        list.Add(new SecurityBuffer(helper.ChannelBinding));
                    }
                    SecurityBuffer[] inputBuffers = null;
                    if (list.Count > 0)
                    {
                        inputBuffers = list.ToArray();
                    }
                    int error = SspiWrapper.AcceptSecurityContext(credentialsHandle, ref refContext, inFlags, Endianness.Native, inputBuffers, outputBuffer, ref zero);
                    switch (error)
                    {
                    case 0:
                        break;

                    case 0x90312:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error)));

                    case -2146893056:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosApReqInvalidOrOutOfMemory"), new Win32Exception(error)));

                    default:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailAcceptSecurityContext"), new Win32Exception(error)));
                    }
                    LifeSpan span                  = (LifeSpan)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.Lifespan);
                    DateTime effectiveTimeUtc      = span.EffectiveTimeUtc;
                    DateTime expiryTimeUtc         = span.ExpiryTimeUtc;
                    SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.SessionKey);
                    this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey);
                    error = SspiWrapper.QuerySecurityContextToken(refContext, out token);
                    if (error != 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                    }
                    System.Security.Principal.WindowsIdentity windowsIdentity = new System.Security.Principal.WindowsIdentity(token.DangerousGetHandle(), "Kerberos");
                    base.Initialize(this.id, "Kerberos", effectiveTimeUtc, expiryTimeUtc, windowsIdentity, false);
                    this.isAuthenticated = true;
                }
                finally
                {
                    if (token != null)
                    {
                        token.Close();
                    }
                    if (refContext != null)
                    {
                        refContext.Close();
                    }
                    if (flag && (credentialsHandle != null))
                    {
                        credentialsHandle.Close();
                    }
                }
            }
        }
        private void AcquireClientCredentials()
        {
            SecureCredential scc = new SecureCredential(4, this.ClientCertificate, SecureCredential.Flags.NoDefaultCred | SecureCredential.Flags.ValidateManual, this.protocolFlags);

            this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Microsoft Unified Security Protocol Provider", CredentialUse.Outbound, scc);
        }
Example #26
0
        /// <summary>
        /// Generate SSPI context
        /// </summary>
        /// <param name="sspiClientContextStatus">SSPI client context status</param>
        /// <param name="receivedBuff">Receive buffer</param>
        /// <param name="sendBuff">Send buffer</param>
        /// <param name="serverName">Service Principal Name buffer</param>
        /// <returns>SNI error code</returns>
        internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName)
        {
            SafeDeleteContext   securityContext   = sspiClientContextStatus.SecurityContext;
            ContextFlagsPal     contextFlags      = sspiClientContextStatus.ContextFlags;
            SafeFreeCredentials credentialsHandle = sspiClientContextStatus.CredentialsHandle;

            string securityPackage = NegotiationInfoClass.Negotiate;

            if (securityContext == null)
            {
                credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(securityPackage, false);
            }

            SecurityBuffer[] inSecurityBufferArray;
            if (receivedBuff != null)
            {
                inSecurityBufferArray = new SecurityBuffer[] { new SecurityBuffer(receivedBuff, SecurityBufferType.SECBUFFER_TOKEN) };
            }
            else
            {
                inSecurityBufferArray = Array.Empty <SecurityBuffer>();
            }

            int tokenSize = NegotiateStreamPal.QueryMaxTokenSize(securityPackage);

            SecurityBuffer outSecurityBuffer = new SecurityBuffer(tokenSize, SecurityBufferType.SECBUFFER_TOKEN);

            ContextFlagsPal requestedContextFlags = ContextFlagsPal.Connection
                                                    | ContextFlagsPal.Confidentiality
                                                    | ContextFlagsPal.Delegate
                                                    | ContextFlagsPal.MutualAuth;

            string[] serverSPNs = new string[serverName.Length];
            for (int i = 0; i < serverName.Length; i++)
            {
                serverSPNs[i] = Encoding.UTF8.GetString(serverName[i]);
            }
            SecurityStatusPal statusCode = NegotiateStreamPal.InitializeSecurityContext(
                credentialsHandle,
                ref securityContext,
                serverSPNs,
                requestedContextFlags,
                inSecurityBufferArray,
                outSecurityBuffer,
                ref contextFlags);

            if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded ||
                statusCode.ErrorCode == SecurityStatusPalErrorCode.CompAndContinue)
            {
                inSecurityBufferArray   = new SecurityBuffer[] { outSecurityBuffer };
                statusCode              = NegotiateStreamPal.CompleteAuthToken(ref securityContext, inSecurityBufferArray);
                outSecurityBuffer.token = null;
            }

            sendBuff = outSecurityBuffer.token;
            if (sendBuff == null)
            {
                sendBuff = Array.Empty <byte>();
            }

            sspiClientContextStatus.SecurityContext   = securityContext;
            sspiClientContextStatus.ContextFlags      = contextFlags;
            sspiClientContextStatus.CredentialsHandle = credentialsHandle;

            if (IsErrorStatus(statusCode.ErrorCode))
            {
                // Could not access Kerberos Ticket.
                //
                // SecurityStatusPalErrorCode.InternalError only occurs in Unix and always comes with a GssApiException,
                // so we don't need to check for a GssApiException here.
                if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError)
                {
                    throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode);
                }
                else
                {
                    throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + "\n" + statusCode);
                }
            }
        }
Example #27
0
 public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
 {
     return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags);
 }
Example #28
0
 internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled) : this(false, package, credentialsHandle, impersonationLevel, servicePrincipalName, doMutualAuth, interactiveLogonEnabled, ntlmEnabled)
 {
 }
Example #29
0
 internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, string defaultServiceBinding) : this(true, package, credentialsHandle, TokenImpersonationLevel.Delegation, defaultServiceBinding, false, false, true)
 {
 }
Example #30
0
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            this.ThrowIfDisposed();
            int error = 0;
            SspiContextFlags inFlags = SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;

            if (this.doMutualAuth)
            {
                inFlags |= SspiContextFlags.MutualAuth;
            }
            if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
            {
                inFlags |= SspiContextFlags.Delegate;
            }
            else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Identification))
            {
                inFlags |= SspiContextFlags.InitIdentify;
            }
            else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Anonymous))
            {
                inFlags |= SspiContextFlags.InitAnonymous;
            }
            ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);

            if (this.isServer)
            {
                if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy))
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.ServiceModel.SR.GetString("SecurityChannelBindingMissing")));
                }
                if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }
                if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    inFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                }
            }
            List <SecurityBuffer> list = new List <SecurityBuffer>(2);

            if (incomingBlob != null)
            {
                list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
            }
            if (this.isServer)
            {
                if (helper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(helper.ChannelBinding));
                }
            }
            else if (helper.ChannelBinding != null)
            {
                list.Add(new SecurityBuffer(helper.ChannelBinding));
            }
            SecurityBuffer[] inputBuffers = null;
            if (list.Count > 0)
            {
                inputBuffers = list.ToArray();
            }
            SecurityBuffer outputBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);

            if (!this.isServer)
            {
                error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
            }
            else
            {
                bool             flag         = this.securityContext == null;
                SspiContextFlags contextFlags = this.contextFlags;
                error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
                if ((error == -2146893048) && !flag)
                {
                    this.contextFlags = contextFlags;
                    this.CloseContext();
                    error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
                }
            }
            if ((error & -2147483648) != 0)
            {
                if (((!this.isServer && this.interactiveNegoLogonEnabled) && (System.ServiceModel.Security.SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint)error))) && SspiWrapper.IsNegotiateExPackagePresent())
                {
                    if (this.MaxPromptAttempts >= 1)
                    {
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidClientCredentials")));
                    }
                    IntPtr zero = IntPtr.Zero;
                    uint   num2 = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out zero, ref this.saveClientCredentialsOnSspiUi);
                    if (num2 == 0)
                    {
                        IntPtr ppNewAuthIdentity = IntPtr.Zero;
                        if (!this.allowNtlm)
                        {
                            UnsafeNativeMethods.SspiExcludePackage(zero, "NTLM", out ppNewAuthIdentity);
                        }
                        else
                        {
                            ppNewAuthIdentity = zero;
                        }
                        this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);
                        if (IntPtr.Zero != ppNewAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                        }
                        this.CloseContext();
                        this.MaxPromptAttempts++;
                        return(this.GetOutgoingBlob(null, channelbinding, protectionPolicy));
                    }
                    if (IntPtr.Zero != zero)
                    {
                        UnsafeNativeMethods.SspiFreeAuthIdentity(zero);
                    }
                    this.CloseContext();
                    this.isCompleted = true;
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)num2, System.ServiceModel.SR.GetString("SspiErrorOrInvalidClientCredentials")));
                }
                this.CloseContext();
                this.isCompleted = true;
                if (this.isServer || (((error != -2146893042) && (error != -2146893053)) && (error != -2146893022)))
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidSspiNegotiation")));
                }
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("IncorrectSpnOrUpnSpecified", new object[] { this.servicePrincipalName })));
            }
            if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
            {
                if (this.isServer)
                {
                    SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
                }
                else
                {
                    SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
                }
            }
            if (error == 0)
            {
                this.isCompleted = true;
                if ((this.isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == SspiContextFlags.Zero)) && ((string.Compare(this.ProtocolName, "Kerberos", StringComparison.OrdinalIgnoreCase) != 0) && helper.ShouldCheckServiceBinding))
                {
                    helper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
                }
            }
            return(outputBuffer.token);
        }
 /// <summary>
 /// Client side ctor
 /// </summary>
 internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled)
     : this(false, package, credentialsHandle, impersonationLevel, servicePrincipalName, doMutualAuth, interactiveLogonEnabled, ntlmEnabled)
 { }
Example #32
0
 public AcceleratedTokenProvider(SafeFreeCredentials credentialsHandle)
 {
     this.credentialsHandle = credentialsHandle;
 }
 /// <summary>
 /// Server side ctor
 /// </summary>
 internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, string defaultServiceBinding)
     : this(true, package, credentialsHandle, TokenImpersonationLevel.Delegation, defaultServiceBinding, false, false, true)
 { }
        void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            bool ownCredentialsHandle         = false;
            SafeDeleteContext securityContext = null;

            try
            {
                if (credentialsHandle == null)
                {
                    if (networkCredential == null || networkCredential == CredentialCache.DefaultNetworkCredentials)
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Outbound);
                    }
                    else
                    {
                        AuthIdentityEx authIdentity = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain);
                        credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", CredentialUse.Outbound, ref authIdentity);
                    }
                    ownCredentialsHandle = true;
                }

                SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory
                                               | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.ReplayDetect
                                               | SspiContextFlags.SequenceDetect;


                // we only accept Identity or Impersonation (Impersonation is default).
                if (tokenImpersonationLevel == TokenImpersonationLevel.Identification)
                {
                    fContextReq |= SspiContextFlags.InitIdentify;
                }

                SspiContextFlags contextFlags     = SspiContextFlags.Zero;
                SecurityBuffer   inSecurityBuffer = null;
                if (channelBinding != null)
                {
                    inSecurityBuffer = new SecurityBuffer(channelBinding);
                }
                SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token);

                int statusCode = SspiWrapper.InitializeSecurityContext(
                    credentialsHandle,
                    ref securityContext,
                    this.servicePrincipalName,
                    fContextReq,
                    Endianness.Native,
                    inSecurityBuffer,
                    outSecurityBuffer,
                    ref contextFlags);

                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    SecurityTraceRecordHelper.TraceChannelBindingInformation(null, false, channelBinding);
                }

                if (statusCode != (int)SecurityStatus.OK)
                {
                    if (statusCode == (int)SecurityStatus.ContinueNeeded)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode)));
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.FailInitializeSecurityContext), new Win32Exception(statusCode)));
                    }
                }

#if REMOVEGSS
                //
                // ... and strip GSS-framing from it
                //
                int offset = 0;
                int len    = outSecurityBuffer.token.Length;
                DEREncoding.VerifyTokenHeader(outSecurityBuffer.token, ref offset, ref len);
                this.apreq = SecurityUtils.CloneBuffer(outSecurityBuffer.token, offset, len);
#else
                this.apreq = outSecurityBuffer.token;
#endif

                // Expiration
                LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan);
                this.effectiveTime  = lifeSpan.EffectiveTimeUtc;
                this.expirationTime = lifeSpan.ExpiryTimeUtc;

                // SessionKey
                SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey);
            }
            finally
            {
                if (securityContext != null)
                {
                    securityContext.Close();
                }

                if (ownCredentialsHandle && credentialsHandle != null)
                {
                    credentialsHandle.Close();
                }
            }
        }
        private void AcquireServerCredentials()
        {
            SecureCredential scc = new SecureCredential(4, this.serverCertificate, SecureCredential.Flags.Zero, this.protocolFlags);

            this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Microsoft Unified Security Protocol Provider", CredentialUse.Inbound, scc);
        }
        internal KerberosRequestorSecurityToken(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, string id, SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            if (servicePrincipalName == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("servicePrincipalName");
            }
            if (tokenImpersonationLevel != TokenImpersonationLevel.Identification && tokenImpersonationLevel != TokenImpersonationLevel.Impersonation)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("tokenImpersonationLevel",
                                                                                                          SR.GetString(SR.ImpersonationLevelNotSupported, tokenImpersonationLevel)));
            }
            if (id == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("id");
            }

            this.servicePrincipalName = servicePrincipalName;
            if (networkCredential != null && networkCredential != CredentialCache.DefaultNetworkCredentials)
            {
                if (string.IsNullOrEmpty(networkCredential.UserName))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.ProvidedNetworkCredentialsForKerberosHasInvalidUserName));
                }
                // Note: we don't check the domain, since Lsa accepts
                // FQ userName.
            }
            this.id = id;
            try
            {
                Initialize(tokenImpersonationLevel, networkCredential, credentialsHandle, channelBinding);
            }
            catch (Win32Exception e)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.UnableToCreateKerberosCredentials), e));
            }
            catch (SecurityTokenException ste)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.UnableToCreateKerberosCredentials), ste));
            }
        }
        // This internal API is not thread-safe.  It is acceptable since ..
        // 1) From public OM, Initialize happens at ctor time.
        // 2) From internal OM (Sfx), Initialize happens right after ctor (single thread env).
        //    i.e. ReadToken and then AuthenticateToken.
        internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
        {
            if (this.isAuthenticated)
            {
                return;
            }
            bool ownCredentialsHandle         = false;
            SafeDeleteContext securityContext = null;
            SafeCloseHandle   tokenHandle     = null;

#if RECOMPUTEGSS
            int    tokenSize  = DEREncoding.TokenSize(this.request.Length);
            byte[] rawRequest = new byte[tokenSize];
            int    offset     = 0;
            int    len        = this.request.Length;
            DEREncoding.MakeTokenHeader(this.request.Length, rawRequest, ref offset, ref len);
            System.Buffer.BlockCopy(this.request, 0, rawRequest, offset, this.request.Length);
#else
            byte[] rawRequest = this.request;
#endif

            try
            {
                if (credentialsHandle == null)
                {
                    credentialsHandle    = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound);
                    ownCredentialsHandle = true;
                }

                SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.ReplayDetect
                                               | SspiContextFlags.SequenceDetect;

                ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy);

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing)));
                }

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    fContextReq |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }

                if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    fContextReq |= SspiContextFlags.ChannelBindingProxyBindings;
                }

                SspiContextFlags contextFlags      = SspiContextFlags.Zero;
                SecurityBuffer   outSecurityBuffer = new SecurityBuffer(0, BufferType.Token);

                List <SecurityBuffer> list = new List <SecurityBuffer>(2);
                list.Add(new SecurityBuffer(rawRequest, BufferType.Token));

                if (policyHelper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }

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

                int statusCode = SspiWrapper.AcceptSecurityContext(credentialsHandle,
                                                                   ref securityContext,
                                                                   fContextReq,
                                                                   Endianness.Native,
                                                                   inSecurityBuffer,
                                                                   outSecurityBuffer,
                                                                   ref contextFlags);


                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, true, channelBinding);
                }

                if (statusCode != (int)SecurityStatus.OK)
                {
                    if (statusCode == (int)SecurityStatus.ContinueNeeded)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode)));
                    }
                    else if (statusCode == (int)SecurityStatus.OutOfMemory)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosApReqInvalidOrOutOfMemory), new Win32Exception(statusCode)));
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.FailAcceptSecurityContext), new Win32Exception(statusCode)));
                    }
                }

                // Expiration
                LifeSpan lifeSpan       = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan);
                DateTime effectiveTime  = lifeSpan.EffectiveTimeUtc;
                DateTime expirationTime = lifeSpan.ExpiryTimeUtc;

                // SessionKey
                SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey);

                // WindowsSecurityToken
                statusCode = SspiWrapper.QuerySecurityContextToken(securityContext, out tokenHandle);
                if (statusCode != (int)SecurityStatus.OK)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
                }

                WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeKerberos);
                Initialize(this.id, SecurityUtils.AuthTypeKerberos, effectiveTime, expirationTime, windowsIdentity, false);

                // Authenticated
                this.isAuthenticated = true;
            }
            finally
            {
                if (tokenHandle != null)
                {
                    tokenHandle.Close();
                }

                if (securityContext != null)
                {
                    securityContext.Close();
                }

                if (ownCredentialsHandle && credentialsHandle != null)
                {
                    credentialsHandle.Close();
                }
            }
        }
 public SspiIssuanceChannelParameter(bool getTokenOnOpen, SafeFreeCredentials credentialsHandle)
 {
     this.getTokenOnOpen    = getTokenOnOpen;
     this.credentialsHandle = credentialsHandle;
 }
Example #39
0
 public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context,
     SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
 {
     return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, true, remoteCertRequired);
 }
Example #40
0
        internal static int InitializeSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Log.InitializeSecurityContext(credential, context, targetName, inFlags);

            int errorCode = secModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffer, outputBuffer, ref outFlags);

            if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffer(nameof(InitializeSecurityContext), inputBuffer?.size ?? 0, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode);
            
            return errorCode;
        }
Example #41
0
 public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer)
 {          
     Debug.Assert(inputBuffers.Length == 2);
     Debug.Assert(inputBuffers[1].token == null);
     return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, false, false);
 }
Example #42
0
        internal static int AcceptSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Log.AcceptSecurityContext(credential, context, inFlags);

            int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags);

            if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffers(nameof(AcceptSecurityContext), inputBuffers?.Length ?? 0, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode);

            return errorCode;
        }
Example #43
0
        internal static int AcceptSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags)
        {
            if (SecurityEventSource.Log.IsEnabled())
            {
                SecurityEventSource.Log.AcceptSecurityContext(credential.ToString(), LoggingHash.ObjectToString(context), inFlags);
            }

            int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags);

            if (SecurityEventSource.Log.IsEnabled())
            {
                SecurityEventSource.Log.SecurityContextInputBuffers("AcceptSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SecurityStatus)errorCode);
            }

            return errorCode;
        }
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            ThrowIfDisposed();
            int statusCode = 0;

            // use the confidentiality option to ensure we can encrypt messages
            SspiContextFlags requestedFlags = SspiContextFlags.Confidentiality
                                            | SspiContextFlags.ReplayDetect
                                            | SspiContextFlags.SequenceDetect;

            if (this.doMutualAuth)
            {
                requestedFlags |= SspiContextFlags.MutualAuth;
            }

            if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
            {
                requestedFlags |= SspiContextFlags.Delegate;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Identification)
            {
                requestedFlags |= SspiContextFlags.InitIdentify;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Anonymous)
            {
                requestedFlags |= SspiContextFlags.InitAnonymous;
            }

            ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);

            if (isServer)
            {
                if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing)));
                }

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }

                if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                }
            }

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

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

            // when deciding if the channel binding should be added to the security buffer
            // it is necessary to differentiate between  client and server.
            // Server rules were added to policyHelper as they are shared with Kerb and I want them consistent
            // Client adds if not null.
            if (this.isServer)
            {
                if (policyHelper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }
            else
            {
                if (policyHelper.ChannelBinding != null)
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }

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

            SecurityBuffer outSecurityBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);

            if (!this.isServer)
            {
                //client session
                statusCode = SspiWrapper.InitializeSecurityContext(this.credentialsHandle,
                                                                    ref this.securityContext,
                                                                    this.servicePrincipalName,
                                                                    requestedFlags,
                                                                    Endianness.Network,
                                                                    inSecurityBuffer,
                                                                    outSecurityBuffer,
                                                                    ref this.contextFlags);
            }
            else
            {
                // server session
                //This check is to save an unnecessary ASC call.
                bool isServerSecurityContextNull = this.securityContext == null;
                SspiContextFlags serverContextFlags = this.contextFlags;

                statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                                ref this.securityContext,
                                                                requestedFlags,
                                                                Endianness.Network,
                                                                inSecurityBuffer,
                                                                outSecurityBuffer,
                                                                ref this.contextFlags);

                if (statusCode == (int)SecurityStatus.InvalidToken && !isServerSecurityContextNull)
                {
                    // Call again into ASC after deleting the Securitycontext. If this securitycontext is not deleted 
                    // then when the client sends NTLM blob the service will treat it as Nego2blob and will fail to authenticate the client.
                    this.contextFlags = serverContextFlags;
                    CloseContext();
                    statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                                    ref this.securityContext,
                                                                    requestedFlags,
                                                                    Endianness.Network,
                                                                    inSecurityBuffer,
                                                                    outSecurityBuffer,
                                                                    ref this.contextFlags);
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                IMD.SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, this.isServer, channelbinding);
            }

            if ((statusCode & unchecked((int)0x80000000)) != 0)
            {
                if (!this.isServer
                    && this.interactiveNegoLogonEnabled
                    && SecurityUtils.IsOSGreaterThanOrEqualToWin7()
                    && SspiWrapper.IsSspiPromptingNeeded((uint)statusCode)
                    && SspiWrapper.IsNegotiateExPackagePresent())
                {
                    // If we have prompted enough number of times (DefaultMaxPromptAttempts) with wrong credentials, then we do not prompt again and throw. 
                    if (MaxPromptAttempts >= DefaultMaxPromptAttempts)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidClientCredentials)));
                    }

                    IntPtr ppAuthIdentity = IntPtr.Zero;
                    uint errorCode = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out ppAuthIdentity, ref this.saveClientCredentialsOnSspiUi);
                    if (errorCode == (uint)CredentialStatus.Success)
                    {
                        IntPtr ppNewAuthIdentity = IntPtr.Zero;

                        if (!this.allowNtlm)
                        {
                            // When Ntlm is  explicitly disabled we don't want the collected 
                            //creds from the Kerb/NTLM tile to be used for NTLM auth.

                            uint status = UnsafeNativeMethods.SspiExcludePackage(ppAuthIdentity, "NTLM", out ppNewAuthIdentity);
                        }
                        else
                        {
                            ppNewAuthIdentity = ppAuthIdentity;
                        }

                        this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);

                        if (IntPtr.Zero != ppNewAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                        }

                        CloseContext();

                        MaxPromptAttempts++;
                        return this.GetOutgoingBlob(null, channelbinding, protectionPolicy);
                    }
                    else
                    {
                        // Call into SspiPromptForCredential had an error. Time to throw.
                        if (IntPtr.Zero != ppAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppAuthIdentity);
                        }

                        CloseContext();
                        this.isCompleted = true;
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)errorCode, SR.GetString(SR.SspiErrorOrInvalidClientCredentials)));
                    }
                }

                CloseContext();
                this.isCompleted = true;
                if (!this.isServer && (statusCode == (int)SecurityStatus.TargetUnknown
                    || statusCode == (int)SecurityStatus.WrongPrincipal))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.IncorrectSpnOrUpnSpecified, this.servicePrincipalName)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidSspiNegotiation)));
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                if (this.isServer)
                {
                    SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
                }
                else
                {
                    SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
                }
            }

            if (statusCode == (int)SecurityStatus.OK)
            {
                // we're done
                this.isCompleted = true;

                // These must all be true to check service binding
                // 1. we are the service (listener)
                // 2. caller is not anonymous
                // 3. protocol is not Kerberos
                // 4. policy is set to check service binding
                // 
                if (isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == 0) && (string.Compare(this.ProtocolName, NegotiationInfoClass.Kerberos, StringComparison.OrdinalIgnoreCase) != 0) && policyHelper.ShouldCheckServiceBinding)
                {
                    // in the server case the servicePrincipalName is the defaultServiceBinding
                   
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        string serviceBindingNameSentByClient;
                        SspiWrapper.QuerySpecifiedTarget(securityContext, out serviceBindingNameSentByClient);
                        IMD.SecurityTraceRecordHelper.TraceServiceNameBindingOnServer( serviceBindingNameSentByClient, this.servicePrincipalName, policyHelper.ServiceNameCollection);
                    }
                    
                    policyHelper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
                }
            }
            else
            {
                // we need to continue
            }

            return outSecurityBuffer.token;
        }
Example #45
0
 public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SecureCredential authdata, out SafeFreeCredentials outCredential)
 {
     return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
 }
Example #46
0
 internal IssuedSecurityTokenProvider(SafeFreeCredentials credentialsHandle)
 {
     this.federatedTokenProvider = new CoreFederatedTokenProvider(credentialsHandle);
     this.messageSecurityVersion = System.ServiceModel.MessageSecurityVersion.Default;
 }
Example #47
0
 public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
 {
     return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags);
 }
Example #48
0
        private void AcquireDummyCredentials()
        {
            SecureCredential secureCredential = new SecureCredential(SecureCredential.CurrentVersion, null, SecureCredential.Flags.ValidateManual | SecureCredential.Flags.NoDefaultCred, this.protocolFlags);

            this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(SecurityPackage, CredentialUse.Outbound, secureCredential);
        }