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); } }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 0) && (inSecurityBufferArray[0].type == SecurityBufferType.ChannelBindings)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } return(EstablishSecurityContext( (SafeFreeNegoCredentials)credentialsHandle, ref securityContext, false, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags)); }
internal static SecurityStatusPal InitializeSecurityContext( ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext?securityContext, string?spn, ContextFlagsPal requestedContextFlags, ReadOnlySpan <byte> incomingBlob, ChannelBinding?channelBinding, ref byte[]?resultBlob, out int resultBlobLength, ref ContextFlagsPal contextFlags) { SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } SecurityStatusPal status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, channelBinding, spn, requestedContextFlags, incomingBlob, out resultBlob, ref contextFlags); resultBlobLength = resultBlob?.Length ?? 0; return(status); }
/// <summary> /// Generate SSPI context /// </summary> /// <param name="handle">SNI connection handle</param> /// <param name="receivedBuff">Receive buffer</param> /// <param name="receivedLength">Received length</param> /// <param name="sendBuff">Send buffer</param> /// <param name="sendLength">Send length</param> /// <param name="serverName">Service Principal Name buffer</param> /// <param name="serverNameLength">Length of Service Principal Name</param> /// <returns>SNI error code</returns> public void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[] serverName) { SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext; ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags; SafeFreeCredentials credentialsHandle = sspiClientContextStatus.CredentialsHandle; SecurityBuffer[] inSecurityBufferArray = null; if (securityContext == null) //first iteration { credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(Kerberos, false); } else { inSecurityBufferArray = new SecurityBuffer[] { new SecurityBuffer(receivedBuff, SecurityBufferType.SECBUFFER_TOKEN) }; } int tokenSize = NegotiateStreamPal.QueryMaxTokenSize(Kerberos); SecurityBuffer outSecurityBuffer = new SecurityBuffer(tokenSize, SecurityBufferType.SECBUFFER_TOKEN); ContextFlagsPal requestedContextFlags = ContextFlagsPal.Connection | ContextFlagsPal.Confidentiality | ContextFlagsPal.MutualAuth; string serverSPN = System.Text.Encoding.UTF8.GetString(serverName); SecurityStatusPal statusCode = NegotiateStreamPal.InitializeSecurityContext( credentialsHandle, ref securityContext, serverSPN, requestedContextFlags, inSecurityBufferArray, outSecurityBuffer, ref contextFlags); if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded || statusCode.ErrorCode == SecurityStatusPalErrorCode.CompAndContinue) { inSecurityBufferArray = new SecurityBuffer[] { outSecurityBuffer }; statusCode = NegotiateStreamPal.CompleteAuthToken(ref securityContext, inSecurityBufferArray); } sendBuff = outSecurityBuffer.token; sspiClientContextStatus.SecurityContext = securityContext; sspiClientContextStatus.ContextFlags = contextFlags; sspiClientContextStatus.CredentialsHandle = credentialsHandle; if (IsErrorStatus(statusCode.ErrorCode)) { if (statusCode.ErrorCode == SecurityStatusPalErrorCode.InternalError && statusCode.Exception is Interop.NetSecurityNative.GssApiException) // when unable to access Kerberos Ticket { throw new Exception(SQLMessage.KerberosTicketMissingError() + "\n" + statusCode); } else { throw new Exception(SQLMessage.SSPIGenerateError() + "\n" + statusCode); } } }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } return(EstablishSecurityContext( negoCredentialsHandle, ref securityContext, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags)); }
internal static ContextFlagsPal GetContextFlagsPalFromInterop(Interop.NetSecurityNative.GssFlags gssFlags, bool isServer) { ContextFlagsPal flags = ContextFlagsPal.None; // GSS_C_IDENTIFY_FLAG is handled separately as its value can either be AcceptIdentify (used by server) or InitIdentify (used by client) if ((gssFlags & Interop.NetSecurityNative.GssFlags.GSS_C_IDENTIFY_FLAG) != 0) { flags |= isServer ? ContextFlagsPal.AcceptIdentify : ContextFlagsPal.InitIdentify; } foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((gssFlags & mapping.GssFlags) == mapping.GssFlags) { flags |= mapping.ContextFlag; } } // GSS_C_INTEG_FLAG is handled separately as its value can either be AcceptIntegrity (used by server) or InitIntegrity (used by client) if ((gssFlags & Interop.NetSecurityNative.GssFlags.GSS_C_INTEG_FLAG) != 0) { flags |= isServer ? ContextFlagsPal.AcceptIntegrity : ContextFlagsPal.InitIntegrity; } foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((gssFlags & mapping.GssFlags) == mapping.GssFlags) { flags |= mapping.ContextFlag; } } return(flags); }
internal static Interop.NetSecurityNative.GssFlags GetInteropFromContextFlagsPal(ContextFlagsPal flags, bool isServer) { Interop.NetSecurityNative.GssFlags gssFlags = 0; // GSS_C_INTEG_FLAG is set if either AcceptIntegrity (used by server) or InitIntegrity (used by client) is set if (isServer) { if ((flags & ContextFlagsPal.AcceptIntegrity) != 0) { gssFlags |= Interop.NetSecurityNative.GssFlags.GSS_C_INTEG_FLAG; } } else { if ((flags & ContextFlagsPal.InitIntegrity) != 0) { gssFlags |= Interop.NetSecurityNative.GssFlags.GSS_C_INTEG_FLAG; } } foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((flags & mapping.ContextFlag) == mapping.ContextFlag) { gssFlags |= mapping.GssFlags; } } return gssFlags; }
internal static SecurityStatusPal InitializeSecurityContext( ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, byte[] incomingBlob, ChannelBinding channelBinding, ref byte[] resultBlob, ref ContextFlagsPal contextFlags) { #if netstandard Span <SecurityBuffer> inSecurityBufferSpan = new SecurityBuffer[2]; #else TwoSecurityBuffers twoSecurityBuffers = default; Span <SecurityBuffer> inSecurityBufferSpan = MemoryMarshal.CreateSpan(ref twoSecurityBuffers._item0, 2); #endif int inSecurityBufferSpanLength = 0; if (incomingBlob != null && channelBinding != null) { inSecurityBufferSpan[0] = new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN); inSecurityBufferSpan[1] = new SecurityBuffer(channelBinding); inSecurityBufferSpanLength = 2; } else if (incomingBlob != null) { inSecurityBufferSpan[0] = new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN); inSecurityBufferSpanLength = 1; } else if (channelBinding != null) { inSecurityBufferSpan[0] = new SecurityBuffer(channelBinding); inSecurityBufferSpanLength = 1; } inSecurityBufferSpan = inSecurityBufferSpan.Slice(0, inSecurityBufferSpanLength); var outSecurityBuffer = new SecurityBuffer(resultBlob, SecurityBufferType.SECBUFFER_TOKEN); Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; // There is only one SafeDeleteContext type on Windows which is SafeDeleteSslContext so this cast is safe. SafeDeleteSslContext sslContext = (SafeDeleteSslContext)securityContext; Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, ref credentialsHandle, ref sslContext, spn, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inSecurityBufferSpan, ref outSecurityBuffer, ref outContextFlags); securityContext = sslContext; resultBlob = outSecurityBuffer.token; contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
/// <summary> /// Initializes a new instance of the <see cref="NegotiateAuthentication"/> /// for client-side authentication session. /// </summary> /// <param name="clientOptions">The property bag for the authentication options.</param> public NegotiateAuthentication(NegotiateAuthenticationClientOptions clientOptions) { ArgumentNullException.ThrowIfNull(clientOptions); ContextFlagsPal contextFlags = clientOptions.RequiredProtectionLevel switch { ProtectionLevel.Sign => ContextFlagsPal.InitIntegrity, ProtectionLevel.EncryptAndSign => ContextFlagsPal.InitIntegrity | ContextFlagsPal.Confidentiality, _ => 0 } | ContextFlagsPal.Connection;
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { throw new PlatformNotSupportedException(SR.net_nego_server_not_supported); }
internal InitializeCallbackContext(NTAuthentication thisPtr, bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { ThisPtr = thisPtr; IsServer = isServer; Package = package; Credential = credential; Spn = spn; RequestedContextFlags = requestedContextFlags; ChannelBinding = channelBinding; }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string[] spns, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(Strings.net_nego_channel_binding_not_supported); } SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; SecurityStatusPal status = default; foreach (string spn in spns) { if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(Strings.net_nego_not_supported_empty_target_with_defaultcreds); } status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags); if (status.ErrorCode != SecurityStatusPalErrorCode.InternalError) { break; // Successful case, exit the loop with current SPN. } else { securityContext = null; // Reset security context to be generated again for next SPN. } } // Confidentiality flag should not be set if not requested if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { ContextFlagsPal mask = ContextFlagsPal.Confidentiality; if ((requestedContextFlags & mask) != (contextFlags & mask)) { throw new PlatformNotSupportedException(Strings.net_nego_protection_level_not_supported); } } return(status); }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials?credentialsHandle, ref SafeDeleteContext?securityContext, ContextFlagsPal requestedContextFlags, byte[]?incomingBlob, ChannelBinding?channelBinding, ref byte[] resultBlob, ref ContextFlagsPal contextFlags) { throw new PlatformNotSupportedException(); }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, ContextFlagsPal requestedContextFlags, byte[] incomingBlob, ChannelBinding channelBinding, ref byte[] resultBlob, ref ContextFlagsPal contextFlags) { throw new PlatformNotSupportedException(SR.net_nego_server_not_supported); }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials?credentialsHandle, ref SafeDeleteContext?securityContext, ContextFlagsPal requestedContextFlags, ReadOnlySpan <byte> incomingBlob, ChannelBinding?channelBinding, ref byte[]?resultBlob, out int resultBlobLength, ref ContextFlagsPal contextFlags) { InputSecurityBuffers inputBuffers = default; if (!incomingBlob.IsEmpty) { inputBuffers.SetNextBuffer(new InputSecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN)); } if (channelBinding != null) { inputBuffers.SetNextBuffer(new InputSecurityBuffer(channelBinding)); } var outSecurityBuffer = new SecurityBuffer(resultBlob, SecurityBufferType.SECBUFFER_TOKEN); Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; // There is only one SafeDeleteContext type on Windows which is SafeDeleteSslContext so this cast is safe. SafeDeleteSslContext?sslContext = (SafeDeleteSslContext?)securityContext; Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref sslContext, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inputBuffers, ref outSecurityBuffer, ref outContextFlags); // SSPI Workaround // If a client sends up a blob on the initial request, Negotiate returns SEC_E_INVALID_HANDLE // when it should return SEC_E_INVALID_TOKEN. if (winStatus == Interop.SECURITY_STATUS.InvalidHandle && securityContext == null && !incomingBlob.IsEmpty) { winStatus = Interop.SECURITY_STATUS.InvalidToken; } Debug.Assert(outSecurityBuffer.offset == 0); resultBlob = outSecurityBuffer.token; resultBlobLength = outSecurityBuffer.size; securityContext = sslContext; contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, ContextFlagsPal requestedContextFlags, byte[] incomingBlob, ChannelBinding channelBinding, ref byte[] resultBlob, ref ContextFlagsPal contextFlags) { if (securityContext == null) { securityContext = new SafeDeleteNegoContext((SafeFreeNegoCredentials)credentialsHandle); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)securityContext; try { SafeGssContextHandle contextHandle = negoContext.GssContext; bool done = GssAcceptSecurityContext( ref contextHandle, incomingBlob, out resultBlob, out uint outputFlags); Debug.Assert(resultBlob != null, "Unexpected null buffer returned by GssApi"); Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle); } contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop( (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: true); SecurityStatusPalErrorCode errorCode = done ? (negoContext.IsNtlmUsed && resultBlob.Length > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) : SecurityStatusPalErrorCode.ContinueNeeded; return(new SecurityStatusPal(errorCode)); } catch (Exception ex) { if (NetEventSource.IsEnabled) { NetEventSource.Error(null, ex); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex)); } }
internal static Interop.SspiCli.ContextFlags GetInteropFromContextFlagsPal(ContextFlagsPal flags) { Interop.SspiCli.ContextFlags win32Flags = Interop.SspiCli.ContextFlags.Zero; foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((flags & mapping.ContextFlag) == mapping.ContextFlag) { win32Flags |= mapping.Win32Flag; } } return(win32Flags); }
internal static Interop.NetSecurityNative.GssFlags GetInteropFromContextFlagsPal(ContextFlagsPal flags) { Interop.NetSecurityNative.GssFlags gssFlags = 0; foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((flags & mapping.ContextFlag) == mapping.ContextFlag) { gssFlags |= mapping.GssFlags; } } return gssFlags; }
internal static Interop.SspiCli.ContextFlags GetInteropFromContextFlagsPal(ContextFlagsPal flags) { Interop.SspiCli.ContextFlags win32Flags = Interop.SspiCli.ContextFlags.Zero; foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((flags & mapping.ContextFlag) == mapping.ContextFlag) { win32Flags |= mapping.Win32Flag; } } return win32Flags; }
internal static ContextFlagsPal GetContextFlagsPalFromInterop(Interop.SspiCli.ContextFlags win32Flags) { ContextFlagsPal flags = ContextFlagsPal.None; foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((win32Flags & mapping.Win32Flag) == mapping.Win32Flag) { flags |= mapping.ContextFlag; } } return(flags); }
internal static ContextFlagsPal GetContextFlagsPalFromInterop(Interop.NetSecurityNative.GssFlags gssFlags) { ContextFlagsPal flags = ContextFlagsPal.None; foreach (ContextFlagMapping mapping in s_contextFlagMapping) { if ((gssFlags & mapping.GssFlags) == mapping.GssFlags) { flags |= mapping.ContextFlag; } } return(flags); }
internal static SecurityStatusPal InitializeSecurityContext( ref SafeFreeCredentials?credentialsHandle, ref SafeDeleteContext?securityContext, string?spn, ContextFlagsPal requestedContextFlags, ReadOnlySpan <byte> incomingBlob, ChannelBinding?channelBinding, ref byte[]?resultBlob, out int resultBlobLength, ref ContextFlagsPal contextFlags) { InputSecurityBuffers inputBuffers = default; if (!incomingBlob.IsEmpty) { inputBuffers.SetNextBuffer(new InputSecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN)); } if (channelBinding != null) { inputBuffers.SetNextBuffer(new InputSecurityBuffer(channelBinding)); } var outSecurityBuffer = new SecurityBuffer(resultBlob, SecurityBufferType.SECBUFFER_TOKEN); Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; // There is only one SafeDeleteContext type on Windows which is SafeDeleteSslContext so this cast is safe. SafeDeleteSslContext?sslContext = (SafeDeleteSslContext?)securityContext; Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, ref credentialsHandle, ref sslContext, spn, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inputBuffers, ref outSecurityBuffer, ref outContextFlags); securityContext = sslContext; Debug.Assert(outSecurityBuffer.offset == 0); resultBlob = outSecurityBuffer.token; resultBlobLength = outSecurityBuffer.size; contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } SecurityBuffer cbtBuffer = null; if ((inSecurityBufferArray != null) && (inSecurityBufferArray.Length > 1)) { Debug.Assert(inSecurityBufferArray[1].type == SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS); cbtBuffer = inSecurityBufferArray[1]; } SecurityStatusPal status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, cbtBuffer, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags); // Confidentiality flag should not be set if not requested if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { ContextFlagsPal mask = ContextFlagsPal.Confidentiality; if ((requestedContextFlags & mask) != (contextFlags & mask)) { throw new PlatformNotSupportedException(SR.net_nego_protection_level_not_supported); } } return(status); }
/// <summary> /// Initializes a new instance of the <see cref="NegotiateAuthentication"/> /// for client-side authentication session. /// </summary> /// <param name="clientOptions">The property bag for the authentication options.</param> public NegotiateAuthentication(NegotiateAuthenticationClientOptions clientOptions) { ArgumentNullException.ThrowIfNull(clientOptions); ContextFlagsPal contextFlags = ContextFlagsPal.Connection; contextFlags |= clientOptions.RequiredProtectionLevel switch { ProtectionLevel.Sign => ContextFlagsPal.InitIntegrity, ProtectionLevel.EncryptAndSign => ContextFlagsPal.InitIntegrity | ContextFlagsPal.Confidentiality, _ => 0 }; contextFlags |= clientOptions.RequireMutualAuthentication ? ContextFlagsPal.MutualAuth : 0; contextFlags |= clientOptions.AllowedImpersonationLevel switch { TokenImpersonationLevel.Identification => ContextFlagsPal.InitIdentify, TokenImpersonationLevel.Delegation => ContextFlagsPal.Delegate, _ => 0 }; _isServer = false; _requestedPackage = clientOptions.Package; _requiredImpersonationLevel = TokenImpersonationLevel.None; _requiredProtectionLevel = clientOptions.RequiredProtectionLevel; try { _ntAuthentication = new NTAuthentication( isServer: false, clientOptions.Package, clientOptions.Credential, clientOptions.TargetName, contextFlags, clientOptions.Binding); } catch (PlatformNotSupportedException) // Managed implementation, Unix { } catch (NotSupportedException) // Windows implementation { } catch (Win32Exception) // Unix implementation in native layer { } }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials?credentialsHandle, ref SafeDeleteContext?securityContext, ContextFlagsPal requestedContextFlags, byte[]?incomingBlob, ChannelBinding?channelBinding, ref byte[]?resultBlob, ref ContextFlagsPal contextFlags) { InputSecurityBuffers inputBuffers = default; if (incomingBlob != null) { inputBuffers.SetNextBuffer(new InputSecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN)); } if (channelBinding != null) { inputBuffers.SetNextBuffer(new InputSecurityBuffer(channelBinding)); } var outSecurityBuffer = new SecurityBuffer(resultBlob, SecurityBufferType.SECBUFFER_TOKEN); Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; // There is only one SafeDeleteContext type on Windows which is SafeDeleteSslContext so this cast is safe. SafeDeleteSslContext?sslContext = (SafeDeleteSslContext?)securityContext; Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref sslContext, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inputBuffers, ref outSecurityBuffer, ref outContextFlags); resultBlob = outSecurityBuffer.token; securityContext = sslContext; contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
internal static SecurityStatusPal InitializeSecurityContext( ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext?securityContext, string?spn, ContextFlagsPal requestedContextFlags, byte[]?incomingBlob, ChannelBinding?channelBinding, ref byte[]?resultBlob, ref ContextFlagsPal contextFlags) { SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials)credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } SecurityStatusPal status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, channelBinding, spn, requestedContextFlags, incomingBlob, ref resultBlob, ref contextFlags); // Confidentiality flag should not be set if not requested if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { ContextFlagsPal mask = ContextFlagsPal.Confidentiality; if ((requestedContextFlags & mask) != (contextFlags & mask)) { throw new PlatformNotSupportedException(SR.net_nego_protection_level_not_supported); } } return(status); }
private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor() package:" + LoggingHash.ObjectToString(package) + " spn:" + LoggingHash.ObjectToString(spn) + " flags :" + requestedContextFlags.ToString()); } _tokenSize = NegotiateStreamPal.QueryMaxTokenSize(package); _isServer = isServer; _spn = spn; _securityContext = null; _requestedContextFlags = requestedContextFlags; _package = package; _channelBinding = channelBinding; if (GlobalLog.IsEnabled) { GlobalLog.Print("Peer SPN-> '" + _spn + "'"); } // // Check if we're using DefaultCredentials. // Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials); if (credential == CredentialCache.DefaultCredentials) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor(): using DefaultCredentials"); } _credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(package, _isServer); } else { _credentialsHandle = NegotiateStreamPal.AcquireCredentialsHandle(package, _isServer, credential); } }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref securityContext, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inSecurityBufferArray, outSecurityBuffer, ref outContextFlags); contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
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); } }
internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string?spn, ContextFlagsPal requestedContextFlags, ChannelBinding?channelBinding) { if (isServer) { throw new PlatformNotSupportedException(SR.net_nego_server_not_supported); } if (package.Equals("NTLM", StringComparison.OrdinalIgnoreCase)) { _isSpNego = false; } else if (package.Equals("Negotiate", StringComparison.OrdinalIgnoreCase)) { _isSpNego = true; } else { throw new PlatformNotSupportedException(SR.net_securitypackagesupport); } if (string.IsNullOrWhiteSpace(credential.UserName) || string.IsNullOrWhiteSpace(credential.Password)) { // NTLM authentication is not possible with default credentials which are no-op throw new PlatformNotSupportedException(SR.net_ntlm_not_possible_default_cred); } if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"package={package}, spn={spn}, requestedContextFlags={requestedContextFlags}"); } _credential = credential; _spn = spn; _channelBinding = channelBinding; _contextFlags = requestedContextFlags; IsServer = isServer; }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref securityContext, spn, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref outContextFlags); contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus)); }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref securityContext, spn, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inSecurityBufferArray, outSecurityBuffer, ref outContextFlags); contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus); }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref securityContext, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), Interop.SspiCli.Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref outContextFlags); contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags); return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus); }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext context, bool isNtlm, string targetName, ContextFlagsPal inFlags, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlagsPal outFlags) { Debug.Assert(!isNtlm, "EstablishSecurityContext: NTLM is not yet supported"); if (context == null) { context = new SafeDeleteNegoContext(credential, targetName); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags); uint outputFlags; SafeGssContextHandle contextHandle = negoContext.GssContext; bool done = Interop.GssApi.EstablishSecurityContext( ref contextHandle, credential.GssCredential, isNtlm, negoContext.TargetName, inputFlags, inputBuffer?.token, out outputBuffer.token, out outputFlags); Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi"); outputBuffer.size = outputBuffer.token.Length; outputBuffer.offset = 0; outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle); } SecurityStatusPalErrorCode errorCode = done ? SecurityStatusPalErrorCode.CompleteNeeded : SecurityStatusPalErrorCode.ContinueNeeded; return new SecurityStatusPal(errorCode); } catch(Exception ex) { //TODO (Issue #5890): Print exception until issue is fixed Debug.Write("Exception Caught. - " + ex); if (GlobalLog.IsEnabled) { GlobalLog.Print("Exception Caught. - " + ex); } return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex); } }
internal InitializeCallbackContext(NTAuthentication thisPtr, bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { ThisPtr = thisPtr; IsServer = isServer; Package = package; Credential = credential; Spn = spn; RequestedContextFlags = requestedContextFlags; ChannelBinding = channelBinding; }
// // This overload does not attempt to impersonate because the caller either did it already or the original thread context is still preserved. // internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { Initialize(isServer, package, credential, spn, requestedContextFlags, channelBinding); }
public ContextFlagMapping(Interop.SspiCli.ContextFlags win32Flag, ContextFlagsPal contextFlag) { Win32Flag = win32Flag; ContextFlag = contextFlag; }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 0) && (inSecurityBufferArray[0].type == SecurityBufferType.ChannelBindings)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } return EstablishSecurityContext( (SafeFreeNegoCredentials)credentialsHandle, ref securityContext, false, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags); }
public ContextFlagMapping(Interop.NetSecurityNative.GssFlags gssFlag, ContextFlagsPal contextFlag) { GssFlags = gssFlag; ContextFlag = contextFlag; }
private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor() package:" + LoggingHash.ObjectToString(package) + " spn:" + LoggingHash.ObjectToString(spn) + " flags :" + requestedContextFlags.ToString()); } _tokenSize = NegotiateStreamPal.QueryMaxTokenSize(package); _isServer = isServer; _spn = spn; _securityContext = null; _requestedContextFlags = requestedContextFlags; _package = package; _channelBinding = channelBinding; if (GlobalLog.IsEnabled) { GlobalLog.Print("Peer SPN-> '" + _spn + "'"); } // // Check if we're using DefaultCredentials. // Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials); if (credential == CredentialCache.DefaultCredentials) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor(): using DefaultCredentials"); } _credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(package, _isServer); } else { _credentialsHandle = NegotiateStreamPal.AcquireCredentialsHandle(package, _isServer, credential); } }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials) credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } return EstablishSecurityContext( negoCredentialsHandle, ref securityContext, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags); }
// // This overload does not attempt to impersonate because the caller either did it already or the original thread context is still preserved. // internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { Initialize(isServer, package, credential, spn, requestedContextFlags, channelBinding); }
internal static SecurityStatusPal InitializeSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, string spn, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { // TODO (Issue #3718): The second buffer can contain a channel binding which is not supported if ((null != inSecurityBufferArray) && (inSecurityBufferArray.Length > 1)) { throw new PlatformNotSupportedException(SR.net_nego_channel_binding_not_supported); } SafeFreeNegoCredentials negoCredentialsHandle = (SafeFreeNegoCredentials) credentialsHandle; if (negoCredentialsHandle.IsDefault && string.IsNullOrEmpty(spn)) { throw new PlatformNotSupportedException(SR.net_nego_not_supported_empty_target_with_defaultcreds); } SecurityStatusPal status = EstablishSecurityContext( negoCredentialsHandle, ref securityContext, spn, requestedContextFlags, ((inSecurityBufferArray != null && inSecurityBufferArray.Length != 0) ? inSecurityBufferArray[0] : null), outSecurityBuffer, ref contextFlags); // Confidentiality flag should not be set if not requested if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) { ContextFlagsPal mask = ContextFlagsPal.Confidentiality; if ((requestedContextFlags & mask) != (contextFlags & mask)) { throw new PlatformNotSupportedException(SR.net_nego_protection_level_not_supported); } } return status; }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext?context, ChannelBinding?channelBinding, string?targetName, ContextFlagsPal inFlags, byte[]?incomingBlob, ref byte[]?resultBuffer, ref ContextFlagsPal outFlags) { bool isNtlmOnly = credential.IsNtlmOnly; if (context == null) { if (NetEventSource.Log.IsEnabled()) { string protocol = isNtlmOnly ? "NTLM" : "SPNEGO"; NetEventSource.Info(context, $"requested protocol = {protocol}, target = {targetName}"); } context = new SafeDeleteNegoContext(credential, targetName !); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false); uint outputFlags; bool isNtlmUsed; SafeGssContextHandle?contextHandle = negoContext.GssContext; bool done = GssInitSecurityContext( ref contextHandle, credential.GssCredential, isNtlmOnly, channelBinding, negoContext.TargetName, inputFlags, incomingBlob, out resultBuffer, out outputFlags, out isNtlmUsed); if (done) { if (NetEventSource.Log.IsEnabled()) { string protocol = isNtlmOnly ? "NTLM" : isNtlmUsed ? "SPNEGO-NTLM" : "SPNEGO-Kerberos"; NetEventSource.Info(context, $"actual protocol = {protocol}"); } // Populate protocol used for authentication negoContext.SetAuthenticationPackage(isNtlmUsed); } Debug.Assert(resultBuffer != null, "Unexpected null buffer returned by GssApi"); outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop( (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false); Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle !); } SecurityStatusPalErrorCode errorCode = done ? (negoContext.IsNtlmUsed && resultBuffer.Length > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) : SecurityStatusPalErrorCode.ContinueNeeded; return(new SecurityStatusPal(errorCode)); } catch (Exception ex) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(null, ex); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex)); } }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials credentialsHandle, ref SafeDeleteContext securityContext, ContextFlagsPal requestedContextFlags, SecurityBuffer[] inSecurityBufferArray, SecurityBuffer outSecurityBuffer, ref ContextFlagsPal contextFlags) { throw new PlatformNotSupportedException(SR.net_nego_server_not_supported); }
internal static SecurityStatusPal AcceptSecurityContext( SafeFreeCredentials?credentialsHandle, ref SafeDeleteContext?securityContext, ContextFlagsPal requestedContextFlags, byte[]?incomingBlob, ChannelBinding?channelBinding, ref byte[] resultBlob, ref ContextFlagsPal contextFlags) { if (securityContext == null) { securityContext = new SafeDeleteNegoContext((SafeFreeNegoCredentials)credentialsHandle !); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)securityContext; try { SafeGssContextHandle?contextHandle = negoContext.GssContext; bool done = GssAcceptSecurityContext( ref contextHandle, negoContext.AcceptorCredential, incomingBlob, out resultBlob, out uint outputFlags, out bool isNtlmUsed); Debug.Assert(resultBlob != null, "Unexpected null buffer returned by GssApi"); Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle !); } contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop( (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: true); SecurityStatusPalErrorCode errorCode; if (done) { if (NetEventSource.Log.IsEnabled()) { string protocol = isNtlmUsed ? "SPNEGO-NTLM" : "SPNEGO-Kerberos"; NetEventSource.Info(securityContext, $"AcceptSecurityContext: actual protocol = {protocol}"); } negoContext.SetAuthenticationPackage(isNtlmUsed); errorCode = (isNtlmUsed && resultBlob.Length > 0) ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded; } else { errorCode = SecurityStatusPalErrorCode.ContinueNeeded; } return(new SecurityStatusPal(errorCode)); } catch (Interop.NetSecurityNative.GssApiException gex) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(null, gex); } return(new SecurityStatusPal(GetErrorCode(gex), gex)); } catch (Exception ex) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(null, ex); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex)); } }
private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlagsPal inFlags, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlagsPal outFlags) { bool isNtlmOnly = credential.IsNtlmOnly; if (context == null) { // Empty target name causes the failure on Linux, hence passing a non-empty string context = isNtlmOnly ? new SafeDeleteNegoContext(credential, credential.UserName) : new SafeDeleteNegoContext(credential, targetName); } SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context; try { Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer:false); uint outputFlags; int isNtlmUsed; SafeGssContextHandle contextHandle = negoContext.GssContext; bool done = GssInitSecurityContext( ref contextHandle, credential.GssCredential, isNtlmOnly, negoContext.TargetName, inputFlags, inputBuffer?.token, out outputBuffer.token, out outputFlags, out isNtlmUsed); Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi"); outputBuffer.size = outputBuffer.token.Length; outputBuffer.offset = 0; outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags, isServer:false); Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); // Save the inner context handle for further calls to NetSecurity Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext); if (null == negoContext.GssContext) { negoContext.SetGssContext(contextHandle); } // Populate protocol used for authentication if (done) { negoContext.SetAuthenticationPackage(Convert.ToBoolean(isNtlmUsed)); } SecurityStatusPalErrorCode errorCode = done ? (negoContext.IsNtlmUsed && outputBuffer.size > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) : SecurityStatusPalErrorCode.ContinueNeeded; return new SecurityStatusPal(errorCode); } catch(Exception ex) { if (NetEventSource.IsEnabled) NetEventSource.Error(null, ex); return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex); } }