protected override Stream OnInitiateUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity) { OutWrapper <SecurityMessageProperty> remoteSecurityOut = new OutWrapper <SecurityMessageProperty>(); var retVal = OnInitiateUpgradeAsync(stream, remoteSecurityOut).GetAwaiter().GetResult(); remoteSecurity = remoteSecurityOut.Value; return(retVal); }
// used for HTTP (from HttpChannelUtilities.GetCredential) public static async Task <NetworkCredential> GetSspiCredentialAsync(SecurityTokenProviderContainer tokenProvider, OutWrapper <TokenImpersonationLevel> impersonationLevelWrapper, OutWrapper <AuthenticationLevel> authenticationLevelWrapper, TimeSpan timeout) { OutWrapper <bool> dummyExtractWindowsGroupClaimsWrapper = new OutWrapper <bool>(); OutWrapper <bool> allowNtlmWrapper = new OutWrapper <bool>(); NetworkCredential result = await GetSspiCredentialAsync(tokenProvider.TokenProvider as SspiSecurityTokenProvider, dummyExtractWindowsGroupClaimsWrapper, impersonationLevelWrapper, allowNtlmWrapper, timeout); authenticationLevelWrapper.Value = allowNtlmWrapper.Value ? AuthenticationLevel.MutualAuthRequested : AuthenticationLevel.MutualAuthRequired; return(result); }
protected override async Task <Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper <SecurityMessageProperty> remoteSecurityWrapper) { if (WcfEventSource.Instance.SslOnInitiateUpgradeIsEnabled()) { WcfEventSource.Instance.SslOnInitiateUpgrade(); } X509CertificateCollection clientCertificates = null; LocalCertificateSelectionCallback selectionCallback = null; if (_clientToken != null) { clientCertificates = new X509CertificateCollection(); clientCertificates.Add(_clientToken.Certificate); selectionCallback = ClientCertificateSelectionCallback; } SslStream sslStream = new SslStream(stream, false, this.ValidateRemoteCertificate, selectionCallback); try { await sslStream.AuthenticateAsClientAsync(string.Empty, clientCertificates, _parent.SslProtocols, false); } catch (SecurityTokenValidationException tokenValidationException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(tokenValidationException.Message, tokenValidationException)); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( string.Format(SRServiceModel.NegotiationFailedIO, ioException.Message), ioException)); } remoteSecurityWrapper.Value = _serverSecurity; if (this.IsChannelBindingSupportEnabled) { _channelBindingToken = ChannelBindingUtility.GetToken(sslStream); } return(sslStream); #endif //!FEATURE_NETNATIVE }
public static Task <NetworkCredential> GetCredentialAsync(AuthenticationSchemes authenticationScheme, SecurityTokenProviderContainer credentialProvider, OutWrapper <TokenImpersonationLevel> impersonationLevelWrapper, OutWrapper <AuthenticationLevel> authenticationLevelWrapper, CancellationToken cancellationToken) { impersonationLevelWrapper.Value = TokenImpersonationLevel.None; authenticationLevelWrapper.Value = AuthenticationLevel.None; if (authenticationScheme == AuthenticationSchemes.Anonymous) { return(Task.FromResult((NetworkCredential)null)); } return(GetCredentialCoreAsync(authenticationScheme, credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken)); }
public static Task<NetworkCredential> GetCredentialAsync(AuthenticationSchemes authenticationScheme, SecurityTokenProviderContainer credentialProvider, OutWrapper<TokenImpersonationLevel> impersonationLevelWrapper, OutWrapper<AuthenticationLevel> authenticationLevelWrapper, CancellationToken cancellationToken) { impersonationLevelWrapper.Value = TokenImpersonationLevel.None; authenticationLevelWrapper.Value = AuthenticationLevel.None; if (authenticationScheme == AuthenticationSchemes.Anonymous) { return Task.FromResult((NetworkCredential)null); } return GetCredentialCoreAsync(authenticationScheme, credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken); }
static async Task <NetworkCredential> GetCredentialCoreAsync(AuthenticationSchemes authenticationScheme, SecurityTokenProviderContainer credentialProvider, OutWrapper <TokenImpersonationLevel> impersonationLevelWrapper, OutWrapper <AuthenticationLevel> authenticationLevelWrapper, CancellationToken cancellationToken) { impersonationLevelWrapper.Value = TokenImpersonationLevel.None; authenticationLevelWrapper.Value = AuthenticationLevel.None; NetworkCredential result = null; switch (authenticationScheme) { case AuthenticationSchemes.Basic: result = await TransportSecurityHelpers.GetUserNameCredentialAsync(credentialProvider, cancellationToken); impersonationLevelWrapper.Value = TokenImpersonationLevel.Delegation; break; case AuthenticationSchemes.Digest: result = await TransportSecurityHelpers.GetSspiCredentialAsync(credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken); ValidateDigestCredential(result, impersonationLevelWrapper.Value); break; case AuthenticationSchemes.Negotiate: result = await TransportSecurityHelpers.GetSspiCredentialAsync(credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken); break; case AuthenticationSchemes.Ntlm: result = await TransportSecurityHelpers.GetSspiCredentialAsync(credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken); if (authenticationLevelWrapper.Value == AuthenticationLevel.MutualAuthRequired) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR.CredentialDisallowsNtlm)); } break; default: // The setter for this property should prevent this. throw Fx.AssertAndThrow("GetCredential: Invalid authentication scheme"); } return(result); }
static async Task<NetworkCredential> GetCredentialCoreAsync(AuthenticationSchemes authenticationScheme, SecurityTokenProviderContainer credentialProvider, OutWrapper<TokenImpersonationLevel> impersonationLevelWrapper, OutWrapper<AuthenticationLevel> authenticationLevelWrapper, CancellationToken cancellationToken) { impersonationLevelWrapper.Value = TokenImpersonationLevel.None; authenticationLevelWrapper.Value = AuthenticationLevel.None; NetworkCredential result = null; switch (authenticationScheme) { case AuthenticationSchemes.Basic: result = await TransportSecurityHelpers.GetUserNameCredentialAsync(credentialProvider, cancellationToken); impersonationLevelWrapper.Value = TokenImpersonationLevel.Delegation; break; case AuthenticationSchemes.Digest: result = await TransportSecurityHelpers.GetSspiCredentialAsync(credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken); ValidateDigestCredential(result, impersonationLevelWrapper.Value); break; case AuthenticationSchemes.Negotiate: result = await TransportSecurityHelpers.GetSspiCredentialAsync(credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken); break; case AuthenticationSchemes.Ntlm: result = await TransportSecurityHelpers.GetSspiCredentialAsync(credentialProvider, impersonationLevelWrapper, authenticationLevelWrapper, cancellationToken); if (authenticationLevelWrapper.Value == AuthenticationLevel.MutualAuthRequired) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR.CredentialDisallowsNtlm)); } break; default: // The setter for this property should prevent this. throw Fx.AssertAndThrow("GetCredential: Invalid authentication scheme"); } return result; }
internal override async Task <Stream> InitiateUpgradeAsync(Stream stream) { if (stream == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream"); } if (!_isOpen) { Open(TimeSpan.Zero); } var remoteSecurityWrapper = new OutWrapper <SecurityMessageProperty>(); Stream result = await OnInitiateUpgradeAsync(stream, remoteSecurityWrapper); _remoteSecurity = remoteSecurityWrapper; _securityUpgraded = true; return(result); }
private async Task <IConnection> SendPreambleAsync(IConnection connection, ArraySegment <byte> preamble, TimeSpan timeout) { var timeoutHelper = new TimeoutHelper(timeout); // initialize a new decoder _decoder = new ClientDuplexDecoder(0); byte[] ackBuffer = new byte[1]; await connection.WriteAsync(preamble.Array, preamble.Offset, preamble.Count, true, timeoutHelper.RemainingTime()); if (_upgrade != null) { StreamUpgradeInitiator upgradeInitiator = _upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via); await upgradeInitiator.OpenAsync(timeoutHelper.RemainingTime()); var connectionWrapper = new OutWrapper <IConnection>(); connectionWrapper.Value = connection; bool upgradeInitiated = await ConnectionUpgradeHelper.InitiateUpgradeAsync(upgradeInitiator, connectionWrapper, _decoder, this, timeoutHelper.RemainingTime()); connection = connectionWrapper.Value; if (!upgradeInitiated) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(_decoder, connection, this.Via, MessageEncoder.ContentType, timeoutHelper.RemainingTime()); } SetRemoteSecurity(upgradeInitiator); await upgradeInitiator.CloseAsync(timeoutHelper.RemainingTime()); await connection.WriteAsync(ClientDuplexEncoder.PreambleEndBytes, 0, ClientDuplexEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime()); } int ackBytesRead = await connection.ReadAsync(ackBuffer, 0, ackBuffer.Length, timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.ValidatePreambleResponse(ackBuffer, ackBytesRead, _decoder, Via)) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(_decoder, connection, Via, MessageEncoder.ContentType, timeoutHelper.RemainingTime()); } return(connection); }
internal override async Task OpenAsync(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); base.Open(timeoutHelper.RemainingTime()); OutWrapper <TokenImpersonationLevel> impersonationLevelWrapper = new OutWrapper <TokenImpersonationLevel>(); OutWrapper <bool> allowNtlmWrapper = new OutWrapper <bool>(); SecurityUtils.OpenTokenProviderIfRequired(_clientTokenProvider, timeoutHelper.RemainingTime()); _credential = await TransportSecurityHelpers.GetSspiCredentialAsync( _clientTokenProvider, impersonationLevelWrapper, allowNtlmWrapper, timeoutHelper.GetCancellationToken()); _impersonationLevel = impersonationLevelWrapper.Value; _allowNtlm = allowNtlmWrapper; return; }
// core Cred lookup code public static async Task <NetworkCredential> GetSspiCredentialAsync(SspiSecurityTokenProvider tokenProvider, OutWrapper <bool> extractGroupsForWindowsAccounts, OutWrapper <TokenImpersonationLevel> impersonationLevelWrapper, OutWrapper <bool> allowNtlmWrapper, TimeSpan timeout) { NetworkCredential credential = null; extractGroupsForWindowsAccounts.Value = TransportDefaults.ExtractGroupsForWindowsAccounts; impersonationLevelWrapper.Value = TokenImpersonationLevel.Identification; allowNtlmWrapper.Value = ConnectionOrientedTransportDefaults.AllowNtlm; if (tokenProvider != null) { SspiSecurityToken token = await TransportSecurityHelpers.GetTokenAsync <SspiSecurityToken>(tokenProvider, timeout); if (token != null) { extractGroupsForWindowsAccounts.Value = token.ExtractGroupsForWindowsAccounts; impersonationLevelWrapper.Value = token.ImpersonationLevel; allowNtlmWrapper.Value = token.AllowNtlm; if (token.NetworkCredential != null) { credential = token.NetworkCredential; SecurityUtils.FixNetworkCredential(ref credential); } } } // Initialize to the default value if no token provided. A partial trust app should not have access to the // default network credentials but should be able to provide credentials. The DefaultNetworkCredentials // getter will throw under partial trust. if (credential == null) { credential = CredentialCache.DefaultNetworkCredentials; } return(credential); }
// used by server WindowsStream security (from Open) public static NetworkCredential GetSspiCredential(SecurityTokenManager credentialProvider, SecurityTokenRequirement sspiTokenRequirement, TimeSpan timeout, out bool extractGroupsForWindowsAccounts) { extractGroupsForWindowsAccounts = TransportDefaults.ExtractGroupsForWindowsAccounts; NetworkCredential result = null; if (credentialProvider != null) { SecurityTokenProvider tokenProvider = credentialProvider.CreateSecurityTokenProvider(sspiTokenRequirement); if (tokenProvider != null) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); SecurityUtils.OpenTokenProviderIfRequired(tokenProvider, timeoutHelper.RemainingTime()); bool success = false; try { OutWrapper <TokenImpersonationLevel> dummyImpersonationLevelWrapper = new OutWrapper <TokenImpersonationLevel>(); OutWrapper <bool> dummyAllowNtlmWrapper = new OutWrapper <bool>(); OutWrapper <bool> extractGroupsForWindowsAccountsWrapper = new OutWrapper <bool>(); result = GetSspiCredentialAsync((SspiSecurityTokenProvider)tokenProvider, extractGroupsForWindowsAccountsWrapper, dummyImpersonationLevelWrapper, dummyAllowNtlmWrapper, timeoutHelper.RemainingTime()).GetAwaiter().GetResult(); success = true; } finally { if (!success) { SecurityUtils.AbortTokenProviderIfRequired(tokenProvider); } } SecurityUtils.CloseTokenProviderIfRequired(tokenProvider, timeoutHelper.RemainingTime()); } } return(result); }
internal async Task <IConnection> SendPreambleAsync(IConnection connection, TimeoutHelper timeoutHelper, ClientFramingDecoder decoder) { await connection.WriteAsync(Preamble, 0, Preamble.Length, true, timeoutHelper.RemainingTime()); if (_upgrade != null) { StreamUpgradeInitiator upgradeInitiator = _upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via); await upgradeInitiator.OpenAsync(timeoutHelper.RemainingTime()); var connectionWrapper = new OutWrapper <IConnection>(); connectionWrapper.Value = connection; bool upgradeInitiated = await ConnectionUpgradeHelper.InitiateUpgradeAsync(upgradeInitiator, connectionWrapper, decoder, this, timeoutHelper.RemainingTime()); connection = connectionWrapper.Value; if (!upgradeInitiated) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(decoder, connection, this.Via, _messageEncoder.ContentType, timeoutHelper.RemainingTime()); } await upgradeInitiator.CloseAsync(timeoutHelper.RemainingTime()); await connection.WriteAsync(ClientSingletonEncoder.PreambleEndBytes, 0, ClientSingletonEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime()); } byte[] ackBuffer = new byte[1]; int ackBytesRead = await connection.ReadAsync(ackBuffer, 0, ackBuffer.Length, timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.ValidatePreambleResponse(ackBuffer, ackBytesRead, decoder, Via)) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(decoder, connection, Via, _messageEncoder.ContentType, timeoutHelper.RemainingTime()); } return(connection); }
internal async Task<IConnection> SendPreambleAsync(IConnection connection, TimeoutHelper timeoutHelper, ClientFramingDecoder decoder) { await connection.WriteAsync(Preamble, 0, Preamble.Length, true, timeoutHelper.RemainingTime()); if (_upgrade != null) { StreamUpgradeInitiator upgradeInitiator = _upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via); await upgradeInitiator.OpenAsync(timeoutHelper.RemainingTime()); var connectionWrapper = new OutWrapper<IConnection>(); connectionWrapper.Value = connection; bool upgradeInitiated = await ConnectionUpgradeHelper.InitiateUpgradeAsync(upgradeInitiator, connectionWrapper, decoder, this, timeoutHelper.RemainingTime()); connection = connectionWrapper.Value; if (!upgradeInitiated) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(decoder, connection, this.Via, _messageEncoder.ContentType, timeoutHelper.RemainingTime()); } await upgradeInitiator.CloseAsync(timeoutHelper.RemainingTime()); await connection.WriteAsync(ClientSingletonEncoder.PreambleEndBytes, 0, ClientSingletonEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime()); } byte[] ackBuffer = new byte[1]; int ackBytesRead = await connection.ReadAsync(ackBuffer, 0, ackBuffer.Length, timeoutHelper.RemainingTime()); if (!ConnectionUpgradeHelper.ValidatePreambleResponse(ackBuffer, ackBytesRead, decoder, Via)) { await ConnectionUpgradeHelper.DecodeFramingFaultAsync(decoder, connection, Via, _messageEncoder.ContentType, timeoutHelper.RemainingTime()); } return connection; }
protected override Task <Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper <SecurityMessageProperty> remoteSecurity) { throw ExceptionHelper.PlatformNotSupported(ExceptionHelper.WinsdowsStreamSecurityNotSupported); }
protected override Task <Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper <SecurityMessageProperty> remoteSecurityWrapper) { throw ExceptionHelper.PlatformNotSupported("SslStreamSecurityUpgradeInitiator.InInitiateUpgradeAsync");
protected abstract Task <Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper <SecurityMessageProperty> remoteSecurity);
// used by client WindowsStream security (from InitiateUpgrade) public static Task <NetworkCredential> GetSspiCredentialAsync(SspiSecurityTokenProvider tokenProvider, OutWrapper <TokenImpersonationLevel> impersonationLevel, OutWrapper <bool> allowNtlm, TimeSpan timeout) { OutWrapper <bool> dummyExtractWindowsGroupClaimsWrapper = new OutWrapper <bool>(); return(GetSspiCredentialAsync(tokenProvider, dummyExtractWindowsGroupClaimsWrapper, impersonationLevel, allowNtlm, timeout)); }
public Task<Message> ParseIncomingMessageAsync(OutWrapper<Exception> requestException) { return this.ParseIncomingMessageAsync(null, requestException); }
protected override async Task <Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper <SecurityMessageProperty> remoteSecurityWrapper) { if (WcfEventSource.Instance.SslOnInitiateUpgradeIsEnabled()) { WcfEventSource.Instance.SslOnInitiateUpgrade(); } // There is currently no way to convert a .Net X509Certificate2 to a UWP Certificate. The client certificate // needs to be provided by looking it up in the certificate store. E.g. // // factory.Credentials.ClientCertificate.SetCertificate( // StoreLocation.CurrentUser, // StoreName.My, // X509FindType.FindByThumbprint, // clientCertThumb); // // The certificate is retrieved using .Net api's and UWP api's. An artifical X509Extension is used to attach the // UWP certificate to the .Net X509Certificate2. This is then retrieved at the point of usage to use with UWP // networking api's. Certificate clientCertificate = null; if (_clientToken != null) { foreach (var extension in _clientToken.Certificate.Extensions) { var attachmentExtension = extension as X509CertificateInitiatorClientCredential.X509UwpCertificateAttachmentExtension; if (attachmentExtension != null && attachmentExtension.AttachedCertificate != null) { clientCertificate = attachmentExtension.AttachedCertificate; break; } } Contract.Assert(clientCertificate != null, "Missing UWP Certificate as an attachment to X509Certificate2"); } try { // Fetch the underlying raw transport object. For UWP, this will be a StreamSocket var connectionStream = stream as ConnectionStream; Contract.Assert(connectionStream != null, "stream is either null or not a ConnectionStream"); var rtStreamSocket = connectionStream.Connection.GetCoreTransport() as StreamSocket; Contract.Assert(rtStreamSocket != null, "Core transport is either null or not a StreamSocket"); rtStreamSocket.Control.ClientCertificate = clientCertificate; // On CoreClr, we use SslStream which calls a callback with any problems with the server certificate, which // returns whether to accept the certificate or not. With SocketStream in UWP, any custom validation needs to // happen after the connection has successfully negotiated. Some certificate errors need to be set to be ignored // to allow the connection to be established so we can retrieve the server certificate and choose whether to // accept the server certificate or not. rtStreamSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted); rtStreamSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired); rtStreamSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName); rtStreamSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain); rtStreamSocket.Control.IgnorableServerCertificateErrors.Add( ChainValidationResult.RevocationInformationMissing); rtStreamSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationFailure); // SocketStream doesn't take a bitwise field of accepted protocols, but instead accepts a value specifying the highest // protocol that can be negotiated. A check is made for each of the protocols in order to see if they've been requested // by the binding and set the protection level to the UWP equivalent. This will have the effect of protectionLevel being // set to the most secure protocol that was specified by client code. After the connection is established, if a protocol // was negotiated which the binding didn't request, the connection needs to be aborted. This could happen for example if // the requested SslProtocols was SslProtocols.Tls11 | SslProtocols.Tls12 and the server only supported SSL3 | Tls10. In // this case, SocketProtectionLevel would be set to SocketProtectionLevel.Tls12, which would mean Tls10, Tls11 and Tls12 // are all acceptable protocols to negotiate. As the server is offering SSL3 | Tls10, the connection would be successfully // negotiated using Tls10 which isn't allowed according to the binding configuration. SocketProtectionLevel protectionLevel = SocketProtectionLevel.PlainSocket; if ((_parent.SslProtocols & SslProtocols.Tls) != SslProtocols.None) { protectionLevel = SocketProtectionLevel.Tls10; } if ((_parent.SslProtocols & SslProtocols.Tls11) != SslProtocols.None) { protectionLevel = SocketProtectionLevel.Tls11; } if ((_parent.SslProtocols & SslProtocols.Tls12) != SslProtocols.None) { protectionLevel = SocketProtectionLevel.Tls12; } // With SslStream, the hostname provided in the server certificate is provided to the client and verified in the callback. // With UWP StreamSocket, the hostname needs to be provided to the call to UpgradeToSslAsync. The code to fetch the identity // lives in the callback for CoreClr but needs to be pulled into this method for UWP. EndpointAddress remoteAddress = RemoteAddress; if (remoteAddress.Identity == null && remoteAddress.Uri != Via) { remoteAddress = new EndpointAddress(Via); } EndpointIdentity identity; if (!_parent.IdentityVerifier.TryGetIdentity(remoteAddress, out identity)) { SecurityTraceRecordHelper.TraceIdentityVerificationFailure(identity: identity, authContext: null, identityVerifier: GetType()); throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning( new MessageSecurityException(SR.Format(SR.IdentityCheckFailedForOutgoingMessage, identity, remoteAddress))); } Contract.Assert(identity.IdentityClaim.ClaimType == ClaimTypes.Dns); string dnsHostName = identity.IdentityClaim.Resource as string; // This is the actual call to negotiate an SSL connection await rtStreamSocket.UpgradeToSslAsync(protectionLevel, new HostName(dnsHostName)).AsTask(); // Verify that we didn't negotiate a protocol lower than the binding configuration specified. No need to check Tls12 // as it will only be negotiated if Tls12 was actually specified. var negotiatedProtectionLevel = rtStreamSocket.Information.ProtectionLevel; if ((negotiatedProtectionLevel == SocketProtectionLevel.Tls11 && (_parent.SslProtocols & SslProtocols.Tls11) == SslProtocols.None) || (negotiatedProtectionLevel == SocketProtectionLevel.Tls10 && (_parent.SslProtocols & SslProtocols.Tls) == SslProtocols.None)) { // Need to dispose StreamSocket as normally SslStream wouldn't end up in a usable state in this situation. As // post-upgrade validation is required in UWP, the connection needs to be Dispose'd to ensure it isn't used. rtStreamSocket.Dispose(); throw new SecurityNegotiationException(SR.Format(SR.SSLProtocolNegotiationFailed, _parent.SslProtocols, negotiatedProtectionLevel)); } X509Certificate2 serverCertificate = null; X509Certificate2[] chainCertificates = null; X509Chain chain = null; try { // Convert the UWP Certificate object to a .Net X509Certificate2. byte[] serverCertificateBlob = rtStreamSocket.Information.ServerCertificate.GetCertificateBlob().ToArray(); serverCertificate = new X509Certificate2(serverCertificateBlob); // The chain building and validation logic is done by SslStream in CoreClr. This section of code is based // on the SslStream implementation to try to maintain behavior parity. chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; var serverIntermediateCertificates = rtStreamSocket.Information.ServerIntermediateCertificates; chainCertificates = new X509Certificate2[serverIntermediateCertificates.Count]; for (int i = 0; i < chainCertificates.Length; i++) { chainCertificates[i] = new X509Certificate2(serverIntermediateCertificates[i].GetCertificateBlob().ToArray()); } chain.ChainPolicy.ExtraStore.AddRange(chainCertificates); chain.Build(serverCertificate); SslPolicyErrors policyErrors = SslPolicyErrors.None; foreach (var serverCertificateError in rtStreamSocket.Information.ServerCertificateErrors) { if (serverCertificateError == ChainValidationResult.InvalidName) { policyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch; continue; } if (serverCertificateError == ChainValidationResult.IncompleteChain) { policyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; } } X509ChainStatus[] chainStatusArray = chain.ChainStatus; if (chainStatusArray != null && chainStatusArray.Length != 0) { policyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; } if (!ValidateRemoteCertificate(this, serverCertificate, chain, policyErrors)) { // Need to dispose StreamSocket as normally SslStream wouldn't end up in a usable state in this situation. As // post-upgrade validation is required in UWP, the connection needs to be Dispose'd to ensure it isn't used. rtStreamSocket.Dispose(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityNegotiationException(SR.ssl_io_cert_validation)); } } finally { serverCertificate?.Dispose(); chain?.Dispose(); if (chainCertificates != null) { foreach (var chainCert in chainCertificates) { chainCert?.Dispose(); } } } } catch (SecurityTokenValidationException tokenValidationException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityNegotiationException(tokenValidationException.Message, tokenValidationException)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( SR.Format(SR.NegotiationFailedIO, ioException.Message), ioException)); } catch (Exception exception) { // In NET Native the WinRT API's can throw the base Exception // class with an HRESULT indicating the issue. However, custom // validation code can also throw Exception, and to be compatible // with the CoreCLR version, we must allow those exceptions to // propagate without wrapping them. We use the simple heuristic // that if an HRESULT has been set to other than the default, // the exception should be wrapped in SecurityNegotiationException. if (exception.HResult == __HResults.COR_E_EXCEPTION) { throw; } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( exception.Message, exception)); } remoteSecurityWrapper.Value = _serverSecurity; return(stream); }
public async Task <Message> ReceiveReplyAsync(TimeoutHelper timeoutHelper) { _timeoutHelper = timeoutHelper; HttpResponseMessage httpResponse = null; HttpRequestException responseException = null; try { httpResponse = await _httpResponseMessageTask; } catch (HttpRequestException requestException) { responseException = requestException; httpResponse = HttpChannelUtilities.ProcessGetResponseWebException(responseException, _httpRequestMessage, _abortReason); } catch (OperationCanceledException) { if (_timeoutHelper.CancellationToken.IsCancellationRequested) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException(SR.Format( SR.HttpRequestTimedOut, _httpRequestMessage.RequestUri, _timeoutHelper.OriginalTimeout))); } else { // Cancellation came from somewhere other than timeoutCts and needs to be handled differently. throw; } } try { HttpInput httpInput = HttpChannelUtilities.ValidateRequestReplyResponse(_httpRequestMessage, httpResponse, _factory, responseException); Message replyMessage = null; if (httpInput != null) { var outException = new OutWrapper <Exception>(); replyMessage = await httpInput.ParseIncomingMessageAsync(outException); Exception exception = outException; Contract.Assert(exception == null, "ParseIncomingMessage should not set an exception after parsing a response message."); } this.TryCompleteHttpRequest(_httpRequestMessage); return(replyMessage); } catch (OperationCanceledException) { if (_timeoutHelper.CancellationToken.IsCancellationRequested) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException(SR.Format( SR.HttpResponseTimedOut, _httpRequestMessage.RequestUri, timeoutHelper.OriginalTimeout))); } else { // Cancellation came from somewhere other than timeoutCts and needs to be handled differently. throw; } } }
internal override async Task<Stream> InitiateUpgradeAsync(Stream stream) { if (stream == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream"); } if (!_isOpen) { Open(TimeSpan.Zero); } var remoteSecurityWrapper = new OutWrapper<SecurityMessageProperty>(); Stream result = await OnInitiateUpgradeAsync(stream, remoteSecurityWrapper); _remoteSecurity = remoteSecurityWrapper; _securityUpgraded = true; return result; }
internal override async Task OpenAsync(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); base.Open(timeoutHelper.RemainingTime()); OutWrapper<TokenImpersonationLevel> impersonationLevelWrapper = new OutWrapper<TokenImpersonationLevel>(); OutWrapper<bool> allowNtlmWrapper = new OutWrapper<bool>(); SecurityUtils.OpenTokenProviderIfRequired(_clientTokenProvider, timeoutHelper.RemainingTime()); _credential = await TransportSecurityHelpers.GetSspiCredentialAsync( _clientTokenProvider, impersonationLevelWrapper, allowNtlmWrapper, timeoutHelper.GetCancellationToken()); _impersonationLevel = impersonationLevelWrapper.Value; _allowNtlm = allowNtlmWrapper; return; }
protected override async Task <Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper <SecurityMessageProperty> remoteSecurity) { NegotiateStream negotiateStream; string targetName; EndpointIdentity identity; if (WcfEventSource.Instance.WindowsStreamSecurityOnInitiateUpgradeIsEnabled()) { WcfEventSource.Instance.WindowsStreamSecurityOnInitiateUpgrade(); } // prepare InitiateUpgradePrepare(stream, out negotiateStream, out targetName, out identity); // authenticate try { await negotiateStream.AuthenticateAsClientAsync(_credential, targetName, _parent.ProtectionLevel, _impersonationLevel); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( SR.Format(SR.NegotiationFailedIO, ioException.Message), ioException)); } remoteSecurity.Value = CreateServerSecurity(negotiateStream); ValidateMutualAuth(identity, negotiateStream, remoteSecurity.Value, _allowNtlm); return(negotiateStream); }
protected abstract Task<Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper<SecurityMessageProperty> remoteSecurity);
protected override Task<Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper<SecurityMessageProperty> remoteSecurity) { throw ExceptionHelper.PlatformNotSupported(ExceptionHelper.WinsdowsStreamSecurityNotSupported); }
protected override async Task<Stream> OnInitiateUpgradeAsync(Stream stream, OutWrapper<SecurityMessageProperty> remoteSecurity) { NegotiateStream negotiateStream; string targetName; EndpointIdentity identity; if (WcfEventSource.Instance.WindowsStreamSecurityOnInitiateUpgradeIsEnabled()) { WcfEventSource.Instance.WindowsStreamSecurityOnInitiateUpgrade(); } // prepare InitiateUpgradePrepare(stream, out negotiateStream, out targetName, out identity); // authenticate try { await negotiateStream.AuthenticateAsClientAsync(_credential, targetName, _parent.ProtectionLevel, _impersonationLevel); } catch (AuthenticationException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message, exception)); } catch (IOException ioException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException( SR.Format(SR.NegotiationFailedIO, ioException.Message), ioException)); } remoteSecurity.Value = CreateServerSecurity(negotiateStream); ValidateMutualAuth(identity, negotiateStream, remoteSecurity.Value, _allowNtlm); return negotiateStream; }
protected override Stream OnInitiateUpgrade(Stream stream, out SecurityMessageProperty remoteSecurity) { OutWrapper<SecurityMessageProperty> remoteSecurityOut = new OutWrapper<SecurityMessageProperty>(); var retVal = OnInitiateUpgradeAsync(stream, remoteSecurityOut).GetAwaiter().GetResult(); remoteSecurity = remoteSecurityOut.Value; return retVal; }
// used by client WindowsStream security (from InitiateUpgrade) public static async Task <NetworkCredential> GetSspiCredentialAsync(SspiSecurityTokenProvider tokenProvider, OutWrapper <TokenImpersonationLevel> impersonationLevel, OutWrapper <bool> allowNtlm, CancellationToken cancellationToken) { OutWrapper <bool> dummyExtractWindowsGroupClaimsWrapper = new OutWrapper <bool>(); return(await GetSspiCredentialAsync(tokenProvider, dummyExtractWindowsGroupClaimsWrapper, impersonationLevel, allowNtlm, cancellationToken)); }
public static async Task <NetworkCredential> GetSspiCredentialAsync(SecurityTokenProviderContainer tokenProvider, OutWrapper <TokenImpersonationLevel> impersonationLevelWrapper, OutWrapper <AuthenticationLevel> authenticationLevelWrapper, CancellationToken cancellationToken) { OutWrapper <bool> allowNtlmWrapper = new OutWrapper <bool>(); NetworkCredential result = await GetSspiCredentialAsync(tokenProvider.TokenProvider as SspiSecurityTokenProvider, impersonationLevelWrapper, allowNtlmWrapper, cancellationToken); authenticationLevelWrapper.Value = allowNtlmWrapper.Value ? AuthenticationLevel.MutualAuthRequested : AuthenticationLevel.MutualAuthRequired; return(result); }
public static async Task <bool> InitiateUpgradeAsync(StreamUpgradeInitiator upgradeInitiator, OutWrapper <IConnection> connectionWrapper, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeSpan timeout) { IConnection connection = connectionWrapper.Value; string upgradeContentType = upgradeInitiator.GetNextUpgrade(); while (upgradeContentType != null) { EncodedUpgrade encodedUpgrade = new EncodedUpgrade(upgradeContentType); // write upgrade request framing for synchronization await connection.WriteAsync(encodedUpgrade.EncodedBytes, 0, encodedUpgrade.EncodedBytes.Length, true, timeout); byte[] buffer = new byte[1]; // read upgrade response framing int size = await connection.ReadAsync(buffer, 0, buffer.Length, timeout); if (!ValidateUpgradeResponse(buffer, size, decoder)) // we have a problem { return(false); } // initiate wire upgrade ConnectionStream connectionStream = new ConnectionStream(connection, defaultTimeouts); Stream upgradedStream = await upgradeInitiator.InitiateUpgradeAsync(connectionStream); // and re-wrap connection connection = new StreamConnection(upgradedStream, connectionStream); connectionWrapper.Value = connection; upgradeContentType = upgradeInitiator.GetNextUpgrade(); } return(true); }
public async Task<Message> ParseIncomingMessageAsync(HttpRequestMessage httpRequestMessage, OutWrapper<Exception> requestException) { Message message = null; requestException.Value = null; bool throwing = true; try { ValidateContentType(); if (!this.HasContent) { if (_messageEncoder.MessageVersion == MessageVersion.None) { message = new NullMessage(); } else { return null; } } else { Stream stream = this.GetInputStream(true); if (_streamed) { message = ReadStreamedMessage(stream); } else if (this.ContentLength == -1) { message = ReadChunkedBufferedMessage(stream); } else { if (httpRequestMessage == null) { message = await ReadBufferedMessageAsync(stream); } else { message = await ReadBufferedMessageAsync(httpRequestMessage); } } } requestException.Value = ProcessHttpAddressing(message); throwing = false; return message; } finally { if (throwing) { Close(); } } }