void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding) { bool ownCredentialsHandle = false; SafeDeleteContext securityContext = null; try { if (credentialsHandle == null) { if (networkCredential == null || networkCredential == CredentialCache.DefaultNetworkCredentials) { credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Outbound); } else { AuthIdentityEx authIdentity = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain); credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", CredentialUse.Outbound, ref authIdentity); } ownCredentialsHandle = true; } SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.ReplayDetect | SspiContextFlags.SequenceDetect; // we only accept Identity or Impersonation (Impersonation is default). if (tokenImpersonationLevel == TokenImpersonationLevel.Identification) { fContextReq |= SspiContextFlags.InitIdentify; } SspiContextFlags contextFlags = SspiContextFlags.Zero; SecurityBuffer inSecurityBuffer = null; if (channelBinding != null) { inSecurityBuffer = new SecurityBuffer(channelBinding); } SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token); int statusCode = SspiWrapper.InitializeSecurityContext( credentialsHandle, ref securityContext, this.servicePrincipalName, fContextReq, Endianness.Native, inSecurityBuffer, outSecurityBuffer, ref contextFlags); if (DiagnosticUtility.ShouldTraceInformation) { SecurityTraceRecordHelper.TraceChannelBindingInformation(null, false, channelBinding); } if (statusCode != (int)SecurityStatus.OK) { if (statusCode == (int)SecurityStatus.ContinueNeeded) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.FailInitializeSecurityContext), new Win32Exception(statusCode))); } } #if REMOVEGSS // // ... and strip GSS-framing from it // int offset = 0; int len = outSecurityBuffer.token.Length; DEREncoding.VerifyTokenHeader(outSecurityBuffer.token, ref offset, ref len); this.apreq = SecurityUtils.CloneBuffer(outSecurityBuffer.token, offset, len); #else this.apreq = outSecurityBuffer.token; #endif // Expiration LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan); this.effectiveTime = lifeSpan.EffectiveTimeUtc; this.expirationTime = lifeSpan.ExpiryTimeUtc; // SessionKey SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey); this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey); } finally { if (securityContext != null) { securityContext.Close(); } if (ownCredentialsHandle && credentialsHandle != null) { credentialsHandle.Close(); } } }
internal 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)); } }
public SecurityBuffer(ChannelBinding channelBinding) { this.size = channelBinding.Size; this.type = BufferType.ChannelBindings; this.unmanagedToken = channelBinding; }
internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) { _instance = s_ntAuthentication.Invoke(new object[] { isServer, package, credential, spn, requestedContextFlags, channelBinding }); }
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; }
public virtual IAsyncResult BeginAuthenticateAsClient(NetworkCredential credential, ChannelBinding binding, string targetName, AsyncCallback asyncCallback, object asyncState) { return(BeginAuthenticateAsClient(credential, binding, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, asyncCallback, asyncState)); }
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) { // 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, channelBinding, negoContext.TargetName, inputFlags, incomingBlob, out resultBuffer, out outputFlags, out 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); } // Populate protocol used for authentication if (done) { negoContext.SetAuthenticationPackage(Convert.ToBoolean(isNtlmUsed)); } SecurityStatusPalErrorCode errorCode = done ? (negoContext.IsNtlmUsed && resultBuffer.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 void ValidateCreateContext(string package, bool isServer, NetworkCredential credential, string servicePrincipalName, ChannelBinding channelBinding, ProtectionLevel protectionLevel, TokenImpersonationLevel impersonationLevel) { if ((this._Exception != null) && !this._CanRetryAuthentication) { throw this._Exception; } if ((this._Context != null) && this._Context.IsValidContext) { throw new InvalidOperationException(SR.GetString("net_auth_reauth")); } if (credential == null) { throw new ArgumentNullException("credential"); } if (servicePrincipalName == null) { throw new ArgumentNullException("servicePrincipalName"); } if (ComNetOS.IsWin9x && (protectionLevel != ProtectionLevel.None)) { throw new NotSupportedException(SR.GetString("net_auth_no_protection_on_win9x")); } if (((impersonationLevel != TokenImpersonationLevel.Identification) && (impersonationLevel != TokenImpersonationLevel.Impersonation)) && (impersonationLevel != TokenImpersonationLevel.Delegation)) { throw new ArgumentOutOfRangeException("impersonationLevel", impersonationLevel.ToString(), SR.GetString("net_auth_supported_impl_levels")); } if ((this._Context != null) && (this.IsServer != isServer)) { throw new InvalidOperationException(SR.GetString("net_auth_client_server")); } this._Exception = null; this._RemoteOk = false; this._Framer = new StreamFramer(this._InnerStream); this._Framer.WriteHeader.MessageId = 0x16; this._ExpectedProtectionLevel = protectionLevel; this._ExpectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None; this._WriteSequenceNumber = 0; this._ReadSequenceNumber = 0; ContextFlags connection = ContextFlags.Connection; if ((protectionLevel == ProtectionLevel.None) && !isServer) { package = "NTLM"; } else if (protectionLevel == ProtectionLevel.EncryptAndSign) { connection |= ContextFlags.Confidentiality; } else if (protectionLevel == ProtectionLevel.Sign) { connection |= ContextFlags.AcceptStream | ContextFlags.SequenceDetect | ContextFlags.ReplayDetect; } if (isServer) { if (this._ExtendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported) { connection |= ContextFlags.AllowMissingBindings; } if ((this._ExtendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never) && (this._ExtendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy)) { connection |= ContextFlags.ProxyBindings; } } else { if (protectionLevel != ProtectionLevel.None) { connection |= ContextFlags.MutualAuth; } if (impersonationLevel == TokenImpersonationLevel.Identification) { connection |= ContextFlags.AcceptIntegrity; } if (impersonationLevel == TokenImpersonationLevel.Delegation) { connection |= ContextFlags.Delegate; } } this._CanRetryAuthentication = false; if (!(credential is SystemNetworkCredential)) { ExceptionHelper.ControlPrincipalPermission.Demand(); } try { this._Context = new NTAuthentication(isServer, package, credential, servicePrincipalName, connection, channelBinding); } catch (Win32Exception exception) { throw new AuthenticationException(SR.GetString("net_auth_SSPI"), exception); } }
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); } }
/// <summary> /// Converts provided binding to <see cref="IChannelBinding"/>. /// </summary> /// <param name="binding">Binding to convert.</param> /// <returns>Converted binding.</returns> public static IChannelBinding ToInterface(this ChannelBinding binding) { return((binding == null) ? null : new ChannelBindingAdapter(binding)); }
internal void ValidateCreateContext( string package, bool isServer, NetworkCredential credential, string servicePrincipalName, ChannelBinding channelBinding, ProtectionLevel protectionLevel, TokenImpersonationLevel impersonationLevel) { if (_exception != null && !_canRetryAuthentication) { throw _exception; } if (_context != null && _context.IsValidContext) { throw new InvalidOperationException(SR.net_auth_reauth); } if (credential == null) { throw new ArgumentNullException(nameof(credential)); } if (servicePrincipalName == null) { throw new ArgumentNullException(nameof(servicePrincipalName)); } NegotiateStreamPal.ValidateImpersonationLevel(impersonationLevel); if (_context != null && IsServer != isServer) { throw new InvalidOperationException(SR.net_auth_client_server); } _exception = null; _remoteOk = false; _framer = new StreamFramer(_innerStream); _framer.WriteHeader.MessageId = FrameHeader.HandshakeId; _expectedProtectionLevel = protectionLevel; _expectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None; _writeSequenceNumber = 0; _readSequenceNumber = 0; ContextFlagsPal flags = ContextFlagsPal.Connection; // A workaround for the client when talking to Win9x on the server side. if (protectionLevel == ProtectionLevel.None && !isServer) { package = NegotiationInfoClass.NTLM; } else if (protectionLevel == ProtectionLevel.EncryptAndSign) { flags |= ContextFlagsPal.Confidentiality; } else if (protectionLevel == ProtectionLevel.Sign) { // Assuming user expects NT4 SP4 and above. flags |= (ContextFlagsPal.ReplayDetect | ContextFlagsPal.SequenceDetect | ContextFlagsPal.InitIntegrity); } if (isServer) { if (_extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported) { flags |= ContextFlagsPal.AllowMissingBindings; } if (_extendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never && _extendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy) { flags |= ContextFlagsPal.ProxyBindings; } } else { // Server side should not request any of these flags. if (protectionLevel != ProtectionLevel.None) { flags |= ContextFlagsPal.MutualAuth; } if (impersonationLevel == TokenImpersonationLevel.Identification) { flags |= ContextFlagsPal.InitIdentify; } if (impersonationLevel == TokenImpersonationLevel.Delegation) { flags |= ContextFlagsPal.Delegate; } } _canRetryAuthentication = false; try { _context = new NTAuthentication(isServer, package, credential, servicePrincipalName, flags, channelBinding); } catch (Win32Exception e) { throw new AuthenticationException(SR.net_auth_SSPI, e); } }
/// <summary> /// Called by clients to authenticate the client, and optionally the server, in a client-server connection. The authentication process uses the specified client credential and the channel binding. /// </summary> /// <param name="credential">The NetworkCredential that is used to establish the identity of the client.</param> /// <param name="binding">The ChannelBinding that is used for extended protection. </param> /// <param name="targetName">The Service Principal Name (SPN) that uniquely identifies the server to authenticate.</param> public VaserKerberosClient(NetworkCredential credential, ChannelBinding binding, string targetName) { _credential = credential; _targetName = targetName; _binding = binding; }
internal SecurityToken GetToken(TimeSpan timeout, ChannelBinding channelbinding) { return(new KerberosRequestorSecurityToken(this.innerProvider.ServicePrincipalName, this.innerProvider.TokenImpersonationLevel, this.innerProvider.NetworkCredential, System.ServiceModel.Security.SecurityUniqueId.Create().Value, this.credentialsHandle, channelbinding)); }
public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy) { this.ThrowIfDisposed(); int error = 0; SspiContextFlags inFlags = SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect; if (this.doMutualAuth) { inFlags |= SspiContextFlags.MutualAuth; } if (this.impersonationLevel == TokenImpersonationLevel.Delegation) { inFlags |= SspiContextFlags.Delegate; } else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Identification)) { inFlags |= SspiContextFlags.InitIdentify; } else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Anonymous)) { inFlags |= SspiContextFlags.InitAnonymous; } ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy); if (this.isServer) { if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.ServiceModel.SR.GetString("SecurityChannelBindingMissing"))); } if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy) { inFlags |= SspiContextFlags.ChannelBindingProxyBindings; } } List <SecurityBuffer> list = new List <SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, BufferType.Token)); } if (this.isServer) { if (helper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } } else if (helper.ChannelBinding != null) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } SecurityBuffer[] inputBuffers = null; if (list.Count > 0) { inputBuffers = list.ToArray(); } SecurityBuffer outputBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token); if (!this.isServer) { error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); } else { bool flag = this.securityContext == null; SspiContextFlags contextFlags = this.contextFlags; error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); if ((error == -2146893048) && !flag) { this.contextFlags = contextFlags; this.CloseContext(); error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); } } if ((error & -2147483648) != 0) { if (((!this.isServer && this.interactiveNegoLogonEnabled) && (System.ServiceModel.Security.SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint)error))) && SspiWrapper.IsNegotiateExPackagePresent()) { if (this.MaxPromptAttempts >= 1) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidClientCredentials"))); } IntPtr zero = IntPtr.Zero; uint num2 = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out zero, ref this.saveClientCredentialsOnSspiUi); if (num2 == 0) { IntPtr ppNewAuthIdentity = IntPtr.Zero; if (!this.allowNtlm) { UnsafeNativeMethods.SspiExcludePackage(zero, "NTLM", out ppNewAuthIdentity); } else { ppNewAuthIdentity = zero; } this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity); if (IntPtr.Zero != ppNewAuthIdentity) { UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity); } this.CloseContext(); this.MaxPromptAttempts++; return(this.GetOutgoingBlob(null, channelbinding, protectionPolicy)); } if (IntPtr.Zero != zero) { UnsafeNativeMethods.SspiFreeAuthIdentity(zero); } this.CloseContext(); this.isCompleted = true; throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)num2, System.ServiceModel.SR.GetString("SspiErrorOrInvalidClientCredentials"))); } this.CloseContext(); this.isCompleted = true; if (this.isServer || (((error != -2146893042) && (error != -2146893053)) && (error != -2146893022))) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidSspiNegotiation"))); } throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("IncorrectSpnOrUpnSpecified", new object[] { this.servicePrincipalName }))); } if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation) { if (this.isServer) { SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this); } else { SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this); } } if (error == 0) { this.isCompleted = true; if ((this.isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == SspiContextFlags.Zero)) && ((string.Compare(this.ProtocolName, "Kerberos", StringComparison.OrdinalIgnoreCase) != 0) && helper.ShouldCheckServiceBinding)) { helper.CheckServiceBinding(this.securityContext, this.servicePrincipalName); } } return(outputBuffer.token); }
private static bool GssInitSecurityContext( ref SafeGssContextHandle context, SafeGssCredHandle credential, bool isNtlm, ChannelBinding channelBinding, SafeGssNameHandle targetName, Interop.NetSecurityNative.GssFlags inFlags, byte[] buffer, out byte[] outputBuffer, out uint outFlags, out int isNtlmUsed) { // If a TLS channel binding token (cbt) is available then get the pointer // to the application specific data. IntPtr cbtAppData = IntPtr.Zero; int cbtAppDataSize = 0; if (channelBinding != null) { int appDataOffset = Marshal.SizeOf <SecChannelBindings>(); Debug.Assert(appDataOffset < channelBinding.Size); cbtAppData = channelBinding.DangerousGetHandle() + appDataOffset; cbtAppDataSize = channelBinding.Size - appDataOffset; } outputBuffer = null; outFlags = 0; // EstablishSecurityContext is called multiple times in a session. // In each call, we need to pass the context handle from the previous call. // For the first call, the context handle will be null. if (context == null) { context = new SafeGssContextHandle(); } Interop.NetSecurityNative.GssBuffer token = default(Interop.NetSecurityNative.GssBuffer); Interop.NetSecurityNative.Status status; try { Interop.NetSecurityNative.Status minorStatus; status = Interop.NetSecurityNative.InitSecContext(out minorStatus, credential, ref context, isNtlm, cbtAppData, cbtAppDataSize, targetName, (uint)inFlags, buffer, (buffer == null) ? 0 : buffer.Length, ref token, out outFlags, out isNtlmUsed); if ((status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE) && (status != Interop.NetSecurityNative.Status.GSS_S_CONTINUE_NEEDED)) { throw new Interop.NetSecurityNative.GssApiException(status, minorStatus); } outputBuffer = token.ToByteArray(); } finally { token.Dispose(); } return(status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE); }
public Authorization Authenticate(string challenge, NetworkCredential credential, object sessionCookie, string spn, ChannelBinding channelBindingToken) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Enter(NetEventSource.ComponentType.Web, this, nameof(Authenticate), null); } try { lock (_sessions) { NetworkCredential cachedCredential; if (!_sessions.TryGetValue(sessionCookie, out cachedCredential)) { if (credential == null || ReferenceEquals(credential, CredentialCache.DefaultNetworkCredentials)) { return(null); } _sessions[sessionCookie] = credential; string userName = credential.UserName; string domain = credential.Domain; if (domain != null && domain.Length > 0) { userName = domain + "\\" + userName; } return(new Authorization(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(userName)), false)); } else { _sessions.Remove(sessionCookie); return(new Authorization(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(cachedCredential.Password)), true)); } } } finally { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Exit(NetEventSource.ComponentType.Web, this, "Authenticate", null); } } }
// // 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, Interop.SspiCli.ContextFlags requestedContextFlags, ChannelBinding channelBinding) { Initialize(isServer, package, credential, spn, requestedContextFlags, channelBinding); }
protected void SetChannelBinding(ChannelBinding channelBinding) { Fx.Assert(_channelBindingToken == null, "ChannelBinding token can only be set once."); _channelBindingToken = channelBinding; }
private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, Interop.SspiCli.ContextFlags requestedContextFlags, ChannelBinding channelBinding) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor() package:" + LoggingHash.ObjectToString(package) + " spn:" + LoggingHash.ObjectToString(spn) + " flags :" + requestedContextFlags.ToString()); _tokenSize = SSPIWrapper.GetVerifyPackageInfo(GlobalSSPI.SSPIAuth, package, true).MaxToken; _isServer = isServer; _spn = spn; _securityContext = null; _requestedContextFlags = requestedContextFlags; _package = package; _channelBinding = channelBinding; GlobalLog.Print("Peer SPN-> '" + _spn + "'"); // // Check if we're using DefaultCredentials. // Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials); if (credential == CredentialCache.DefaultCredentials) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::.ctor(): using DefaultCredentials"); _credentialsHandle = SSPIWrapper.AcquireDefaultCredential( GlobalSSPI.SSPIAuth, package, (_isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound)); } else { unsafe { SafeSspiAuthDataHandle authData = null; try { Interop.SecurityStatus result = Interop.SspiCli.SspiEncodeStringsAsAuthIdentity( credential.UserName, credential.Domain, credential.Password, out authData); if (result != Interop.SecurityStatus.OK) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.PrintError( NetEventSource.ComponentType.Security, SR.Format( SR.net_log_operation_failed_with_error, "SspiEncodeStringsAsAuthIdentity()", String.Format(CultureInfo.CurrentCulture, "0x{0:X}", (int)result))); } throw new Win32Exception((int)result); } _credentialsHandle = SSPIWrapper.AcquireCredentialsHandle(GlobalSSPI.SSPIAuth, package, (_isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound), ref authData); } finally { if (authData != null) { authData.Dispose(); } } } } }
public virtual void AuthenticateAsClient(NetworkCredential credential, ChannelBinding binding, string targetName) { AuthenticateAsClient(credential, binding, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); }
internal KerberosRequestorSecurityToken(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, string id, System.IdentityModel.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", System.IdentityModel.SR.GetString("ImpersonationLevelNotSupported", new object[] { tokenImpersonationLevel }))); } if (id == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("id"); } this.servicePrincipalName = servicePrincipalName; if (((networkCredential != null) && (networkCredential != CredentialCache.DefaultNetworkCredentials)) && string.IsNullOrEmpty(networkCredential.UserName)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(System.IdentityModel.SR.GetString("ProvidedNetworkCredentialsForKerberosHasInvalidUserName")); } this.id = id; try { this.Initialize(tokenImpersonationLevel, networkCredential, credentialsHandle, channelBinding); } catch (Win32Exception exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(System.IdentityModel.SR.GetString("UnableToCreateKerberosCredentials"), exception)); } catch (SecurityTokenException exception2) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(System.IdentityModel.SR.GetString("UnableToCreateKerberosCredentials"), exception2)); } }
/// <devdoc> /// <para>Pre-authenticates a request.</para> /// </devdoc> public override Authorization PreAuthenticate(WebRequest request, ICredentials credentials) { GlobalLog.Print("AuthenticationManager::PreAuthenticate() request:" + ValidationHelper.HashString(request) + " credentials:" + ValidationHelper.HashString(credentials)); if (request == null) { throw new ArgumentNullException("request"); } if (credentials == null) { return(null); } HttpWebRequest httpWebRequest = request as HttpWebRequest; IAuthenticationModule authenticationModule; if (httpWebRequest == null) { return(null); } // // PrefixLookup is thread-safe // string moduleName = moduleBinding.Lookup(httpWebRequest.ChallengedUri.AbsoluteUri) as string; GlobalLog.Print("AuthenticationManager::PreAuthenticate() s_ModuleBinding.Lookup returns:" + ValidationHelper.ToString(moduleName)); if (moduleName == null) { return(null); } if (!this.moduleList.TryGetValue(moduleName.ToUpperInvariant(), out authenticationModule)) { // The module could have been unregistered // No preauthentication is possible return(null); } // prepopulate the channel binding token so we can try preauth (but only for modules that actually need it!) if (httpWebRequest.ChallengedUri.Scheme == Uri.UriSchemeHttps) { object binding = httpWebRequest.ServicePoint.CachedChannelBinding; #if DEBUG // the ModuleRequiresChannelBinding method is only compiled in DEBUG so the assert must be restricted to DEBUG // as well // If the authentication module does CBT, we require that it also caches channel bindings. System.Diagnostics.Debug.Assert(!(binding == null && ModuleRequiresChannelBinding(authenticationModule))); #endif // can also be DBNull.Value, indicating "we previously succeeded without getting a CBT." // (ie, unpatched SSP talking to a partially-hardened server) ChannelBinding channelBinding = binding as ChannelBinding; if (channelBinding != null) { httpWebRequest.CurrentAuthenticationState.TransportContext = new CachedTransportContext(channelBinding); } } // Otherwise invoke the PreAuthenticate method // we're guaranteed that CanPreAuthenticate is true because we check before calling BindModule() Authorization authorization = authenticationModule.PreAuthenticate(request, credentials); if (authorization != null && !authorization.Complete && httpWebRequest != null) { httpWebRequest.CurrentAuthenticationState.Module = authenticationModule; } GlobalLog.Print( "AuthenticationManager::PreAuthenticate() IAuthenticationModule.PreAuthenticate()" + " returned authorization:" + ValidationHelper.HashString(authorization)); return(authorization); }
private void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, System.IdentityModel.SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding) { bool flag = false; System.IdentityModel.SafeDeleteContext context = null; try { if (credentialsHandle == null) { if ((networkCredential == null) || (networkCredential == CredentialCache.DefaultNetworkCredentials)) { credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", System.IdentityModel.CredentialUse.Outbound, new string[0]); } else { AuthIdentityEx authdata = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain, new string[0]); credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", System.IdentityModel.CredentialUse.Outbound, ref authdata); } flag = true; } SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect; if (tokenImpersonationLevel == TokenImpersonationLevel.Identification) { inFlags |= SspiContextFlags.InitIdentify; } SspiContextFlags zero = SspiContextFlags.Zero; System.IdentityModel.SecurityBuffer inputBuffer = null; if (channelBinding != null) { inputBuffer = new System.IdentityModel.SecurityBuffer(channelBinding); } System.IdentityModel.SecurityBuffer outputBuffer = new System.IdentityModel.SecurityBuffer(0, System.IdentityModel.BufferType.Token); int error = SspiWrapper.InitializeSecurityContext(credentialsHandle, ref context, this.servicePrincipalName, inFlags, System.IdentityModel.Endianness.Native, inputBuffer, outputBuffer, ref zero); switch (error) { case 0: break; case 0x90312: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error))); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailInitializeSecurityContext"), new Win32Exception(error))); } this.apreq = outputBuffer.token; LifeSpan span = (LifeSpan)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.Lifespan); this.effectiveTime = span.EffectiveTimeUtc; this.expirationTime = span.ExpiryTimeUtc; SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.SessionKey); this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey); } finally { if (context != null) { context.Close(); } if (flag && (credentialsHandle != null)) { credentialsHandle.Close(); } } }
internal AuthenticateCallbackContext(SmtpConnection thisPtr, ISmtpAuthenticationModule module, NetworkCredential credential, string spn, ChannelBinding Token) { _thisPtr = thisPtr; _module = module; _credential = credential; _spn = spn; _token = Token; _result = null; }
internal Task <SecurityToken> GetTokenAsync(CancellationToken cancellationToken, ChannelBinding channelbinding) { return(Task.FromResult((SecurityToken) new KerberosRequestorSecurityToken(this.innerProvider.ServicePrincipalName, this.innerProvider.TokenImpersonationLevel, this.innerProvider.NetworkCredential, SecurityUniqueId.Create().Value))); }
public InputSecurityBuffer(ChannelBinding binding) { Type = SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS; Token = default; UnmanagedToken = binding; }
public Authorization Authenticate(string challenge, NetworkCredential credential, object sessionCookie, string spn, ChannelBinding channelBindingToken) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(this, "Authenticate"); } try { lock (_sessions) { NTAuthentication clientContext; if (!_sessions.TryGetValue(sessionCookie, out clientContext)) { if (credential == null) { return(null); } _sessions[sessionCookie] = clientContext = new NTAuthentication(false, "Ntlm", credential, spn, ContextFlagsPal.Connection, channelBindingToken); } string resp = clientContext.GetOutgoingBlob(challenge); if (!clientContext.IsCompleted) { return(new Authorization(resp, false)); } else { _sessions.Remove(sessionCookie); return(new Authorization(resp, true)); } } } // From reflected type NTAuthentication in System.Net.Security. catch (NullReferenceException) { return(null); } finally { if (NetEventSource.IsEnabled) { NetEventSource.Exit(this, "Authenticate"); } } }
internal KerberosRequestorSecurityToken(string servicePrincipalName, TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, string id, ChannelBinding channelBinding) : this(servicePrincipalName, tokenImpersonationLevel, networkCredential, id, null, channelBinding) { }
public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy) { ThrowIfDisposed(); SecurityBuffer incomingSecurity = null; if (incomingBlob != null) { incomingSecurity = new SecurityBuffer(incomingBlob, BufferType.Token); } SecurityBuffer outgoingSecurity = new SecurityBuffer(null, BufferType.Token); this.remoteCertificate = null; int statusCode = 0; if (this.isServer == true) { statusCode = SspiWrapper.AcceptSecurityContext( this.credentialsHandle, ref this.securityContext, ServerStandardFlags | (this.clientCertRequired ? SspiContextFlags.MutualAuth : SspiContextFlags.Zero), Endianness.Native, incomingSecurity, outgoingSecurity, ref this.attributes ); } else { statusCode = SspiWrapper.InitializeSecurityContext( this.credentialsHandle, ref this.securityContext, this.destination, ClientStandardFlags, Endianness.Native, incomingSecurity, outgoingSecurity, ref this.attributes ); } if ((statusCode & unchecked ((int)0x80000000)) != 0) { this.Dispose(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode)); } if (statusCode == (int)SecurityStatus.OK) { // we're done // ensure that the key negotiated is strong enough if (SecurityUtils.ShouldValidateSslCipherStrength()) { SslConnectionInfo connectionInfo = (SslConnectionInfo)SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.ConnectionInfo); if (connectionInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.CannotObtainSslConnectionInfo))); } SecurityUtils.ValidateSslCipherStrength(connectionInfo.DataKeySize); } this.isCompleted = true; } else if (statusCode == (int)SecurityStatus.CredentialsNeeded) { // the server requires the client to supply creds // Currently we dont attempt to find the client cert to choose at runtime // so just re-call the function AcquireClientCredentials(); if (this.ClientCertificate != null) { this.wasClientCertificateSent = true; } return(this.GetOutgoingBlob(incomingBlob, channelbinding, protectionPolicy)); } else if (statusCode != (int)SecurityStatus.ContinueNeeded) { this.Dispose(); if (statusCode == (int)SecurityStatus.InternalError) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.LsaAuthorityNotContacted))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode)); } } return(outgoingSecurity.token); }
public virtual Task AuthenticateAsClientAsync(NetworkCredential credential, ChannelBinding binding, string targetName) { return(Task.Factory.FromAsync(BeginAuthenticateAsClient, EndAuthenticateAsClient, credential, binding, targetName, null)); }
public ExtendedProtectionPolicy(PolicyEnforcement policyEnforcement, ChannelBinding customChannelBinding);