// 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(); } } }
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 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(); } } } }