示例#1
0
        private IConnection SendPreamble(IConnection connection, ArraySegment <byte> preamble, ref TimeoutHelper timeoutHelper)
        {
            this.decoder = new ClientDuplexDecoder(0L);
            byte[] buffer = new byte[1];
            connection.Write(preamble.Array, preamble.Offset, preamble.Count, true, timeoutHelper.RemainingTime());
            if (this.upgrade != null)
            {
                IStreamUpgradeChannelBindingProvider property = this.upgrade.GetProperty <IStreamUpgradeChannelBindingProvider>();
                StreamUpgradeInitiator upgradeInitiator       = this.upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via);
                upgradeInitiator.Open(timeoutHelper.RemainingTime());
                if (!ConnectionUpgradeHelper.InitiateUpgrade(upgradeInitiator, ref connection, this.decoder, this, ref timeoutHelper))
                {
                    ConnectionUpgradeHelper.DecodeFramingFault(this.decoder, connection, this.Via, base.MessageEncoder.ContentType, ref timeoutHelper);
                }
                if ((property != null) && property.IsChannelBindingSupportEnabled)
                {
                    base.SetChannelBinding(property.GetChannelBinding(upgradeInitiator, ChannelBindingKind.Endpoint));
                }
                this.SetRemoteSecurity(upgradeInitiator);
                upgradeInitiator.Close(timeoutHelper.RemainingTime());
                connection.Write(SessionEncoder.PreambleEndBytes, 0, SessionEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime());
            }
            int count = connection.Read(buffer, 0, buffer.Length, timeoutHelper.RemainingTime());

            if (!ConnectionUpgradeHelper.ValidatePreambleResponse(buffer, count, this.decoder, this.Via))
            {
                ConnectionUpgradeHelper.DecodeFramingFault(this.decoder, connection, this.Via, base.MessageEncoder.ContentType, ref timeoutHelper);
            }
            return(connection);
        }
示例#2
0
        private IConnection SendPreamble(IConnection connection, ref TimeoutHelper timeoutHelper, ClientFramingDecoder decoder, out SecurityMessageProperty remoteSecurity)
        {
            connection.Write(this.Preamble, 0, this.Preamble.Length, true, timeoutHelper.RemainingTime());
            if (this.upgrade != null)
            {
                IStreamUpgradeChannelBindingProvider property = this.upgrade.GetProperty <IStreamUpgradeChannelBindingProvider>();
                StreamUpgradeInitiator upgradeInitiator       = this.upgrade.CreateUpgradeInitiator(base.RemoteAddress, base.Via);
                if (!ConnectionUpgradeHelper.InitiateUpgrade(upgradeInitiator, ref connection, decoder, this, ref timeoutHelper))
                {
                    ConnectionUpgradeHelper.DecodeFramingFault(decoder, connection, base.Via, this.messageEncoder.ContentType, ref timeoutHelper);
                }
                if ((property != null) && property.IsChannelBindingSupportEnabled)
                {
                    this.channelBindingToken = property.GetChannelBinding(upgradeInitiator, ChannelBindingKind.Endpoint);
                }
                remoteSecurity = StreamSecurityUpgradeInitiator.GetRemoteSecurity(upgradeInitiator);
                connection.Write(ClientSingletonEncoder.PreambleEndBytes, 0, ClientSingletonEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime());
            }
            else
            {
                remoteSecurity = null;
            }
            byte[] buffer = new byte[1];
            int    count  = connection.Read(buffer, 0, buffer.Length, timeoutHelper.RemainingTime());

            if (!ConnectionUpgradeHelper.ValidatePreambleResponse(buffer, count, decoder, base.Via))
            {
                ConnectionUpgradeHelper.DecodeFramingFault(decoder, connection, base.Via, this.messageEncoder.ContentType, ref timeoutHelper);
            }
            return(connection);
        }
        internal IConnection SendPreamble(IConnection connection, ref TimeoutHelper timeoutHelper,
                                          ClientFramingDecoder decoder, out SecurityMessageProperty remoteSecurity)
        {
            connection.Write(Preamble, 0, Preamble.Length, true, timeoutHelper.RemainingTime());

            if (_upgrade != null)
            {
                IStreamUpgradeChannelBindingProvider channelBindingProvider = _upgrade.GetProperty <IStreamUpgradeChannelBindingProvider>();

                StreamUpgradeInitiator upgradeInitiator = _upgrade.CreateUpgradeInitiator(this.RemoteAddress, this.Via);

                if (!ConnectionUpgradeHelper.InitiateUpgrade(upgradeInitiator, ref connection, decoder,
                                                             this, ref timeoutHelper))
                {
                    ConnectionUpgradeHelper.DecodeFramingFault(decoder, connection, Via, _messageEncoder.ContentType, ref timeoutHelper);
                }

#if FEATURE_CORECLR // ExtendedProtection
                if (channelBindingProvider != null && channelBindingProvider.IsChannelBindingSupportEnabled)
                {
                    _channelBindingToken = channelBindingProvider.GetChannelBinding(upgradeInitiator, ChannelBindingKind.Endpoint);
                }
#endif // FEATURE_CORECLR // ExtendedProtection

                remoteSecurity = StreamSecurityUpgradeInitiator.GetRemoteSecurity(upgradeInitiator);

                connection.Write(ClientSingletonEncoder.PreambleEndBytes, 0,
                                 ClientSingletonEncoder.PreambleEndBytes.Length, true, timeoutHelper.RemainingTime());
            }
            else
            {
                remoteSecurity = null;
            }

            // read ACK
            byte[] ackBuffer    = new byte[1];
            int    ackBytesRead = connection.Read(ackBuffer, 0, ackBuffer.Length, timeoutHelper.RemainingTime());
            if (!ConnectionUpgradeHelper.ValidatePreambleResponse(ackBuffer, ackBytesRead, decoder, this.Via))
            {
                ConnectionUpgradeHelper.DecodeFramingFault(decoder, connection, Via, _messageEncoder.ContentType, ref timeoutHelper);
            }

            return(connection);
        }
        public IConnection CompletePreamble(TimeSpan timeout)
        {
            int           num;
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            if (!this.transportSettings.MessageEncoderFactory.Encoder.IsContentTypeSupported(this.decoder.ContentType))
            {
                this.SendFault("http://schemas.microsoft.com/ws/2006/05/framing/faults/ContentTypeInvalid", ref timeoutHelper);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(System.ServiceModel.SR.GetString("ContentTypeMismatch", new object[] { this.decoder.ContentType, this.transportSettings.MessageEncoderFactory.Encoder.ContentType })));
            }
            StreamUpgradeAcceptor upgradeAcceptor         = null;
            StreamUpgradeProvider upgrade                 = this.transportSettings.Upgrade;
            IStreamUpgradeChannelBindingProvider property = null;

            if (upgrade != null)
            {
                property        = upgrade.GetProperty <IStreamUpgradeChannelBindingProvider>();
                upgradeAcceptor = upgrade.CreateUpgradeAcceptor();
            }
            IConnection connection = base.Connection;

Label_00B1:
            if (this.size == 0)
            {
                this.offset = 0;
                this.size   = connection.Read(this.connectionBuffer, 0, this.connectionBuffer.Length, timeoutHelper.RemainingTime());
                if (this.size == 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.decoder.CreatePrematureEOFException());
                }
            }
Label_0101:
            num = this.decoder.Decode(this.connectionBuffer, this.offset, this.size);
            if (num > 0)
            {
                this.offset += num;
                this.size   -= num;
            }
            switch (this.decoder.CurrentState)
            {
            case ServerSingletonDecoder.State.UpgradeRequest:
            {
                if (upgradeAcceptor == null)
                {
                    this.SendFault("http://schemas.microsoft.com/ws/2006/05/framing/faults/UpgradeInvalid", ref timeoutHelper);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(System.ServiceModel.SR.GetString("UpgradeRequestToNonupgradableService", new object[] { this.decoder.Upgrade })));
                }
                if (!upgradeAcceptor.CanUpgrade(this.decoder.Upgrade))
                {
                    this.SendFault("http://schemas.microsoft.com/ws/2006/05/framing/faults/UpgradeInvalid", ref timeoutHelper);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(System.ServiceModel.SR.GetString("UpgradeProtocolNotSupported", new object[] { this.decoder.Upgrade })));
                }
                connection.Write(ServerSingletonEncoder.UpgradeResponseBytes, 0, ServerSingletonEncoder.UpgradeResponseBytes.Length, true, timeoutHelper.RemainingTime());
                IConnection innerConnection = connection;
                if (this.size > 0)
                {
                    innerConnection = new PreReadConnection(innerConnection, this.connectionBuffer, this.offset, this.size);
                }
                try
                {
                    connection            = InitialServerConnectionReader.UpgradeConnection(innerConnection, upgradeAcceptor, this.transportSettings);
                    this.connectionBuffer = connection.AsyncReadBuffer;
                    if ((property != null) && property.IsChannelBindingSupportEnabled)
                    {
                        this.channelBindingToken = property.GetChannelBinding(upgradeAcceptor, ChannelBindingKind.Endpoint);
                    }
                    goto Label_02C0;
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }
                    this.WriteAuditFailure(upgradeAcceptor as StreamSecurityUpgradeAcceptor, exception);
                    throw;
                }
                break;
            }

            case ServerSingletonDecoder.State.Start:
                break;

            default:
                goto Label_02C0;
            }
            this.SetupSecurityIfNecessary(upgradeAcceptor);
            connection.Write(ServerSessionEncoder.AckResponseBytes, 0, ServerSessionEncoder.AckResponseBytes.Length, true, timeoutHelper.RemainingTime());
            return(connection);

Label_02C0:
            if (this.size != 0)
            {
                goto Label_0101;
            }
            goto Label_00B1;
        }
示例#5
0
        public async Task <IConnection> CompletePreambleAsync(TimeSpan timeout)
        {
            var timeoutHelper = new TimeoutHelper(timeout);
            var parent        = this;

            if (!transportSettings.MessageEncoderFactory.Encoder.IsContentTypeSupported(Decoder.ContentType))
            {
                SendFault(FramingEncodingString.ContentTypeInvalidFault, ref timeoutHelper);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.Format(
                                                                                                    SR.ContentTypeMismatch, Decoder.ContentType, parent.transportSettings.MessageEncoderFactory.Encoder.ContentType)));
            }

            IStreamUpgradeChannelBindingProvider channelBindingProvider = null;
            StreamUpgradeAcceptor upgradeAcceptor = null;

            if (transportSettings.Upgrade != null)
            {
                channelBindingProvider = transportSettings.Upgrade.GetProperty <IStreamUpgradeChannelBindingProvider>();
                upgradeAcceptor        = transportSettings.Upgrade.CreateUpgradeAcceptor();
            }

            var          currentConnection = Connection;
            UpgradeState upgradeState      = UpgradeState.None;

            while (true)
            {
                if (size == 0 && CanReadAndDecode(upgradeState))
                {
                    size = await currentConnection.ReadAsync(0, connectionBuffer.Length, timeoutHelper.RemainingTime());

                    if (size == 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Decoder.CreatePrematureEOFException());
                    }
                }

                while (true)
                {
                    if (CanReadAndDecode(upgradeState))
                    {
                        int bytesRead = Decoder.Decode(connectionBuffer, offset, size);
                        if (bytesRead > 0)
                        {
                            offset += bytesRead;
                            size   -= bytesRead;
                        }
                    }

                    switch (Decoder.CurrentState)
                    {
                    case ServerSingletonDecoder.State.UpgradeRequest:
                        switch (upgradeState)
                        {
                        case UpgradeState.None:
                            //change the state so that we don't read/decode until it is safe
                            ChangeUpgradeState(ref upgradeState, UpgradeState.VerifyingUpgradeRequest);
                            break;

                        case UpgradeState.VerifyingUpgradeRequest:
                            if (upgradeAcceptor == null)
                            {
                                SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper);
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                          new ProtocolException(SR.Format(SR.UpgradeRequestToNonupgradableService, Decoder.Upgrade)));
                            }

                            if (!upgradeAcceptor.CanUpgrade(Decoder.Upgrade))
                            {
                                SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper);
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.Format(SR.UpgradeProtocolNotSupported, Decoder.Upgrade)));
                            }

                            ChangeUpgradeState(ref upgradeState, UpgradeState.WritingUpgradeAck);
                            // accept upgrade
                            await currentConnection.WriteAsync(ServerSingletonEncoder.UpgradeResponseBytes, 0, ServerSingletonEncoder.UpgradeResponseBytes.Length,
                                                               true, timeoutHelper.RemainingTime());

                            ChangeUpgradeState(ref upgradeState, UpgradeState.UpgradeAckSent);
                            break;

                        case UpgradeState.UpgradeAckSent:
                            IConnection connectionToUpgrade = currentConnection;
                            if (size > 0)
                            {
                                connectionToUpgrade = new PreReadConnection(connectionToUpgrade, connectionBuffer, offset, size);
                            }
                            ChangeUpgradeState(ref upgradeState, UpgradeState.BeginUpgrade);
                            break;

                        case UpgradeState.BeginUpgrade:
                            try
                            {
                                currentConnection = await InitialServerConnectionReader.UpgradeConnectionAsync(currentConnection, upgradeAcceptor, transportSettings);

                                connectionBuffer = currentConnection.AsyncReadBuffer;
                                if (channelBindingProvider != null &&
                                    channelBindingProvider.IsChannelBindingSupportEnabled &&
                                    channelBindingToken == null)        //first one wins in the case of multiple upgrades.
                                {
                                    channelBindingToken = channelBindingProvider.GetChannelBinding(upgradeAcceptor, ChannelBindingKind.Endpoint);
                                }
                                ChangeUpgradeState(ref upgradeState, UpgradeState.EndUpgrade);
                                ChangeUpgradeState(ref upgradeState, UpgradeState.UpgradeComplete);
                            }
                            catch (Exception exception)
                            {
                                if (Fx.IsFatal(exception))
                                {
                                    throw;
                                }

                                WriteAuditFailure(upgradeAcceptor as StreamSecurityUpgradeAcceptor, exception);
                                throw;
                            }
                            break;

                        case UpgradeState.UpgradeComplete:
                            //Client is doing more than one upgrade, reset the state
                            ChangeUpgradeState(ref upgradeState, UpgradeState.VerifyingUpgradeRequest);
                            break;
                        }
                        break;

                    case ServerSingletonDecoder.State.Start:
                        SetupSecurityIfNecessary(upgradeAcceptor);

                        if (upgradeState == UpgradeState.UpgradeComplete ||  //We have done at least one upgrade, but we are now done.
                            upgradeState == UpgradeState.None)       //no upgrade, just send the preample end bytes
                        {
                            ChangeUpgradeState(ref upgradeState, UpgradeState.WritingPreambleEnd);
                            // we've finished the preamble. Ack and return.
                            await currentConnection.WriteAsync(ServerSessionEncoder.AckResponseBytes, 0, ServerSessionEncoder.AckResponseBytes.Length,
                                                               true, timeoutHelper.RemainingTime());

                            //terminal state
                            ChangeUpgradeState(ref upgradeState, UpgradeState.PreambleEndSent);
                        }

                        //we are done, this.currentConnection is the upgraded connection
                        return(currentConnection);
                    }

                    if (size == 0)
                    {
                        break;
                    }
                }
            }
        }