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();
                }
            }
        }
        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));
            }
        }
Beispiel #3
0
 public SecurityBuffer(ChannelBinding channelBinding)
 {
     this.size           = channelBinding.Size;
     this.type           = BufferType.ChannelBindings;
     this.unmanagedToken = channelBinding;
 }
 internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding)
 {
     _instance = s_ntAuthentication.Invoke(new object[] { isServer, package, credential, spn, requestedContextFlags, channelBinding });
 }
Beispiel #5
0
 internal InitializeCallbackContext(NTAuthentication thisPtr, bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding)
 {
     ThisPtr               = thisPtr;
     IsServer              = isServer;
     Package               = package;
     Credential            = credential;
     Spn                   = spn;
     RequestedContextFlags = requestedContextFlags;
     ChannelBinding        = channelBinding;
 }
Beispiel #6
0
 public virtual IAsyncResult BeginAuthenticateAsClient(NetworkCredential credential, ChannelBinding binding, string targetName, AsyncCallback asyncCallback, object asyncState)
 {
     return(BeginAuthenticateAsClient(credential, binding, targetName,
                                      ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification,
                                      asyncCallback, asyncState));
 }
Beispiel #7
0
        private static SecurityStatusPal EstablishSecurityContext(
            SafeFreeNegoCredentials credential,
            ref SafeDeleteContext context,
            ChannelBinding channelBinding,
            string targetName,
            ContextFlagsPal inFlags,
            byte[] incomingBlob,
            ref byte[] resultBuffer,
            ref ContextFlagsPal outFlags)
        {
            bool isNtlmOnly = credential.IsNtlmOnly;

            if (context == null)
            {
                // Empty target name causes the failure on Linux, hence passing a non-empty string
                context = isNtlmOnly ? new SafeDeleteNegoContext(credential, credential.UserName) : new SafeDeleteNegoContext(credential, targetName);
            }

            SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context;

            try
            {
                Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false);
                uint outputFlags;
                int  isNtlmUsed;
                SafeGssContextHandle contextHandle = negoContext.GssContext;
                bool done = GssInitSecurityContext(
                    ref contextHandle,
                    credential.GssCredential,
                    isNtlmOnly,
                    channelBinding,
                    negoContext.TargetName,
                    inputFlags,
                    incomingBlob,
                    out resultBuffer,
                    out outputFlags,
                    out isNtlmUsed);

                Debug.Assert(resultBuffer != null, "Unexpected null buffer returned by GssApi");
                outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false);
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);

                // Save the inner context handle for further calls to NetSecurity
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);
                if (null == negoContext.GssContext)
                {
                    negoContext.SetGssContext(contextHandle);
                }

                // Populate protocol used for authentication
                if (done)
                {
                    negoContext.SetAuthenticationPackage(Convert.ToBoolean(isNtlmUsed));
                }

                SecurityStatusPalErrorCode errorCode = done ?
                                                       (negoContext.IsNtlmUsed && resultBuffer.Length > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) :
                                                       SecurityStatusPalErrorCode.ContinueNeeded;
                return(new SecurityStatusPal(errorCode));
            }
            catch (Exception ex)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(null, ex);
                }
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex));
            }
        }
Beispiel #8
0
        internal void ValidateCreateContext(string package, bool isServer, NetworkCredential credential, string servicePrincipalName, ChannelBinding channelBinding, ProtectionLevel protectionLevel, TokenImpersonationLevel impersonationLevel)
        {
            if ((this._Exception != null) && !this._CanRetryAuthentication)
            {
                throw this._Exception;
            }
            if ((this._Context != null) && this._Context.IsValidContext)
            {
                throw new InvalidOperationException(SR.GetString("net_auth_reauth"));
            }
            if (credential == null)
            {
                throw new ArgumentNullException("credential");
            }
            if (servicePrincipalName == null)
            {
                throw new ArgumentNullException("servicePrincipalName");
            }
            if (ComNetOS.IsWin9x && (protectionLevel != ProtectionLevel.None))
            {
                throw new NotSupportedException(SR.GetString("net_auth_no_protection_on_win9x"));
            }
            if (((impersonationLevel != TokenImpersonationLevel.Identification) && (impersonationLevel != TokenImpersonationLevel.Impersonation)) && (impersonationLevel != TokenImpersonationLevel.Delegation))
            {
                throw new ArgumentOutOfRangeException("impersonationLevel", impersonationLevel.ToString(), SR.GetString("net_auth_supported_impl_levels"));
            }
            if ((this._Context != null) && (this.IsServer != isServer))
            {
                throw new InvalidOperationException(SR.GetString("net_auth_client_server"));
            }
            this._Exception = null;
            this._RemoteOk  = false;
            this._Framer    = new StreamFramer(this._InnerStream);
            this._Framer.WriteHeader.MessageId = 0x16;
            this._ExpectedProtectionLevel      = protectionLevel;
            this._ExpectedImpersonationLevel   = isServer ? impersonationLevel : TokenImpersonationLevel.None;
            this._WriteSequenceNumber          = 0;
            this._ReadSequenceNumber           = 0;
            ContextFlags connection = ContextFlags.Connection;

            if ((protectionLevel == ProtectionLevel.None) && !isServer)
            {
                package = "NTLM";
            }
            else if (protectionLevel == ProtectionLevel.EncryptAndSign)
            {
                connection |= ContextFlags.Confidentiality;
            }
            else if (protectionLevel == ProtectionLevel.Sign)
            {
                connection |= ContextFlags.AcceptStream | ContextFlags.SequenceDetect | ContextFlags.ReplayDetect;
            }
            if (isServer)
            {
                if (this._ExtendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    connection |= ContextFlags.AllowMissingBindings;
                }
                if ((this._ExtendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never) && (this._ExtendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy))
                {
                    connection |= ContextFlags.ProxyBindings;
                }
            }
            else
            {
                if (protectionLevel != ProtectionLevel.None)
                {
                    connection |= ContextFlags.MutualAuth;
                }
                if (impersonationLevel == TokenImpersonationLevel.Identification)
                {
                    connection |= ContextFlags.AcceptIntegrity;
                }
                if (impersonationLevel == TokenImpersonationLevel.Delegation)
                {
                    connection |= ContextFlags.Delegate;
                }
            }
            this._CanRetryAuthentication = false;
            if (!(credential is SystemNetworkCredential))
            {
                ExceptionHelper.ControlPrincipalPermission.Demand();
            }
            try
            {
                this._Context = new NTAuthentication(isServer, package, credential, servicePrincipalName, connection, channelBinding);
            }
            catch (Win32Exception exception)
            {
                throw new AuthenticationException(SR.GetString("net_auth_SSPI"), exception);
            }
        }
        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);
            }
        }
 /// <summary>
 /// Converts provided binding to <see cref="IChannelBinding"/>.
 /// </summary>
 /// <param name="binding">Binding to convert.</param>
 /// <returns>Converted binding.</returns>
 public static IChannelBinding ToInterface(this ChannelBinding binding)
 {
     return((binding == null) ? null : new ChannelBindingAdapter(binding));
 }
Beispiel #11
0
        internal void ValidateCreateContext(
            string package,
            bool isServer,
            NetworkCredential credential,
            string servicePrincipalName,
            ChannelBinding channelBinding,
            ProtectionLevel protectionLevel,
            TokenImpersonationLevel impersonationLevel)
        {
            if (_exception != null && !_canRetryAuthentication)
            {
                throw _exception;
            }

            if (_context != null && _context.IsValidContext)
            {
                throw new InvalidOperationException(SR.net_auth_reauth);
            }

            if (credential == null)
            {
                throw new ArgumentNullException(nameof(credential));
            }

            if (servicePrincipalName == null)
            {
                throw new ArgumentNullException(nameof(servicePrincipalName));
            }

            NegotiateStreamPal.ValidateImpersonationLevel(impersonationLevel);
            if (_context != null && IsServer != isServer)
            {
                throw new InvalidOperationException(SR.net_auth_client_server);
            }

            _exception = null;
            _remoteOk  = false;
            _framer    = new StreamFramer(_innerStream);
            _framer.WriteHeader.MessageId = FrameHeader.HandshakeId;

            _expectedProtectionLevel    = protectionLevel;
            _expectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None;
            _writeSequenceNumber        = 0;
            _readSequenceNumber         = 0;

            ContextFlagsPal flags = ContextFlagsPal.Connection;

            // A workaround for the client when talking to Win9x on the server side.
            if (protectionLevel == ProtectionLevel.None && !isServer)
            {
                package = NegotiationInfoClass.NTLM;
            }
            else if (protectionLevel == ProtectionLevel.EncryptAndSign)
            {
                flags |= ContextFlagsPal.Confidentiality;
            }
            else if (protectionLevel == ProtectionLevel.Sign)
            {
                // Assuming user expects NT4 SP4 and above.
                flags |= (ContextFlagsPal.ReplayDetect | ContextFlagsPal.SequenceDetect | ContextFlagsPal.InitIntegrity);
            }

            if (isServer)
            {
                if (_extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    flags |= ContextFlagsPal.AllowMissingBindings;
                }

                if (_extendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never &&
                    _extendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    flags |= ContextFlagsPal.ProxyBindings;
                }
            }
            else
            {
                // Server side should not request any of these flags.
                if (protectionLevel != ProtectionLevel.None)
                {
                    flags |= ContextFlagsPal.MutualAuth;
                }

                if (impersonationLevel == TokenImpersonationLevel.Identification)
                {
                    flags |= ContextFlagsPal.InitIdentify;
                }

                if (impersonationLevel == TokenImpersonationLevel.Delegation)
                {
                    flags |= ContextFlagsPal.Delegate;
                }
            }

            _canRetryAuthentication = false;

            try
            {
                _context = new NTAuthentication(isServer, package, credential, servicePrincipalName, flags, channelBinding);
            }
            catch (Win32Exception e)
            {
                throw new AuthenticationException(SR.net_auth_SSPI, e);
            }
        }
Beispiel #12
0
 /// <summary>
 /// Called by clients to authenticate the client, and optionally the server, in a client-server connection. The authentication process uses the specified client credential and the channel binding.
 /// </summary>
 /// <param name="credential">The NetworkCredential that is used to establish the identity of the client.</param>
 /// <param name="binding">The ChannelBinding that is used for extended protection. </param>
 /// <param name="targetName">The Service Principal Name (SPN) that uniquely identifies the server to authenticate.</param>
 public VaserKerberosClient(NetworkCredential credential, ChannelBinding binding, string targetName)
 {
     _credential = credential;
     _targetName = targetName;
     _binding    = binding;
 }
 internal SecurityToken GetToken(TimeSpan timeout, ChannelBinding channelbinding)
 {
     return(new KerberosRequestorSecurityToken(this.innerProvider.ServicePrincipalName, this.innerProvider.TokenImpersonationLevel, this.innerProvider.NetworkCredential, System.ServiceModel.Security.SecurityUniqueId.Create().Value, this.credentialsHandle, channelbinding));
 }
Beispiel #14
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);
        }
Beispiel #15
0
        private static bool GssInitSecurityContext(
            ref SafeGssContextHandle context,
            SafeGssCredHandle credential,
            bool isNtlm,
            ChannelBinding channelBinding,
            SafeGssNameHandle targetName,
            Interop.NetSecurityNative.GssFlags inFlags,
            byte[] buffer,
            out byte[] outputBuffer,
            out uint outFlags,
            out int isNtlmUsed)
        {
            // If a TLS channel binding token (cbt) is available then get the pointer
            // to the application specific data.
            IntPtr cbtAppData     = IntPtr.Zero;
            int    cbtAppDataSize = 0;

            if (channelBinding != null)
            {
                int appDataOffset = Marshal.SizeOf <SecChannelBindings>();
                Debug.Assert(appDataOffset < channelBinding.Size);
                cbtAppData     = channelBinding.DangerousGetHandle() + appDataOffset;
                cbtAppDataSize = channelBinding.Size - appDataOffset;
            }

            outputBuffer = null;
            outFlags     = 0;

            // EstablishSecurityContext is called multiple times in a session.
            // In each call, we need to pass the context handle from the previous call.
            // For the first call, the context handle will be null.
            if (context == null)
            {
                context = new SafeGssContextHandle();
            }

            Interop.NetSecurityNative.GssBuffer token = default(Interop.NetSecurityNative.GssBuffer);
            Interop.NetSecurityNative.Status    status;

            try
            {
                Interop.NetSecurityNative.Status minorStatus;
                status = Interop.NetSecurityNative.InitSecContext(out minorStatus,
                                                                  credential,
                                                                  ref context,
                                                                  isNtlm,
                                                                  cbtAppData,
                                                                  cbtAppDataSize,
                                                                  targetName,
                                                                  (uint)inFlags,
                                                                  buffer,
                                                                  (buffer == null) ? 0 : buffer.Length,
                                                                  ref token,
                                                                  out outFlags,
                                                                  out isNtlmUsed);

                if ((status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE) && (status != Interop.NetSecurityNative.Status.GSS_S_CONTINUE_NEEDED))
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                outputBuffer = token.ToByteArray();
            }
            finally
            {
                token.Dispose();
            }

            return(status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE);
        }
        public Authorization Authenticate(string challenge, NetworkCredential credential, object sessionCookie, string spn, ChannelBinding channelBindingToken)
        {
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Enter(NetEventSource.ComponentType.Web, this, nameof(Authenticate), null);
            }
            try
            {
                lock (_sessions)
                {
                    NetworkCredential cachedCredential;
                    if (!_sessions.TryGetValue(sessionCookie, out cachedCredential))
                    {
                        if (credential == null || ReferenceEquals(credential, CredentialCache.DefaultNetworkCredentials))
                        {
                            return(null);
                        }

                        _sessions[sessionCookie] = credential;

                        string userName = credential.UserName;
                        string domain   = credential.Domain;

                        if (domain != null && domain.Length > 0)
                        {
                            userName = domain + "\\" + userName;
                        }

                        return(new Authorization(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(userName)), false));
                    }
                    else
                    {
                        _sessions.Remove(sessionCookie);

                        return(new Authorization(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(cachedCredential.Password)), true));
                    }
                }
            }
            finally
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Exit(NetEventSource.ComponentType.Web, this, "Authenticate", null);
                }
            }
        }
Beispiel #17
0
 //
 // This overload does not attempt to impersonate because the caller either did it already or the original thread context is still preserved.
 //
 internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, Interop.SspiCli.ContextFlags requestedContextFlags, ChannelBinding channelBinding)
 {
     Initialize(isServer, package, credential, spn, requestedContextFlags, channelBinding);
 }
Beispiel #18
0
 protected void SetChannelBinding(ChannelBinding channelBinding)
 {
     Fx.Assert(_channelBindingToken == null, "ChannelBinding token can only be set once.");
     _channelBindingToken = channelBinding;
 }
Beispiel #19
0
        private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, Interop.SspiCli.ContextFlags requestedContextFlags, ChannelBinding channelBinding)
        {
            GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor() package:" + LoggingHash.ObjectToString(package) + " spn:" + LoggingHash.ObjectToString(spn) + " flags :" + requestedContextFlags.ToString());
            _tokenSize             = SSPIWrapper.GetVerifyPackageInfo(GlobalSSPI.SSPIAuth, package, true).MaxToken;
            _isServer              = isServer;
            _spn                   = spn;
            _securityContext       = null;
            _requestedContextFlags = requestedContextFlags;
            _package               = package;
            _channelBinding        = channelBinding;

            GlobalLog.Print("Peer SPN-> '" + _spn + "'");

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

            Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials);
            if (credential == CredentialCache.DefaultCredentials)
            {
                GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor(): using DefaultCredentials");
                _credentialsHandle = SSPIWrapper.AcquireDefaultCredential(
                    GlobalSSPI.SSPIAuth,
                    package,
                    (_isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound));
            }
            else
            {
                unsafe
                {
                    SafeSspiAuthDataHandle authData = null;
                    try
                    {
                        Interop.SecurityStatus result = Interop.SspiCli.SspiEncodeStringsAsAuthIdentity(
                            credential.UserName, credential.Domain,
                            credential.Password, out authData);

                        if (result != Interop.SecurityStatus.OK)
                        {
                            if (NetEventSource.Log.IsEnabled())
                            {
                                NetEventSource.PrintError(
                                    NetEventSource.ComponentType.Security,
                                    SR.Format(
                                        SR.net_log_operation_failed_with_error,
                                        "SspiEncodeStringsAsAuthIdentity()",
                                        String.Format(CultureInfo.CurrentCulture, "0x{0:X}", (int)result)));
                            }

                            throw new Win32Exception((int)result);
                        }

                        _credentialsHandle = SSPIWrapper.AcquireCredentialsHandle(GlobalSSPI.SSPIAuth,
                                                                                  package, (_isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound), ref authData);
                    }
                    finally
                    {
                        if (authData != null)
                        {
                            authData.Dispose();
                        }
                    }
                }
            }
        }
Beispiel #20
0
 public virtual void AuthenticateAsClient(NetworkCredential credential, ChannelBinding binding, string targetName)
 {
     AuthenticateAsClient(credential, binding, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification);
 }
 internal KerberosRequestorSecurityToken(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, string id, System.IdentityModel.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", System.IdentityModel.SR.GetString("ImpersonationLevelNotSupported", new object[] { tokenImpersonationLevel })));
     }
     if (id == null)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("id");
     }
     this.servicePrincipalName = servicePrincipalName;
     if (((networkCredential != null) && (networkCredential != CredentialCache.DefaultNetworkCredentials)) && string.IsNullOrEmpty(networkCredential.UserName))
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(System.IdentityModel.SR.GetString("ProvidedNetworkCredentialsForKerberosHasInvalidUserName"));
     }
     this.id = id;
     try
     {
         this.Initialize(tokenImpersonationLevel, networkCredential, credentialsHandle, channelBinding);
     }
     catch (Win32Exception exception)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(System.IdentityModel.SR.GetString("UnableToCreateKerberosCredentials"), exception));
     }
     catch (SecurityTokenException exception2)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(System.IdentityModel.SR.GetString("UnableToCreateKerberosCredentials"), exception2));
     }
 }
Beispiel #22
0
        /// <devdoc>
        ///    <para>Pre-authenticates a request.</para>
        /// </devdoc>
        public override Authorization PreAuthenticate(WebRequest request, ICredentials credentials)
        {
            GlobalLog.Print("AuthenticationManager::PreAuthenticate() request:"
                            + ValidationHelper.HashString(request) + " credentials:" + ValidationHelper.HashString(credentials));

            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (credentials == null)
            {
                return(null);
            }

            HttpWebRequest        httpWebRequest = request as HttpWebRequest;
            IAuthenticationModule authenticationModule;

            if (httpWebRequest == null)
            {
                return(null);
            }

            //
            // PrefixLookup is thread-safe
            //
            string moduleName = moduleBinding.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as string;

            GlobalLog.Print("AuthenticationManager::PreAuthenticate() s_ModuleBinding.Lookup returns:"
                            + ValidationHelper.ToString(moduleName));

            if (moduleName == null)
            {
                return(null);
            }

            if (!this.moduleList.TryGetValue(moduleName.ToUpperInvariant(), out authenticationModule))
            {
                // The module could have been unregistered
                // No preauthentication is possible
                return(null);
            }

            // prepopulate the channel binding token so we can try preauth (but only for modules that actually need it!)
            if (httpWebRequest.ChallengedUri.Scheme == Uri.UriSchemeHttps)
            {
                object binding = httpWebRequest.ServicePoint.CachedChannelBinding;

#if DEBUG
                // the ModuleRequiresChannelBinding method is only compiled in DEBUG so the assert must be restricted to DEBUG
                // as well

                // If the authentication module does CBT, we require that it also caches channel bindings.
                System.Diagnostics.Debug.Assert(!(binding == null && ModuleRequiresChannelBinding(authenticationModule)));
#endif

                // can also be DBNull.Value, indicating "we previously succeeded without getting a CBT."
                // (ie, unpatched SSP talking to a partially-hardened server)
                ChannelBinding channelBinding = binding as ChannelBinding;
                if (channelBinding != null)
                {
                    httpWebRequest.CurrentAuthenticationState.TransportContext =
                        new CachedTransportContext(channelBinding);
                }
            }

            // Otherwise invoke the PreAuthenticate method
            // we're guaranteed that CanPreAuthenticate is true because we check before calling BindModule()
            Authorization authorization = authenticationModule.PreAuthenticate(request, credentials);

            if (authorization != null && !authorization.Complete && httpWebRequest != null)
            {
                httpWebRequest.CurrentAuthenticationState.Module = authenticationModule;
            }

            GlobalLog.Print(
                "AuthenticationManager::PreAuthenticate() IAuthenticationModule.PreAuthenticate()"
                + " returned authorization:" + ValidationHelper.HashString(authorization));

            return(authorization);
        }
        private void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, System.IdentityModel.SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            bool flag = false;

            System.IdentityModel.SafeDeleteContext context = null;
            try
            {
                if (credentialsHandle == null)
                {
                    if ((networkCredential == null) || (networkCredential == CredentialCache.DefaultNetworkCredentials))
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", System.IdentityModel.CredentialUse.Outbound, new string[0]);
                    }
                    else
                    {
                        AuthIdentityEx authdata = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain, new string[0]);
                        credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", System.IdentityModel.CredentialUse.Outbound, ref authdata);
                    }
                    flag = true;
                }
                SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
                if (tokenImpersonationLevel == TokenImpersonationLevel.Identification)
                {
                    inFlags |= SspiContextFlags.InitIdentify;
                }
                SspiContextFlags zero = SspiContextFlags.Zero;
                System.IdentityModel.SecurityBuffer inputBuffer = null;
                if (channelBinding != null)
                {
                    inputBuffer = new System.IdentityModel.SecurityBuffer(channelBinding);
                }
                System.IdentityModel.SecurityBuffer outputBuffer = new System.IdentityModel.SecurityBuffer(0, System.IdentityModel.BufferType.Token);
                int error = SspiWrapper.InitializeSecurityContext(credentialsHandle, ref context, this.servicePrincipalName, inFlags, System.IdentityModel.Endianness.Native, inputBuffer, outputBuffer, ref zero);
                switch (error)
                {
                case 0:
                    break;

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

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailInitializeSecurityContext"), new Win32Exception(error)));
                }
                this.apreq = outputBuffer.token;
                LifeSpan span = (LifeSpan)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.Lifespan);
                this.effectiveTime  = span.EffectiveTimeUtc;
                this.expirationTime = span.ExpiryTimeUtc;
                SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey);
            }
            finally
            {
                if (context != null)
                {
                    context.Close();
                }
                if (flag && (credentialsHandle != null))
                {
                    credentialsHandle.Close();
                }
            }
        }
Beispiel #24
0
            internal AuthenticateCallbackContext(SmtpConnection thisPtr, ISmtpAuthenticationModule module, NetworkCredential credential, string spn, ChannelBinding Token)
            {
                _thisPtr    = thisPtr;
                _module     = module;
                _credential = credential;
                _spn        = spn;
                _token      = Token;

                _result = null;
            }
Beispiel #25
0
 internal Task <SecurityToken> GetTokenAsync(CancellationToken cancellationToken, ChannelBinding channelbinding)
 {
     return(Task.FromResult((SecurityToken) new KerberosRequestorSecurityToken(this.innerProvider.ServicePrincipalName,
                                                                               this.innerProvider.TokenImpersonationLevel, this.innerProvider.NetworkCredential,
                                                                               SecurityUniqueId.Create().Value)));
 }
 public InputSecurityBuffer(ChannelBinding binding)
 {
     Type           = SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS;
     Token          = default;
     UnmanagedToken = binding;
 }
        public Authorization Authenticate(string challenge, NetworkCredential credential, object sessionCookie, string spn, ChannelBinding channelBindingToken)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this, "Authenticate");
            }
            try
            {
                lock (_sessions)
                {
                    NTAuthentication clientContext;
                    if (!_sessions.TryGetValue(sessionCookie, out clientContext))
                    {
                        if (credential == null)
                        {
                            return(null);
                        }

                        _sessions[sessionCookie] =
                            clientContext        =
                                new NTAuthentication(false, "Ntlm", credential, spn, ContextFlagsPal.Connection, channelBindingToken);
                    }

                    string resp = clientContext.GetOutgoingBlob(challenge);

                    if (!clientContext.IsCompleted)
                    {
                        return(new Authorization(resp, false));
                    }
                    else
                    {
                        _sessions.Remove(sessionCookie);
                        return(new Authorization(resp, true));
                    }
                }
            }
            // From reflected type NTAuthentication in System.Net.Security.
            catch (NullReferenceException)
            {
                return(null);
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this, "Authenticate");
                }
            }
        }
 internal KerberosRequestorSecurityToken(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, string id, ChannelBinding channelBinding)
     : this(servicePrincipalName, tokenImpersonationLevel, networkCredential, id, null, channelBinding)
 {
 }
Beispiel #29
0
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            ThrowIfDisposed();
            SecurityBuffer incomingSecurity = null;

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

            SecurityBuffer outgoingSecurity = new SecurityBuffer(null, BufferType.Token);

            this.remoteCertificate = null;
            int statusCode = 0;

            if (this.isServer == true)
            {
                statusCode = SspiWrapper.AcceptSecurityContext(
                    this.credentialsHandle,
                    ref this.securityContext,
                    ServerStandardFlags | (this.clientCertRequired ? SspiContextFlags.MutualAuth : SspiContextFlags.Zero),
                    Endianness.Native,
                    incomingSecurity,
                    outgoingSecurity,
                    ref this.attributes
                    );
            }
            else
            {
                statusCode = SspiWrapper.InitializeSecurityContext(
                    this.credentialsHandle,
                    ref this.securityContext,
                    this.destination,
                    ClientStandardFlags,
                    Endianness.Native,
                    incomingSecurity,
                    outgoingSecurity,
                    ref this.attributes
                    );
            }

            if ((statusCode & unchecked ((int)0x80000000)) != 0)
            {
                this.Dispose();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
            }

            if (statusCode == (int)SecurityStatus.OK)
            {
                // we're done
                // ensure that the key negotiated is strong enough
                if (SecurityUtils.ShouldValidateSslCipherStrength())
                {
                    SslConnectionInfo connectionInfo = (SslConnectionInfo)SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.ConnectionInfo);
                    if (connectionInfo == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.CannotObtainSslConnectionInfo)));
                    }
                    SecurityUtils.ValidateSslCipherStrength(connectionInfo.DataKeySize);
                }
                this.isCompleted = true;
            }
            else if (statusCode == (int)SecurityStatus.CredentialsNeeded)
            {
                // the server requires the client to supply creds
                // Currently we dont attempt to find the client cert to choose at runtime
                // so just re-call the function
                AcquireClientCredentials();
                if (this.ClientCertificate != null)
                {
                    this.wasClientCertificateSent = true;
                }
                return(this.GetOutgoingBlob(incomingBlob, channelbinding, protectionPolicy));
            }
            else if (statusCode != (int)SecurityStatus.ContinueNeeded)
            {
                this.Dispose();
                if (statusCode == (int)SecurityStatus.InternalError)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.LsaAuthorityNotContacted)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
                }
            }
            return(outgoingSecurity.token);
        }
Beispiel #30
0
 public virtual Task AuthenticateAsClientAsync(NetworkCredential credential, ChannelBinding binding, string targetName)
 {
     return(Task.Factory.FromAsync(BeginAuthenticateAsClient, EndAuthenticateAsClient, credential, binding, targetName, null));
 }
 public ExtendedProtectionPolicy(PolicyEnforcement policyEnforcement, ChannelBinding customChannelBinding);