private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this, package, spn, requestedContextFlags); _tokenSize = NegotiateStreamPal.QueryMaxTokenSize(package); _isServer = isServer; _spn = spn; _securityContext = null; _requestedContextFlags = requestedContextFlags; _package = package; _channelBinding = channelBinding; if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Peer SPN-> '{_spn}'"); // // Check if we're using DefaultCredentials. // Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials); if (credential == CredentialCache.DefaultCredentials) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, "using DefaultCredentials"); _credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(package, _isServer); } else { _credentialsHandle = NegotiateStreamPal.AcquireCredentialsHandle(package, _isServer, credential); } }
public void AcceptSecurityContext(SafeFreeCredentials credential, SafeDeleteContext context, Interop.SspiCli.ContextFlags inFlags) { if (IsEnabled()) { AcceptSecurityContext(IdOf(credential), IdOf(context), inFlags); } }
public void InitializeSecurityContext(SafeFreeCredentials credential, SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags) { if (IsEnabled()) { InitializeSecurityContext(IdOf(credential), IdOf(context), targetName, inFlags); } }
public SecurityStatus InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer) { Interop.Secur32.ContextFlags outFlags = Interop.Secur32.ContextFlags.Zero; var retStatus = (SecurityStatus)SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, RequiredFlags | Interop.Secur32.ContextFlags.InitManualCredValidation, Interop.Secur32.Endianness.Native, inputBuffer, null, outputBuffer, ref outFlags); return MapToSecurityStatus((Interop.SecurityStatus)retStatus); }
internal static SecurityStatus AcceptSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "AcceptSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "remoteCertRequired = " + remoteCertRequired); } return SecModule.AcceptSecurityContext(ref credential, ref context, inputBuffer, outputBuffer, remoteCertRequired); }
public SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { SafeFreeCredentials retVal = new SafeFreeCredentials(certificate, protocols, policy); if (null != retVal) { // Caller does a ref count decrement bool ignore = false; retVal.DangerousAddRef(ref ignore); // TODO (Issue #3362) retVal is not getting released now, need to be fixed. } return retVal; }
public int AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { Interop.Secur32.ContextFlags outFlags = Interop.Secur32.ContextFlags.Zero; return SafeDeleteContext.AcceptSecurityContext( ref credential, ref context, ServerRequiredFlags | (remoteCertRequired ? Interop.Secur32.ContextFlags.MutualAuth : Interop.Secur32.ContextFlags.Zero), Interop.Secur32.Endianness.Native, inputBuffer, null, outputBuffer, ref outFlags ); }
internal static SecurityStatus InitializeSecurityContext(SSPIInterface SecModule, SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "InitializeSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "targetName = " + targetName); } SecurityStatus errorCode = SecModule.InitializeSecurityContext(credential, ref context, targetName, inputBuffers, outputBuffer); return errorCode; }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags); int errorCode = SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPISecureChannel, ref credentialsHandle, ref context, ServerRequiredFlags | (remoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero), Interop.SspiCli.Endianness.Native, inputBuffer, outputBuffer, ref unusedAttributes); return GetSecurityStatusPalFromWin32Int(errorCode); }
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer) { Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags); int errorCode = SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPISecureChannel, credentialsHandle, ref context, targetName, RequiredFlags | Interop.SspiCli.ContextFlags.InitManualCredValidation, Interop.SspiCli.Endianness.Native, inputBuffers, outputBuffer, ref unusedAttributes); return GetSecurityStatusPalFromWin32Int(errorCode); }
internal static void CacheCredential(SafeFreeCredentials creds, byte[] thumbPrint, SchProtocols allowedProtocols, EncryptionPolicy encryptionPolicy) { if (!creds.IsInvalid) { object obj2 = new SslCredKey(thumbPrint, allowedProtocols, encryptionPolicy); SafeCredentialReference reference = s_CachedCreds[obj2] as SafeCredentialReference; if (((reference == null) || reference.IsClosed) || reference._Target.IsInvalid) { lock (s_CachedCreds) { reference = s_CachedCreds[obj2] as SafeCredentialReference; if ((reference == null) || reference.IsClosed) { reference = SafeCredentialReference.CreateReference(creds); if (reference != null) { s_CachedCreds[obj2] = reference; if ((s_CachedCreds.Count % 0x20) == 0) { DictionaryEntry[] array = new DictionaryEntry[s_CachedCreds.Count]; s_CachedCreds.CopyTo(array, 0); for (int i = 0; i < array.Length; i++) { reference = array[i].Value as SafeCredentialReference; if (reference != null) { creds = reference._Target; reference.Close(); if ((!creds.IsClosed && !creds.IsInvalid) && ((reference = SafeCredentialReference.CreateReference(creds)) != null)) { s_CachedCreds[array[i].Key] = reference; } else { s_CachedCreds.Remove(array[i].Key); } } } } } } } } } }
internal static void CacheCredential(SafeFreeCredentials newHandle) { try { SafeCredentialReference newRef = SafeCredentialReference.CreateReference(newHandle); if (newRef == null) return; unchecked { int index = Interlocked.Increment(ref _Current) & c_MaxCacheSize; newRef = Interlocked.Exchange<SafeCredentialReference>(ref _CacheSlots[index], newRef); } if (newRef != null) newRef.Close(); } catch(Exception e) { if (!NclUtilities.IsFatal(e)){ GlobalLog.Assert("SSPIHandlCache", "Attempted to throw: " + e.ToString()); } } }
internal static void CacheCredential(SafeFreeCredentials newHandle) { try { SafeCredentialReference reference = SafeCredentialReference.CreateReference(newHandle); if (reference != null) { int index = Interlocked.Increment(ref _Current) & 0x1f; reference = Interlocked.Exchange<SafeCredentialReference>(ref _CacheSlots[index], reference); if (reference != null) { reference.Close(); } } } catch (Exception exception) { NclUtilities.IsFatal(exception); } }
WindowsSspiNegotiation(bool isServer, string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled) { this.tokenSize = SspiWrapper.GetVerifyPackageInfo(package).MaxToken; this.isServer = isServer; this.servicePrincipalName = servicePrincipalName; this.securityContext = null; if (isServer) { this.impersonationLevel = TokenImpersonationLevel.Delegation; this.doMutualAuth = false; } else { this.impersonationLevel = impersonationLevel; this.doMutualAuth = doMutualAuth; this.interactiveNegoLogonEnabled = interactiveLogonEnabled; this.clientPackageName = package; this.allowNtlm = ntlmEnabled; } this.credentialsHandle = credentialsHandle; }
internal static SecurityStatus InitializeSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer) { if (Logging.On) { Logging.PrintInfo(Logging.Web, "InitializeSecurityContext(" + "credential = " + credential.ToString() + ", " + "context = " + Logging.ObjectToString(context) + ", " + "targetName = " + targetName); } SecurityStatus errorCode = SecModule.InitializeSecurityContext(ref credential, ref context, targetName, inputBuffer, outputBuffer); if (Logging.On) { Logging.PrintInfo(Logging.Web, SR.Format(SR.net_log_sspi_security_context_input_buffer, "InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (SecurityStatus)errorCode)); } return errorCode; }
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired) { Debug.Assert(!credential.IsInvalid); try { if ((null == context) || context.IsInvalid) { context = new SafeDeleteContext(credential, isServer, remoteCertRequired); } byte[] output = null; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(context.SslContext, null, 0, 0, out output, out outputSize); } else { done = Interop.OpenSsl.DoSslHandshake(context.SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, out output, out outputSize); } outputBuffer.size = outputSize; outputBuffer.offset = 0; outputBuffer.token = outputSize > 0 ? output : null; return done ? SecurityStatusPal.OK : SecurityStatusPal.ContinueNeeded; } catch { // TODO: This Debug.Fail is triggering on Linux in many test cases #4317 // Debug.Fail("Exception Caught. - " + ex); return SecurityStatusPal.InternalError; } }
public int AcquireDefaultCredential(string moduleName, Interop.SspiCli.CredentialUse usage, out SafeFreeCredentials outCredential) { return SafeFreeCredentials.AcquireDefaultCredential(moduleName, usage, out outCredential); }
public SecuritySessionSecurityTokenProvider(SafeFreeCredentials credentialsHandle) { this.credentialsHandle = credentialsHandle; this.standardsManager = SecurityStandardsManager.DefaultInstance; this.keyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy; }
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer) { return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, false, false); }
internal static int InitializeSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.InitializeSecurityContext(credential.ToString(), LoggingHash.ObjectToString(context), targetName, inFlags); } int errorCode = secModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffer, outputBuffer, ref outFlags); if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.SecurityContextInputBuffer("InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SecurityStatus)errorCode); } return errorCode; }
/// <summary> /// Generate SSPI context /// </summary> /// <param name="sspiClientContextStatus">SSPI client context status</param> /// <param name="receivedBuff">Receive buffer</param> /// <param name="sendBuff">Send buffer</param> /// <param name="serverName">Service Principal Name buffer</param> public void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[] serverName) { SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext; ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags; SafeFreeCredentials credentialsHandle = sspiClientContextStatus.CredentialsHandle; string securityPackage = NegotiationInfoClass.Negotiate; if (securityContext == null) { credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(securityPackage, false); } int tokenSize = NegotiateStreamPal.QueryMaxTokenSize(securityPackage); byte[] resultToken = new byte[tokenSize]; ContextFlagsPal requestedContextFlags = ContextFlagsPal.Connection | ContextFlagsPal.Confidentiality | ContextFlagsPal.Delegate | ContextFlagsPal.MutualAuth; string serverSPN = System.Text.Encoding.UTF8.GetString(serverName); SecurityStatusPal statusCode = NegotiateStreamPal.InitializeSecurityContext( ref credentialsHandle, ref securityContext, serverSPN, requestedContextFlags, receivedBuff, null, ref resultToken, ref contextFlags); if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded || statusCode.ErrorCode == SecurityStatusPalErrorCode.CompAndContinue) { statusCode = NegotiateStreamPal.CompleteAuthToken(ref securityContext, resultToken); resultToken = null; } sendBuff = resultToken; if (sendBuff == null) { sendBuff = Array.Empty <byte>(); } sspiClientContextStatus.SecurityContext = securityContext; sspiClientContextStatus.ContextFlags = contextFlags; sspiClientContextStatus.CredentialsHandle = credentialsHandle; if (IsErrorStatus(statusCode.ErrorCode)) { // Could not access Kerberos Ticket. // // SecurityStatusPalErrorCode.InternalError only occurs in Unix and always comes with a GssApiException, // so we don't need to check for a GssApiException here. if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError) { throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode); } else { throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + "\n" + statusCode); } } }
public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy) { ThrowIfDisposed(); int statusCode = 0; // use the confidentiality option to ensure we can encrypt messages SspiContextFlags requestedFlags = SspiContextFlags.Confidentiality | SspiContextFlags.ReplayDetect | SspiContextFlags.SequenceDetect; if (this.doMutualAuth) { requestedFlags |= SspiContextFlags.MutualAuth; } if (this.impersonationLevel == TokenImpersonationLevel.Delegation) { requestedFlags |= SspiContextFlags.Delegate; } else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Identification) { requestedFlags |= SspiContextFlags.InitIdentify; } else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Anonymous) { requestedFlags |= SspiContextFlags.InitAnonymous; } ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy); if (isServer) { if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing))); } if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { requestedFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy) { requestedFlags |= SspiContextFlags.ChannelBindingProxyBindings; } } List <SecurityBuffer> list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, BufferType.Token)); } // when deciding if the channel binding should be added to the security buffer // it is necessary to differentiate between client and server. // Server rules were added to policyHelper as they are shared with Kerb and I want them consistent // Client adds if not null. if (this.isServer) { if (policyHelper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(policyHelper.ChannelBinding)); } } else { if (policyHelper.ChannelBinding != null) { list.Add(new SecurityBuffer(policyHelper.ChannelBinding)); } } SecurityBuffer[] inSecurityBuffer = null; if (list.Count > 0) { inSecurityBuffer = list.ToArray(); } SecurityBuffer outSecurityBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token); if (!this.isServer) { //client session statusCode = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); } else { // server session //This check is to save an unnecessary ASC call. bool isServerSecurityContextNull = this.securityContext == null; SspiContextFlags serverContextFlags = this.contextFlags; statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); if (statusCode == (int)SecurityStatus.InvalidToken && !isServerSecurityContextNull) { // Call again into ASC after deleting the Securitycontext. If this securitycontext is not deleted // then when the client sends NTLM blob the service will treat it as Nego2blob and will fail to authenticate the client. this.contextFlags = serverContextFlags; CloseContext(); statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); } } if (DiagnosticUtility.ShouldTraceInformation) { IMD.SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, this.isServer, channelbinding); } if ((statusCode & unchecked ((int)0x80000000)) != 0) { if (!this.isServer && this.interactiveNegoLogonEnabled && SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint)statusCode) && SspiWrapper.IsNegotiateExPackagePresent()) { // If we have prompted enough number of times (DefaultMaxPromptAttempts) with wrong credentials, then we do not prompt again and throw. if (MaxPromptAttempts >= DefaultMaxPromptAttempts) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidClientCredentials))); } IntPtr ppAuthIdentity = IntPtr.Zero; uint errorCode = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out ppAuthIdentity, ref this.saveClientCredentialsOnSspiUi); if (errorCode == (uint)CredentialStatus.Success) { IntPtr ppNewAuthIdentity = IntPtr.Zero; if (!this.allowNtlm) { // When Ntlm is explicitly disabled we don't want the collected //creds from the Kerb/NTLM tile to be used for NTLM auth. uint status = UnsafeNativeMethods.SspiExcludePackage(ppAuthIdentity, "NTLM", out ppNewAuthIdentity); } else { ppNewAuthIdentity = ppAuthIdentity; } this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity); if (IntPtr.Zero != ppNewAuthIdentity) { UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity); } CloseContext(); MaxPromptAttempts++; return(this.GetOutgoingBlob(null, channelbinding, protectionPolicy)); } else { // Call into SspiPromptForCredential had an error. Time to throw. if (IntPtr.Zero != ppAuthIdentity) { UnsafeNativeMethods.SspiFreeAuthIdentity(ppAuthIdentity); } CloseContext(); this.isCompleted = true; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)errorCode, SR.GetString(SR.SspiErrorOrInvalidClientCredentials))); } } CloseContext(); this.isCompleted = true; if (!this.isServer && (statusCode == (int)SecurityStatus.TargetUnknown || statusCode == (int)SecurityStatus.WrongPrincipal)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.IncorrectSpnOrUpnSpecified, this.servicePrincipalName))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidSspiNegotiation))); } } if (DiagnosticUtility.ShouldTraceInformation) { if (this.isServer) { SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this); } else { SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this); } } if (statusCode == (int)SecurityStatus.OK) { // we're done this.isCompleted = true; // These must all be true to check service binding // 1. we are the service (listener) // 2. caller is not anonymous // 3. protocol is not Kerberos // 4. policy is set to check service binding // if (isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == 0) && (string.Compare(this.ProtocolName, NegotiationInfoClass.Kerberos, StringComparison.OrdinalIgnoreCase) != 0) && policyHelper.ShouldCheckServiceBinding) { // in the server case the servicePrincipalName is the defaultServiceBinding if (DiagnosticUtility.ShouldTraceInformation) { string serviceBindingNameSentByClient; SspiWrapper.QuerySpecifiedTarget(securityContext, out serviceBindingNameSentByClient); IMD.SecurityTraceRecordHelper.TraceServiceNameBindingOnServer(serviceBindingNameSentByClient, this.servicePrincipalName, policyHelper.ServiceNameCollection); } policyHelper.CheckServiceBinding(this.securityContext, this.servicePrincipalName); } } else { // we need to continue } return(outSecurityBuffer.token); }
internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy) { if (!this.isAuthenticated) { bool flag = false; SafeDeleteContext refContext = null; SafeCloseHandle token = null; byte[] request = this.request; try { if (credentialsHandle == null) { credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound, new string[0]); flag = true; } SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect; ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy); if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SecurityChannelBindingMissing"))); } if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy) { inFlags |= SspiContextFlags.ChannelBindingProxyBindings; } SspiContextFlags zero = SspiContextFlags.Zero; SecurityBuffer outputBuffer = new SecurityBuffer(0, BufferType.Token); List <SecurityBuffer> list = new List <SecurityBuffer>(2) { new SecurityBuffer(request, 2) }; if (helper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } SecurityBuffer[] inputBuffers = null; if (list.Count > 0) { inputBuffers = list.ToArray(); } int error = SspiWrapper.AcceptSecurityContext(credentialsHandle, ref refContext, inFlags, Endianness.Native, inputBuffers, outputBuffer, ref zero); switch (error) { case 0: break; case 0x90312: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error))); case -2146893056: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosApReqInvalidOrOutOfMemory"), new Win32Exception(error))); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailAcceptSecurityContext"), new Win32Exception(error))); } LifeSpan span = (LifeSpan)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.Lifespan); DateTime effectiveTimeUtc = span.EffectiveTimeUtc; DateTime expiryTimeUtc = span.ExpiryTimeUtc; SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.SessionKey); this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey); error = SspiWrapper.QuerySecurityContextToken(refContext, out token); if (error != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } System.Security.Principal.WindowsIdentity windowsIdentity = new System.Security.Principal.WindowsIdentity(token.DangerousGetHandle(), "Kerberos"); base.Initialize(this.id, "Kerberos", effectiveTimeUtc, expiryTimeUtc, windowsIdentity, false); this.isAuthenticated = true; } finally { if (token != null) { token.Close(); } if (refContext != null) { refContext.Close(); } if (flag && (credentialsHandle != null)) { credentialsHandle.Close(); } } } }
private void AcquireClientCredentials() { SecureCredential scc = new SecureCredential(4, this.ClientCertificate, SecureCredential.Flags.NoDefaultCred | SecureCredential.Flags.ValidateManual, this.protocolFlags); this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Microsoft Unified Security Protocol Provider", CredentialUse.Outbound, scc); }
/// <summary> /// Generate SSPI context /// </summary> /// <param name="sspiClientContextStatus">SSPI client context status</param> /// <param name="receivedBuff">Receive buffer</param> /// <param name="sendBuff">Send buffer</param> /// <param name="serverName">Service Principal Name buffer</param> /// <returns>SNI error code</returns> internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName) { SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext; ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags; SafeFreeCredentials credentialsHandle = sspiClientContextStatus.CredentialsHandle; string securityPackage = NegotiationInfoClass.Negotiate; if (securityContext == null) { credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(securityPackage, false); } SecurityBuffer[] inSecurityBufferArray; if (receivedBuff != null) { inSecurityBufferArray = new SecurityBuffer[] { new SecurityBuffer(receivedBuff, SecurityBufferType.SECBUFFER_TOKEN) }; } else { inSecurityBufferArray = Array.Empty <SecurityBuffer>(); } int tokenSize = NegotiateStreamPal.QueryMaxTokenSize(securityPackage); SecurityBuffer outSecurityBuffer = new SecurityBuffer(tokenSize, SecurityBufferType.SECBUFFER_TOKEN); ContextFlagsPal requestedContextFlags = ContextFlagsPal.Connection | ContextFlagsPal.Confidentiality | ContextFlagsPal.Delegate | ContextFlagsPal.MutualAuth; string[] serverSPNs = new string[serverName.Length]; for (int i = 0; i < serverName.Length; i++) { serverSPNs[i] = Encoding.UTF8.GetString(serverName[i]); } SecurityStatusPal statusCode = NegotiateStreamPal.InitializeSecurityContext( credentialsHandle, ref securityContext, serverSPNs, requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref contextFlags); if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded || statusCode.ErrorCode == SecurityStatusPalErrorCode.CompAndContinue) { inSecurityBufferArray = new SecurityBuffer[] { outSecurityBuffer }; statusCode = NegotiateStreamPal.CompleteAuthToken(ref securityContext, inSecurityBufferArray); outSecurityBuffer.token = null; } sendBuff = outSecurityBuffer.token; if (sendBuff == null) { sendBuff = Array.Empty <byte>(); } sspiClientContextStatus.SecurityContext = securityContext; sspiClientContextStatus.ContextFlags = contextFlags; sspiClientContextStatus.CredentialsHandle = credentialsHandle; if (IsErrorStatus(statusCode.ErrorCode)) { // Could not access Kerberos Ticket. // // SecurityStatusPalErrorCode.InternalError only occurs in Unix and always comes with a GssApiException, // so we don't need to check for a GssApiException here. if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError) { throw new InvalidOperationException(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode); } else { throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + "\n" + statusCode); } } }
public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); }
internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled) : this(false, package, credentialsHandle, impersonationLevel, servicePrincipalName, doMutualAuth, interactiveLogonEnabled, ntlmEnabled) { }
internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, string defaultServiceBinding) : this(true, package, credentialsHandle, TokenImpersonationLevel.Delegation, defaultServiceBinding, false, false, true) { }
public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy) { this.ThrowIfDisposed(); int error = 0; SspiContextFlags inFlags = SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect; if (this.doMutualAuth) { inFlags |= SspiContextFlags.MutualAuth; } if (this.impersonationLevel == TokenImpersonationLevel.Delegation) { inFlags |= SspiContextFlags.Delegate; } else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Identification)) { inFlags |= SspiContextFlags.InitIdentify; } else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Anonymous)) { inFlags |= SspiContextFlags.InitAnonymous; } ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy); if (this.isServer) { if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.ServiceModel.SR.GetString("SecurityChannelBindingMissing"))); } if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy) { inFlags |= SspiContextFlags.ChannelBindingProxyBindings; } } List <SecurityBuffer> list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, BufferType.Token)); } if (this.isServer) { if (helper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } } else if (helper.ChannelBinding != null) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } SecurityBuffer[] inputBuffers = null; if (list.Count > 0) { inputBuffers = list.ToArray(); } SecurityBuffer outputBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token); if (!this.isServer) { error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); } else { bool flag = this.securityContext == null; SspiContextFlags contextFlags = this.contextFlags; error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); if ((error == -2146893048) && !flag) { this.contextFlags = contextFlags; this.CloseContext(); error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); } } if ((error & -2147483648) != 0) { if (((!this.isServer && this.interactiveNegoLogonEnabled) && (System.ServiceModel.Security.SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint)error))) && SspiWrapper.IsNegotiateExPackagePresent()) { if (this.MaxPromptAttempts >= 1) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidClientCredentials"))); } IntPtr zero = IntPtr.Zero; uint num2 = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out zero, ref this.saveClientCredentialsOnSspiUi); if (num2 == 0) { IntPtr ppNewAuthIdentity = IntPtr.Zero; if (!this.allowNtlm) { UnsafeNativeMethods.SspiExcludePackage(zero, "NTLM", out ppNewAuthIdentity); } else { ppNewAuthIdentity = zero; } this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity); if (IntPtr.Zero != ppNewAuthIdentity) { UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity); } this.CloseContext(); this.MaxPromptAttempts++; return(this.GetOutgoingBlob(null, channelbinding, protectionPolicy)); } if (IntPtr.Zero != zero) { UnsafeNativeMethods.SspiFreeAuthIdentity(zero); } this.CloseContext(); this.isCompleted = true; throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)num2, System.ServiceModel.SR.GetString("SspiErrorOrInvalidClientCredentials"))); } this.CloseContext(); this.isCompleted = true; if (this.isServer || (((error != -2146893042) && (error != -2146893053)) && (error != -2146893022))) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidSspiNegotiation"))); } throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("IncorrectSpnOrUpnSpecified", new object[] { this.servicePrincipalName }))); } if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation) { if (this.isServer) { SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this); } else { SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this); } } if (error == 0) { this.isCompleted = true; if ((this.isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == SspiContextFlags.Zero)) && ((string.Compare(this.ProtocolName, "Kerberos", StringComparison.OrdinalIgnoreCase) != 0) && helper.ShouldCheckServiceBinding)) { helper.CheckServiceBinding(this.securityContext, this.servicePrincipalName); } } return(outputBuffer.token); }
/// <summary> /// Client side ctor /// </summary> internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled) : this(false, package, credentialsHandle, impersonationLevel, servicePrincipalName, doMutualAuth, interactiveLogonEnabled, ntlmEnabled) { }
public AcceleratedTokenProvider(SafeFreeCredentials credentialsHandle) { this.credentialsHandle = credentialsHandle; }
/// <summary> /// Server side ctor /// </summary> internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, string defaultServiceBinding) : this(true, package, credentialsHandle, TokenImpersonationLevel.Delegation, defaultServiceBinding, false, false, true) { }
void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding) { bool ownCredentialsHandle = false; SafeDeleteContext securityContext = null; try { if (credentialsHandle == null) { if (networkCredential == null || networkCredential == CredentialCache.DefaultNetworkCredentials) { credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Outbound); } else { AuthIdentityEx authIdentity = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain); credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", CredentialUse.Outbound, ref authIdentity); } ownCredentialsHandle = true; } SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.ReplayDetect | SspiContextFlags.SequenceDetect; // we only accept Identity or Impersonation (Impersonation is default). if (tokenImpersonationLevel == TokenImpersonationLevel.Identification) { fContextReq |= SspiContextFlags.InitIdentify; } SspiContextFlags contextFlags = SspiContextFlags.Zero; SecurityBuffer inSecurityBuffer = null; if (channelBinding != null) { inSecurityBuffer = new SecurityBuffer(channelBinding); } SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token); int statusCode = SspiWrapper.InitializeSecurityContext( credentialsHandle, ref securityContext, this.servicePrincipalName, fContextReq, Endianness.Native, inSecurityBuffer, outSecurityBuffer, ref contextFlags); if (DiagnosticUtility.ShouldTraceInformation) { SecurityTraceRecordHelper.TraceChannelBindingInformation(null, false, channelBinding); } if (statusCode != (int)SecurityStatus.OK) { if (statusCode == (int)SecurityStatus.ContinueNeeded) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.FailInitializeSecurityContext), new Win32Exception(statusCode))); } } #if REMOVEGSS // // ... and strip GSS-framing from it // int offset = 0; int len = outSecurityBuffer.token.Length; DEREncoding.VerifyTokenHeader(outSecurityBuffer.token, ref offset, ref len); this.apreq = SecurityUtils.CloneBuffer(outSecurityBuffer.token, offset, len); #else this.apreq = outSecurityBuffer.token; #endif // Expiration LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan); this.effectiveTime = lifeSpan.EffectiveTimeUtc; this.expirationTime = lifeSpan.ExpiryTimeUtc; // SessionKey SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey); this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey); } finally { if (securityContext != null) { securityContext.Close(); } if (ownCredentialsHandle && credentialsHandle != null) { credentialsHandle.Close(); } } }
private void AcquireServerCredentials() { SecureCredential scc = new SecureCredential(4, this.serverCertificate, SecureCredential.Flags.Zero, this.protocolFlags); this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Microsoft Unified Security Protocol Provider", CredentialUse.Inbound, scc); }
internal KerberosRequestorSecurityToken(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, string id, SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding) { if (servicePrincipalName == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("servicePrincipalName"); } if (tokenImpersonationLevel != TokenImpersonationLevel.Identification && tokenImpersonationLevel != TokenImpersonationLevel.Impersonation) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("tokenImpersonationLevel", SR.GetString(SR.ImpersonationLevelNotSupported, tokenImpersonationLevel))); } if (id == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("id"); } this.servicePrincipalName = servicePrincipalName; if (networkCredential != null && networkCredential != CredentialCache.DefaultNetworkCredentials) { if (string.IsNullOrEmpty(networkCredential.UserName)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.ProvidedNetworkCredentialsForKerberosHasInvalidUserName)); } // Note: we don't check the domain, since Lsa accepts // FQ userName. } this.id = id; try { Initialize(tokenImpersonationLevel, networkCredential, credentialsHandle, channelBinding); } catch (Win32Exception e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.UnableToCreateKerberosCredentials), e)); } catch (SecurityTokenException ste) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.UnableToCreateKerberosCredentials), ste)); } }
// This internal API is not thread-safe. It is acceptable since .. // 1) From public OM, Initialize happens at ctor time. // 2) From internal OM (Sfx), Initialize happens right after ctor (single thread env). // i.e. ReadToken and then AuthenticateToken. internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy) { if (this.isAuthenticated) { return; } bool ownCredentialsHandle = false; SafeDeleteContext securityContext = null; SafeCloseHandle tokenHandle = null; #if RECOMPUTEGSS int tokenSize = DEREncoding.TokenSize(this.request.Length); byte[] rawRequest = new byte[tokenSize]; int offset = 0; int len = this.request.Length; DEREncoding.MakeTokenHeader(this.request.Length, rawRequest, ref offset, ref len); System.Buffer.BlockCopy(this.request, 0, rawRequest, offset, this.request.Length); #else byte[] rawRequest = this.request; #endif try { if (credentialsHandle == null) { credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound); ownCredentialsHandle = true; } SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.Confidentiality | SspiContextFlags.ReplayDetect | SspiContextFlags.SequenceDetect; ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy); if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing))); } if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { fContextReq |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy) { fContextReq |= SspiContextFlags.ChannelBindingProxyBindings; } SspiContextFlags contextFlags = SspiContextFlags.Zero; SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token); List <SecurityBuffer> list = new List <SecurityBuffer>(2); list.Add(new SecurityBuffer(rawRequest, BufferType.Token)); if (policyHelper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(policyHelper.ChannelBinding)); } SecurityBuffer[] inSecurityBuffer = null; if (list.Count > 0) { inSecurityBuffer = list.ToArray(); } int statusCode = SspiWrapper.AcceptSecurityContext(credentialsHandle, ref securityContext, fContextReq, Endianness.Native, inSecurityBuffer, outSecurityBuffer, ref contextFlags); if (DiagnosticUtility.ShouldTraceInformation) { SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, true, channelBinding); } if (statusCode != (int)SecurityStatus.OK) { if (statusCode == (int)SecurityStatus.ContinueNeeded) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode))); } else if (statusCode == (int)SecurityStatus.OutOfMemory) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.KerberosApReqInvalidOrOutOfMemory), new Win32Exception(statusCode))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.FailAcceptSecurityContext), new Win32Exception(statusCode))); } } // Expiration LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan); DateTime effectiveTime = lifeSpan.EffectiveTimeUtc; DateTime expirationTime = lifeSpan.ExpiryTimeUtc; // SessionKey SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey); this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey); // WindowsSecurityToken statusCode = SspiWrapper.QuerySecurityContextToken(securityContext, out tokenHandle); if (statusCode != (int)SecurityStatus.OK) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode)); } WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeKerberos); Initialize(this.id, SecurityUtils.AuthTypeKerberos, effectiveTime, expirationTime, windowsIdentity, false); // Authenticated this.isAuthenticated = true; } finally { if (tokenHandle != null) { tokenHandle.Close(); } if (securityContext != null) { securityContext.Close(); } if (ownCredentialsHandle && credentialsHandle != null) { credentialsHandle.Close(); } } }
public SspiIssuanceChannelParameter(bool getTokenOnOpen, SafeFreeCredentials credentialsHandle) { this.getTokenOnOpen = getTokenOnOpen; this.credentialsHandle = credentialsHandle; }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired) { return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, true, remoteCertRequired); }
internal static int InitializeSecurityContext(SSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { if (NetEventSource.IsEnabled) NetEventSource.Log.InitializeSecurityContext(credential, context, targetName, inFlags); int errorCode = secModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffer, outputBuffer, ref outFlags); if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffer(nameof(InitializeSecurityContext), inputBuffer?.size ?? 0, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); return errorCode; }
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer) { Debug.Assert(inputBuffers.Length == 2); Debug.Assert(inputBuffers[1].token == null); return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, false, false); }
internal static int AcceptSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { if (NetEventSource.IsEnabled) NetEventSource.Log.AcceptSecurityContext(credential, context, inFlags); int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags); if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffers(nameof(AcceptSecurityContext), inputBuffers?.Length ?? 0, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); return errorCode; }
internal static int AcceptSecurityContext(SSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, Interop.Secur32.ContextFlags inFlags, Interop.Secur32.Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.Secur32.ContextFlags outFlags) { if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.AcceptSecurityContext(credential.ToString(), LoggingHash.ObjectToString(context), inFlags); } int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags); if (SecurityEventSource.Log.IsEnabled()) { SecurityEventSource.Log.SecurityContextInputBuffers("AcceptSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SecurityStatus)errorCode); } return errorCode; }
public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy) { ThrowIfDisposed(); int statusCode = 0; // use the confidentiality option to ensure we can encrypt messages SspiContextFlags requestedFlags = SspiContextFlags.Confidentiality | SspiContextFlags.ReplayDetect | SspiContextFlags.SequenceDetect; if (this.doMutualAuth) { requestedFlags |= SspiContextFlags.MutualAuth; } if (this.impersonationLevel == TokenImpersonationLevel.Delegation) { requestedFlags |= SspiContextFlags.Delegate; } else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Identification) { requestedFlags |= SspiContextFlags.InitIdentify; } else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Anonymous) { requestedFlags |= SspiContextFlags.InitAnonymous; } ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy); if (isServer) { if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing))); } if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { requestedFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy) { requestedFlags |= SspiContextFlags.ChannelBindingProxyBindings; } } List<SecurityBuffer> list = new List<SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, BufferType.Token)); } // when deciding if the channel binding should be added to the security buffer // it is necessary to differentiate between client and server. // Server rules were added to policyHelper as they are shared with Kerb and I want them consistent // Client adds if not null. if (this.isServer) { if (policyHelper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(policyHelper.ChannelBinding)); } } else { if (policyHelper.ChannelBinding != null) { list.Add(new SecurityBuffer(policyHelper.ChannelBinding)); } } SecurityBuffer[] inSecurityBuffer = null; if (list.Count > 0) { inSecurityBuffer = list.ToArray(); } SecurityBuffer outSecurityBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token); if (!this.isServer) { //client session statusCode = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); } else { // server session //This check is to save an unnecessary ASC call. bool isServerSecurityContextNull = this.securityContext == null; SspiContextFlags serverContextFlags = this.contextFlags; statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); if (statusCode == (int)SecurityStatus.InvalidToken && !isServerSecurityContextNull) { // Call again into ASC after deleting the Securitycontext. If this securitycontext is not deleted // then when the client sends NTLM blob the service will treat it as Nego2blob and will fail to authenticate the client. this.contextFlags = serverContextFlags; CloseContext(); statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); } } if (DiagnosticUtility.ShouldTraceInformation) { IMD.SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, this.isServer, channelbinding); } if ((statusCode & unchecked((int)0x80000000)) != 0) { if (!this.isServer && this.interactiveNegoLogonEnabled && SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint)statusCode) && SspiWrapper.IsNegotiateExPackagePresent()) { // If we have prompted enough number of times (DefaultMaxPromptAttempts) with wrong credentials, then we do not prompt again and throw. if (MaxPromptAttempts >= DefaultMaxPromptAttempts) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidClientCredentials))); } IntPtr ppAuthIdentity = IntPtr.Zero; uint errorCode = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out ppAuthIdentity, ref this.saveClientCredentialsOnSspiUi); if (errorCode == (uint)CredentialStatus.Success) { IntPtr ppNewAuthIdentity = IntPtr.Zero; if (!this.allowNtlm) { // When Ntlm is explicitly disabled we don't want the collected //creds from the Kerb/NTLM tile to be used for NTLM auth. uint status = UnsafeNativeMethods.SspiExcludePackage(ppAuthIdentity, "NTLM", out ppNewAuthIdentity); } else { ppNewAuthIdentity = ppAuthIdentity; } this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity); if (IntPtr.Zero != ppNewAuthIdentity) { UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity); } CloseContext(); MaxPromptAttempts++; return this.GetOutgoingBlob(null, channelbinding, protectionPolicy); } else { // Call into SspiPromptForCredential had an error. Time to throw. if (IntPtr.Zero != ppAuthIdentity) { UnsafeNativeMethods.SspiFreeAuthIdentity(ppAuthIdentity); } CloseContext(); this.isCompleted = true; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)errorCode, SR.GetString(SR.SspiErrorOrInvalidClientCredentials))); } } CloseContext(); this.isCompleted = true; if (!this.isServer && (statusCode == (int)SecurityStatus.TargetUnknown || statusCode == (int)SecurityStatus.WrongPrincipal)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.IncorrectSpnOrUpnSpecified, this.servicePrincipalName))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidSspiNegotiation))); } } if (DiagnosticUtility.ShouldTraceInformation) { if (this.isServer) { SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this); } else { SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this); } } if (statusCode == (int)SecurityStatus.OK) { // we're done this.isCompleted = true; // These must all be true to check service binding // 1. we are the service (listener) // 2. caller is not anonymous // 3. protocol is not Kerberos // 4. policy is set to check service binding // if (isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == 0) && (string.Compare(this.ProtocolName, NegotiationInfoClass.Kerberos, StringComparison.OrdinalIgnoreCase) != 0) && policyHelper.ShouldCheckServiceBinding) { // in the server case the servicePrincipalName is the defaultServiceBinding if (DiagnosticUtility.ShouldTraceInformation) { string serviceBindingNameSentByClient; SspiWrapper.QuerySpecifiedTarget(securityContext, out serviceBindingNameSentByClient); IMD.SecurityTraceRecordHelper.TraceServiceNameBindingOnServer( serviceBindingNameSentByClient, this.servicePrincipalName, policyHelper.ServiceNameCollection); } policyHelper.CheckServiceBinding(this.securityContext, this.servicePrincipalName); } } else { // we need to continue } return outSecurityBuffer.token; }
public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SecureCredential authdata, out SafeFreeCredentials outCredential) { return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential); }
internal IssuedSecurityTokenProvider(SafeFreeCredentials credentialsHandle) { this.federatedTokenProvider = new CoreFederatedTokenProvider(credentialsHandle); this.messageSecurityVersion = System.ServiceModel.MessageSecurityVersion.Default; }
public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags) { return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); }
private void AcquireDummyCredentials() { SecureCredential secureCredential = new SecureCredential(SecureCredential.CurrentVersion, null, SecureCredential.Flags.ValidateManual | SecureCredential.Flags.NoDefaultCred, this.protocolFlags); this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(SecurityPackage, CredentialUse.Outbound, secureCredential); }