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); }
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; }
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; } } } }