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); }
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); }
public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy) { this.ThrowIfDisposed(); SecurityBuffer inputBuffer = null; if (incomingBlob != null) { inputBuffer = new SecurityBuffer(incomingBlob, System.IdentityModel.BufferType.Token); } SecurityBuffer outputBuffer = new SecurityBuffer(null, System.IdentityModel.BufferType.Token); this.remoteCertificate = null; int error = 0; if (this.isServer) { error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, ServerStandardFlags | (this.clientCertRequired ? SspiContextFlags.MutualAuth : SspiContextFlags.Zero), Endianness.Native, inputBuffer, outputBuffer, ref this.attributes); } else { error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.destination, ClientStandardFlags, Endianness.Native, inputBuffer, outputBuffer, ref this.attributes); } if ((error & -2147483648) != 0) { this.Dispose(); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } if (error == 0) { if (System.ServiceModel.Security.SecurityUtils.ShouldValidateSslCipherStrength()) { SslConnectionInfo info = (SslConnectionInfo)SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.ConnectionInfo); if (info == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("CannotObtainSslConnectionInfo"))); } System.ServiceModel.Security.SecurityUtils.ValidateSslCipherStrength(info.DataKeySize); } this.isCompleted = true; } else { if (error == 0x90320) { this.AcquireClientCredentials(); if (this.ClientCertificate != null) { this.wasClientCertificateSent = true; } return(this.GetOutgoingBlob(incomingBlob, channelbinding, protectionPolicy)); } if (error != 0x90312) { this.Dispose(); if (error == -2146893052) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("LsaAuthorityNotContacted"))); } throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } } return(outputBuffer.token); }
// 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(); } } }
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(); } } } }
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); }