Exemplo n.º 1
0
            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);
            }
Exemplo n.º 2
0
        // 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
        }
Exemplo n.º 4
0
        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));
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 9
0
        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;
            }
Exemplo n.º 11
0
        // 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);
        }
Exemplo n.º 12
0
        // 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);
        }
Exemplo n.º 13
0
        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);
        }
Exemplo n.º 14
0
        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;
        }
Exemplo n.º 15
0
 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);
Exemplo n.º 18
0
        // 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));
        }
Exemplo n.º 19
0
 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);
        }
Exemplo n.º 21
0
                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;
            }
Exemplo n.º 29
0
        // 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));
        }
Exemplo n.º 30
0
        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);
        }
Exemplo n.º 31
0
        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);
        }
Exemplo n.º 32
0
        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();
                }
            }
        }