internal void DecryptInPlace(byte[] encryptedContent, out int dataStartOffset, out int dataLen) { this.ThrowIfDisposed(); dataStartOffset = this.StreamSizes.header; dataLen = 0; byte[] data = new byte[0]; byte[] buffer2 = new byte[0]; byte[] buffer3 = new byte[0]; SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, System.IdentityModel.BufferType.Data), new SecurityBuffer(data, System.IdentityModel.BufferType.Empty), new SecurityBuffer(buffer2, System.IdentityModel.BufferType.Empty), new SecurityBuffer(buffer3, System.IdentityModel.BufferType.Empty) }; int error = SspiWrapper.DecryptMessage(this.securityContext, input, 0, false); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } for (int i = 0; i < input.Length; i++) { if (input[i].type == System.IdentityModel.BufferType.Data) { dataLen = input[i].size; return; } } this.OnBadData(); }
internal bool TryGetContextIdentity(out WindowsIdentity mappedIdentity) { bool flag; if (!this.IsValidContext) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(-2146893055)); } SafeCloseHandle token = null; try { if (SspiWrapper.QuerySecurityContextToken(this.securityContext, out token) != 0) { mappedIdentity = null; return(false); } mappedIdentity = new WindowsIdentity(token.DangerousGetHandle(), "SSL/PCT"); flag = true; } finally { if (token != null) { token.Close(); } } return(flag); }
internal void EncryptInPlace(byte[] buffer, int bufferStartOffset, int dataLen, out int encryptedDataLen) { this.ThrowIfDisposed(); encryptedDataLen = 0; if ((((bufferStartOffset + dataLen) + this.StreamSizes.header) + this.StreamSizes.trailer) > buffer.Length) { this.OnBadData(); } byte[] data = new byte[0]; int offset = (bufferStartOffset + this.StreamSizes.header) + dataLen; SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(buffer, bufferStartOffset, this.StreamSizes.header, System.IdentityModel.BufferType.Header), new SecurityBuffer(buffer, bufferStartOffset + this.StreamSizes.header, dataLen, System.IdentityModel.BufferType.Data), new SecurityBuffer(buffer, offset, this.StreamSizes.trailer, System.IdentityModel.BufferType.Trailer), new SecurityBuffer(data, System.IdentityModel.BufferType.Empty) }; int error = SspiWrapper.EncryptMessage(this.securityContext, input, 0); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } int size = 0; for (int i = 0; i < input.Length; i++) { if (input[i].type == System.IdentityModel.BufferType.Trailer) { size = input[i].size; encryptedDataLen = (this.StreamSizes.header + dataLen) + size; return; } } this.OnBadData(); }
internal bool TryGetContextIdentity(out WindowsIdentity mappedIdentity) { if (!IsValidContext) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)SecurityStatus.InvalidHandle)); } SafeCloseHandle token = null; try { SecurityStatus status = (SecurityStatus)SspiWrapper.QuerySecurityContextToken(this.securityContext, out token); if (status != SecurityStatus.OK) { mappedIdentity = null; return(false); } mappedIdentity = new WindowsIdentity(token.DangerousGetHandle(), SecurityUtils.AuthTypeCertMap); return(true); } finally { if (token != null) { token.Close(); } } }
/// <summary> /// The decrypted data will start header bytes from the start of /// encryptedContent array. /// </summary> internal unsafe void DecryptInPlace(byte[] encryptedContent, out int dataStartOffset, out int dataLen) { ThrowIfDisposed(); dataStartOffset = StreamSizes.header; dataLen = 0; byte[] emptyBuffer1 = new byte[0]; byte[] emptyBuffer2 = new byte[0]; byte[] emptyBuffer3 = new byte[0]; SecurityBuffer[] securityBuffer = new SecurityBuffer[4]; securityBuffer[0] = new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Data); securityBuffer[1] = new SecurityBuffer(emptyBuffer1, BufferType.Empty); securityBuffer[2] = new SecurityBuffer(emptyBuffer2, BufferType.Empty); securityBuffer[3] = new SecurityBuffer(emptyBuffer3, BufferType.Empty); int errorCode = SspiWrapper.DecryptMessage(this.securityContext, securityBuffer, 0, false); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Data) { dataLen = securityBuffer[i].size; return; } } OnBadData(); }
public byte[] Decrypt(byte[] encryptedContent) { if (encryptedContent == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptedContent"); } ThrowIfDisposed(); SecurityBuffer[] securityBuffer = new SecurityBuffer[2]; securityBuffer[0] = new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Stream); securityBuffer[1] = new SecurityBuffer(0, BufferType.Data); int errorCode = SspiWrapper.DecryptMessage(this.securityContext, securityBuffer, 0, true); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Data) { return(securityBuffer[i].token); } } OnBadData(); return(null); }
public void ImpersonateContext() { this.ThrowIfDisposed(); if (!this.IsValidContext) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(-2146893055)); } SspiWrapper.ImpersonateSecurityContext(this.securityContext); }
private void AcquireClientCredentials() { SecureCredential secureCredential = new SecureCredential(SecureCredential.CurrentVersion, this.ClientCertificate, SecureCredential.Flags.ValidateManual | SecureCredential.Flags.NoDefaultCred, this.protocolFlags); this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle( SecurityPackage, CredentialUse.Outbound, secureCredential ); }
private void AcquireServerCredentials() { SecureCredential secureCredential = new SecureCredential(SecureCredential.CurrentVersion, this.serverCertificate, SecureCredential.Flags.Zero, this.protocolFlags); this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle( SecurityPackage, CredentialUse.Inbound, secureCredential ); }
public void ImpersonateContext() { ThrowIfDisposed(); if (!IsValidContext) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)SecurityStatus.InvalidHandle)); } SspiWrapper.ImpersonateSecurityContext(this.securityContext); }
private TlsSspiNegotiation( string destination, bool isServer, SchProtocols protocolFlags, X509Certificate2 serverCertificate, X509Certificate2 clientCertificate, bool clientCertRequired) { SspiWrapper.GetVerifyPackageInfo(SecurityPackage); this.destination = destination; this.isServer = isServer; this.protocolFlags = protocolFlags; this.serverCertificate = serverCertificate; this.clientCertificate = clientCertificate; this.clientCertRequired = clientCertRequired; this.securityContext = null; if (isServer) { ValidateServerCertificate(); } else { ValidateClientCertificate(); } if (this.isServer) { // This retry is to address intermittent failure when accessing private key (MB56153) try { AcquireServerCredentials(); } catch (Win32Exception ex) { if (ex.NativeErrorCode != (int)SecurityStatus.UnknownCredential) { throw; } DiagnosticUtility.TraceHandledException(ex, TraceEventType.Information); // Yield Thread.Sleep(0); AcquireServerCredentials(); } } else { // delay client credentials presenting till they are asked for AcquireDummyCredentials(); } }
internal SafeCloseHandle GetContextToken() { SafeCloseHandle handle; if (!this.IsValidContext) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(-2146893055)); } SecurityStatus status = (SecurityStatus)SspiWrapper.QuerySecurityContextToken(this.securityContext, out handle); if (status != SecurityStatus.OK) { Utility.CloseInvalidOutSafeHandle(handle); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)status)); } return(handle); }
internal SafeCloseHandle GetContextToken() { if (!IsValidContext) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)SecurityStatus.InvalidHandle)); } SafeCloseHandle token; SecurityStatus status = (SecurityStatus)SspiWrapper.QuerySecurityContextToken(this.securityContext, out token); if (status != SecurityStatus.OK) { Utility.CloseInvalidOutSafeHandle(token); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)status)); } return(token); }
public byte[] Encrypt(byte[] input) { if (input == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("input"); } ThrowIfDisposed(); SecurityBuffer[] securityBuffer = new SecurityBuffer[3]; byte[] tokenBuffer = DiagnosticUtility.Utility.AllocateByteArray(SecuritySizes.SecurityTrailer); securityBuffer[0] = new SecurityBuffer(tokenBuffer, 0, tokenBuffer.Length, BufferType.Token); byte[] dataBuffer = DiagnosticUtility.Utility.AllocateByteArray(input.Length); Buffer.BlockCopy(input, 0, dataBuffer, 0, input.Length); securityBuffer[1] = new SecurityBuffer(dataBuffer, 0, dataBuffer.Length, BufferType.Data); byte[] paddingBuffer = DiagnosticUtility.Utility.AllocateByteArray(SecuritySizes.BlockSize); securityBuffer[2] = new SecurityBuffer(paddingBuffer, 0, paddingBuffer.Length, BufferType.Padding); int errorCode = SspiWrapper.EncryptMessage(this.securityContext, securityBuffer, 0); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } int tokenLen = 0; int paddingLen = 0; for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Token) { tokenLen = securityBuffer[i].size; } else if (securityBuffer[i].type == BufferType.Padding) { paddingLen = securityBuffer[i].size; } } byte[] encryptedData = DiagnosticUtility.Utility.AllocateByteArray(checked (tokenLen + dataBuffer.Length + paddingLen)); Buffer.BlockCopy(tokenBuffer, 0, encryptedData, 0, tokenLen); Buffer.BlockCopy(dataBuffer, 0, encryptedData, tokenLen, dataBuffer.Length); Buffer.BlockCopy(paddingBuffer, 0, encryptedData, tokenLen + dataBuffer.Length, paddingLen); return(encryptedData); }
private TlsSspiNegotiation(string destination, bool isServer, SchProtocols protocolFlags, X509Certificate2 serverCertificate, X509Certificate2 clientCertificate, bool clientCertRequired) { this.syncObject = new object(); SspiWrapper.GetVerifyPackageInfo("Microsoft Unified Security Protocol Provider"); this.destination = destination; this.isServer = isServer; this.protocolFlags = protocolFlags; this.serverCertificate = serverCertificate; this.clientCertificate = clientCertificate; this.clientCertRequired = clientCertRequired; this.securityContext = null; if (isServer) { this.ValidateServerCertificate(); } else { this.ValidateClientCertificate(); } if (this.isServer) { try { this.AcquireServerCredentials(); } catch (Win32Exception exception) { if (exception.NativeErrorCode != -2146893043) { throw; } if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation) { System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information); } Thread.Sleep(0); this.AcquireServerCredentials(); } } else { this.AcquireDummyCredentials(); } }
public byte[] Encrypt(byte[] input) { if (input == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("input"); } this.ThrowIfDisposed(); SecurityBuffer[] bufferArray = new SecurityBuffer[3]; byte[] data = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(this.SecuritySizes.SecurityTrailer); bufferArray[0] = new SecurityBuffer(data, 0, data.Length, BufferType.Token); byte[] dst = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(input.Length); Buffer.BlockCopy(input, 0, dst, 0, input.Length); bufferArray[1] = new SecurityBuffer(dst, 0, dst.Length, BufferType.Data); byte[] buffer3 = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(this.SecuritySizes.BlockSize); bufferArray[2] = new SecurityBuffer(buffer3, 0, buffer3.Length, BufferType.Padding); int error = SspiWrapper.EncryptMessage(this.securityContext, bufferArray, 0); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } int count = 0; int size = 0; for (int i = 0; i < bufferArray.Length; i++) { if (bufferArray[i].type == BufferType.Token) { count = bufferArray[i].size; } else if (bufferArray[i].type == BufferType.Padding) { size = bufferArray[i].size; } } byte[] buffer4 = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray((count + dst.Length) + size); Buffer.BlockCopy(data, 0, buffer4, 0, count); Buffer.BlockCopy(dst, 0, buffer4, count, dst.Length); Buffer.BlockCopy(buffer3, 0, buffer4, count + dst.Length, size); return(buffer4); }
WindowsSspiNegotiation(bool isServer, string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled) { this.tokenSize = SspiWrapper.GetVerifyPackageInfo(package).MaxToken; this.isServer = isServer; this.servicePrincipalName = servicePrincipalName; this.securityContext = null; if (isServer) { this.impersonationLevel = TokenImpersonationLevel.Delegation; this.doMutualAuth = false; } else { this.impersonationLevel = impersonationLevel; this.doMutualAuth = doMutualAuth; this.interactiveNegoLogonEnabled = interactiveLogonEnabled; this.clientPackageName = package; this.allowNtlm = ntlmEnabled; } this.credentialsHandle = credentialsHandle; }
/// <summary> /// Assumes that the data to encrypt is "header" bytes ahead of bufferStartOffset /// </summary> internal unsafe void EncryptInPlace(byte[] buffer, int bufferStartOffset, int dataLen, out int encryptedDataLen) { ThrowIfDisposed(); encryptedDataLen = 0; if (bufferStartOffset + dataLen + StreamSizes.header + StreamSizes.trailer > buffer.Length) { OnBadData(); } byte[] emptyBuffer = new byte[0]; int trailerOffset = bufferStartOffset + StreamSizes.header + dataLen; SecurityBuffer[] securityBuffer = new SecurityBuffer[4]; securityBuffer[0] = new SecurityBuffer(buffer, bufferStartOffset, StreamSizes.header, BufferType.Header); securityBuffer[1] = new SecurityBuffer(buffer, bufferStartOffset + StreamSizes.header, dataLen, BufferType.Data); securityBuffer[2] = new SecurityBuffer(buffer, trailerOffset, StreamSizes.trailer, BufferType.Trailer); securityBuffer[3] = new SecurityBuffer(emptyBuffer, BufferType.Empty); int errorCode = SspiWrapper.EncryptMessage(this.securityContext, securityBuffer, 0); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } int trailerSize = 0; for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Trailer) { trailerSize = securityBuffer[i].size; encryptedDataLen = StreamSizes.header + dataLen + trailerSize; return; } } OnBadData(); }
public byte[] Decrypt(byte[] encryptedContent) { if (encryptedContent == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptedContent"); } this.ThrowIfDisposed(); SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Stream), new SecurityBuffer(0, BufferType.Data) }; int error = SspiWrapper.DecryptMessage(this.securityContext, input, 0, true); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } for (int i = 0; i < input.Length; i++) { if (input[i].type == BufferType.Data) { return(input[i].token); } } this.OnBadData(); return(null); }
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(); } } }
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); }
private SafeFreeCertContext ExtractCertificateHandle(ContextAttribute contextAttribute) { SafeFreeCertContext result = SspiWrapper.QueryContextAttributes(this.securityContext, contextAttribute) as SafeFreeCertContext; return(result); }
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(); } } } }
// 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(); } } }
private void AcquireServerCredentials() { SecureCredential scc = new SecureCredential(4, this.serverCertificate, SecureCredential.Flags.Zero, this.protocolFlags); this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Microsoft Unified Security Protocol Provider", CredentialUse.Inbound, scc); }
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); }
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(); } } }
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); }
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); }
private void AcquireClientCredentials() { SecureCredential scc = new SecureCredential(4, this.ClientCertificate, SecureCredential.Flags.NoDefaultCred | SecureCredential.Flags.ValidateManual, this.protocolFlags); this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Microsoft Unified Security Protocol Provider", CredentialUse.Outbound, scc); }