예제 #1
0
        private void OnReadHeaderComplete(TransportAsyncCallbackArgs args)
        {
            if (args.Exception != null)
            {
                CompleteOnException(args);
                return;
            }

            try
            {
                ProtocolHeader receivedHeader = new ProtocolHeader();
                receivedHeader.Decode(new ByteBuffer(args.Buffer, args.Offset, args.Count));
                if (!receivedHeader.Equals(_sentHeader))
                {
                    throw new AmqpException(AmqpErrorCode.NotImplemented, $"The requested protocol version {_sentHeader} is not supported. The supported version is {receivedHeader}");
                }

                SaslTransportProvider provider = _amqpSettings.GetTransportProvider <SaslTransportProvider>();
                var transport = provider.CreateTransport(args.Transport, true);
                _tcs.TrySetResult(transport);
            }
            catch (Exception ex)
            {
                args.Exception = ex;
                CompleteOnException(args);
            }
        }
예제 #2
0
        public static AmqpSettings CreateAmqpSettings(
            Version amqpVersion,
            bool useSslStreamSecurity,
            bool hasTokenProvider,
            string sslHostName    = null,
            bool useWebSockets    = false,
            bool sslStreamUpgrade = false,
            System.Net.NetworkCredential networkCredential = null,
            System.Net.Security.RemoteCertificateValidationCallback certificateValidationCallback = null,
            bool forceTokenProvider = true)
        {
            AmqpSettings settings = new AmqpSettings();

            if (useSslStreamSecurity && !useWebSockets && sslStreamUpgrade)
            {
                var tlsSettings = new TlsTransportSettings
                {
                    CertificateValidationCallback = certificateValidationCallback,
                    TargetHost = sslHostName
                };

                var tlsProvider = new TlsTransportProvider(tlsSettings);
                tlsProvider.Versions.Add(new AmqpVersion(amqpVersion));
                settings.TransportProviders.Add(tlsProvider);
            }

            if (hasTokenProvider || networkCredential != null)
            {
                SaslTransportProvider saslProvider = new SaslTransportProvider();
                saslProvider.Versions.Add(new AmqpVersion(amqpVersion));
                settings.TransportProviders.Add(saslProvider);

                if (forceTokenProvider)
                {
                    saslProvider.AddHandler(new SaslAnonymousHandler(CbsSaslMechanismName));
                }
                else if (networkCredential != null)
                {
                    var plainHandler = new SaslPlainHandler
                    {
                        AuthenticationIdentity = networkCredential.UserName,
                        Password = networkCredential.Password
                    };
                    saslProvider.AddHandler(plainHandler);
                }
                else
                {
                    // old client behavior: keep it for validation only
                    saslProvider.AddHandler(new SaslExternalHandler());
                }
            }

            AmqpTransportProvider amqpProvider = new AmqpTransportProvider();

            amqpProvider.Versions.Add(new AmqpVersion(amqpVersion));
            settings.TransportProviders.Add(amqpProvider);

            return(settings);
        }
예제 #3
0
        public static AmqpSettings GetDefaultAmqpSettings(
            string iotHubHostName,
            IAuthenticator authenticator,
            IClientCredentialsFactory identityFactory,
            ILinkHandlerProvider linkHandlerProvider,
            IConnectionProvider connectionProvider,
            ICredentialsCache credentialsCache)
        {
            Preconditions.CheckNotNull(authenticator, nameof(authenticator));
            Preconditions.CheckNotNull(identityFactory, nameof(identityFactory));
            Preconditions.CheckNotNull(linkHandlerProvider, nameof(linkHandlerProvider));
            Preconditions.CheckNonWhiteSpace(iotHubHostName, nameof(iotHubHostName));
            Preconditions.CheckNotNull(connectionProvider, nameof(connectionProvider));

            var settings = new AmqpSettings
            {
                AllowAnonymousConnection = true,
                RequireSecureTransport   = true,
                RuntimeProvider          = new AmqpRuntimeProvider(linkHandlerProvider, true, identityFactory, authenticator, iotHubHostName, connectionProvider, credentialsCache)
            };

            // Add all transport providers we want to support.
            AddSaslProvider();
            AddAmqpProvider();
            return(settings);

            void AddSaslProvider()
            {
                var saslProvider = new SaslTransportProvider
                {
                    MaxFrameSize = 65536,
                };

                saslProvider.Versions.Add(Constants.AmqpVersion100);

                // TODO: Verify if this handler still needs to be added. It looks like at some point in the past
                //       SASL EXTERNAL was used to do CBS. Since then we have moved away from that and are using
                //       SASL ANONYMOUS to do CBS. So this may not be needed anymore depending on back-compat
                //       needs (i.e. old clients that are still using EXTERNAL for CBS).
                // saslProvider.AddHandler(new SaslExternalHandler());

                saslProvider.AddHandler(new SaslAnonymousHandler()); // CBS for other clients

                // This handler implements SAS key based auth.
                saslProvider.AddHandler(new SaslPlainHandler(new EdgeHubSaslPlainAuthenticator(authenticator, identityFactory, iotHubHostName)));

                settings.TransportProviders.Add(saslProvider);
            }

            void AddAmqpProvider()
            {
                var amqpProvider = new AmqpTransportProvider();

                amqpProvider.Versions.Add(Constants.AmqpVersion100);
                settings.TransportProviders.Add(amqpProvider);
            }
        }
예제 #4
0
        public async Task OpenAsync(TimeSpan timeout, bool useWebSocket, X509Certificate2 clientCert)
        {
            var hostName = _uri.Host;

            var tcpSettings = new TcpTransportSettings {
                Host = hostName, Port = _uri.Port != -1 ? _uri.Port : AmqpConstants.DefaultSecurePort
            };

            TransportSettings = new TlsTransportSettings(tcpSettings)
            {
                TargetHost  = hostName,
                Certificate = clientCert
            };

            TransportBase transport;

            if (useWebSocket)
            {
                transport = await CreateClientWebSocketTransportAsync(timeout).ConfigureAwait(false);

                SaslTransportProvider provider = _amqpSettings.GetTransportProvider <SaslTransportProvider>();
                if (provider != null)
                {
                    _sentHeader = new ProtocolHeader(provider.ProtocolId, provider.DefaultVersion);
                    ByteBuffer buffer = new ByteBuffer(new byte[AmqpConstants.ProtocolHeaderSize]);
                    _sentHeader.Encode(buffer);

                    var args = new TransportAsyncCallbackArgs();
                    args.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Length);
                    args.CompletedCallback = OnWriteHeaderComplete;
                    args.Transport         = transport;
                    transport.WriteAsync(args);

                    _tcs      = new TaskCompletionSource <TransportBase>();
                    transport = await _tcs.Task.ConfigureAwait(false);

                    await transport.OpenAsync(timeout).ConfigureAwait(false);
                }
            }
            else
            {
                var tcpInitiator = new AmqpTransportInitiator(_amqpSettings, TransportSettings);
                transport = await tcpInitiator.ConnectTaskAsync(timeout).ConfigureAwait(false);
            }

            AmqpConnection         = new AmqpConnection(transport, _amqpSettings, AmqpConnectionSettings);
            AmqpConnection.Closed += OnConnectionClosed;
            await AmqpConnection.OpenAsync(timeout).ConfigureAwait(false);

            _isConnectionClosed = false;
        }
예제 #5
0
            private static AmqpSettings CreateAmqpSettings()
            {
                AmqpSettings          amqpSetting           = new AmqpSettings();
                SaslTransportProvider saslTransportProvider = new SaslTransportProvider();

                saslTransportProvider.Versions.Add(AmqpConstants.DefaultProtocolVersion);
                saslTransportProvider.AddHandler(new SaslExternalHandler());
                amqpSetting.TransportProviders.Add(saslTransportProvider);
                AmqpTransportProvider amqpTransportProvider = new AmqpTransportProvider();

                amqpTransportProvider.Versions.Add(AmqpConstants.DefaultProtocolVersion);
                amqpSetting.TransportProviders.Add(amqpTransportProvider);
                return(amqpSetting);
            }
예제 #6
0
        private void OnReadHeaderComplete(TransportAsyncCallbackArgs args)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, $"{nameof(OnReadHeaderComplete)}");
            }

            if (args.Exception != null)
            {
                CompleteOnException(args);
                return;
            }

            try
            {
                ProtocolHeader receivedHeader = new ProtocolHeader();
                receivedHeader.Decode(new ByteBuffer(args.Buffer, args.Offset, args.Count));

                if (Logging.IsEnabled)
                {
                    Logging.Info(this, $"{nameof(OnReadHeaderComplete)}: Received Protocol Header: {receivedHeader.ToString()}");
                }

                if (!receivedHeader.Equals(SentProtocolHeader))
                {
                    throw new AmqpException(AmqpErrorCode.NotImplemented, $"The requested protocol version {SentProtocolHeader} is not supported. The supported version is {receivedHeader}");
                }

                SaslTransportProvider provider = AmqpSettings.GetTransportProvider <SaslTransportProvider>();
                var transport = provider.CreateTransport(args.Transport, true);
                if (Logging.IsEnabled)
                {
                    Logging.Info(this, $"{nameof(OnReadHeaderComplete)}: Created SaslTransportHandler ");
                }
                TaskCompletionSource.TrySetResult(transport);
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, $"{nameof(OnReadHeaderComplete)}");
                }
            }
            catch (Exception ex)
            {
                args.Exception = ex;
                CompleteOnException(args);
            }
        }
예제 #7
0
        public override AmqpSettings CreateAmqpSettings(string idScope)
        {
            var settings = new AmqpSettings();

            var saslProvider = new SaslTransportProvider();

            saslProvider.Versions.Add(AmqpConstants.DefaultProtocolVersion);
            settings.TransportProviders.Add(saslProvider);

            byte[]         ekBuffer   = _security.GetEndorsementKey();
            byte[]         srkBuffer  = _security.GetStorageRootKey();
            SaslTpmHandler tpmHandler = new SaslTpmHandler(ekBuffer, srkBuffer, idScope, _security);

            saslProvider.AddHandler(tpmHandler);

            return(settings);
        }
        public static AmqpSettings CreateAmqpSettings(
            Version amqpVersion,
            bool useSslStreamSecurity,
            string sslHostName    = null,
            bool useWebSockets    = false,
            bool sslStreamUpgrade = false,
            System.Net.NetworkCredential networkCredential = null)
        {
            var amqpSettings = new AmqpSettings();

            if (useSslStreamSecurity && !useWebSockets && sslStreamUpgrade)
            {
                var tlsSettings = new TlsTransportSettings
                {
                    TargetHost = sslHostName
                };

                var tlsProvider = new TlsTransportProvider(tlsSettings);
                tlsProvider.Versions.Add(new AmqpVersion(amqpVersion));
                amqpSettings.TransportProviders.Add(tlsProvider);
            }

            if (networkCredential != null)
            {
                var saslTransportProvider = new SaslTransportProvider();
                saslTransportProvider.Versions.Add(new AmqpVersion(amqpVersion));
                amqpSettings.TransportProviders.Add(saslTransportProvider);

                if (networkCredential != null)
                {
                    var plainHandler = new SaslPlainHandler
                    {
                        AuthenticationIdentity = networkCredential.UserName,
                        Password = networkCredential.Password
                    };
                    saslTransportProvider.AddHandler(plainHandler);
                }
            }

            var amqpTransportProvider = new AmqpTransportProvider();

            amqpTransportProvider.Versions.Add(new AmqpVersion(amqpVersion));
            amqpSettings.TransportProviders.Add(amqpTransportProvider);

            return(amqpSettings);
        }
        /// <summary>
        ///   Creates the settings to use for AMQP communication.
        /// </summary>
        ///
        /// <param name="amqpVersion">The version of AMQP to be used.</param>
        ///
        /// <returns>The settings for AMQP to use for communication with the Service Bus service.</returns>
        ///
        private static AmqpSettings CreateAmpqSettings(Version amqpVersion)
        {
            var saslProvider = new SaslTransportProvider();

            saslProvider.Versions.Add(new AmqpVersion(amqpVersion));
            saslProvider.AddHandler(new SaslAnonymousHandler(CbsSaslHandlerName));

            var amqpProvider = new AmqpTransportProvider();

            amqpProvider.Versions.Add(new AmqpVersion(amqpVersion));

            var settings = new AmqpSettings();

            settings.TransportProviders.Add(saslProvider);
            settings.TransportProviders.Add(amqpProvider);

            return(settings);
        }
예제 #10
0
        public static AmqpSettings GetAmqpSettings(bool client, string sslValue, bool doSslUpgrade, params SaslHandler[] saslHandlers)
        {
            AmqpSettings settings = new AmqpSettings();

#if !WINDOWS_UWP
            if ((client && doSslUpgrade) || (!client && sslValue != null))
            {
                TlsTransportSettings tlsSettings = new TlsTransportSettings();
                if (client)
                {
                    tlsSettings.TargetHost = sslValue;
                    tlsSettings.CertificateValidationCallback = (s, c, h, e) => { return(true); };
                }
                else
                {
                    tlsSettings.IsInitiator = false;
                    tlsSettings.Certificate = GetCertificate(sslValue);;
                }

                TlsTransportProvider tlsProvider = new TlsTransportProvider(tlsSettings);
                tlsProvider.Versions.Add(new AmqpVersion(1, 0, 0));
                settings.TransportProviders.Add(tlsProvider);
            }
#endif

            if (saslHandlers != null && saslHandlers.Length >= 1 && saslHandlers[0] != null)
            {
                SaslTransportProvider saslProvider = new SaslTransportProvider();
                saslProvider.Versions.Add(new AmqpVersion(1, 0, 0));
                foreach (SaslHandler handler in saslHandlers)
                {
                    saslProvider.AddHandler(handler);
                }

                settings.TransportProviders.Add(saslProvider);
            }

            AmqpTransportProvider amqpProvider = new AmqpTransportProvider();
            amqpProvider.Versions.Add(new AmqpVersion(1, 0, 0));
            settings.TransportProviders.Add(amqpProvider);

            return(settings);
        }
예제 #11
0
        public override AmqpSettings CreateAmqpSettings(string idScope)
        {
            var settings = new AmqpSettings();

            var saslProvider = new SaslTransportProvider();

            saslProvider.Versions.Add(AmqpConstants.DefaultProtocolVersion);
            settings.TransportProviders.Add(saslProvider);

            SaslPlainHandler saslHandler = new SaslPlainHandler();

            saslHandler.AuthenticationIdentity = $"{idScope}/registrations/{_security.GetRegistrationID()}";
            string key = _security.GetPrimaryKey();

            saslHandler.Password = ProvisioningSasBuilder.BuildSasSignature("registration", key, saslHandler.AuthenticationIdentity, TimeSpan.FromDays(1));
            saslProvider.AddHandler(saslHandler);

            return(settings);
        }
        internal AmqpSettings CreateAmqpSettings(string sslHostName)
        {
            AmqpSettings amqpSetting = new AmqpSettings();

            if (this.SslStreamUpgrade)
            {
                TlsTransportSettings tlsTransportSetting = new TlsTransportSettings()
                {
                    CertificateValidationCallback = this.CertificateValidationCallback,
                    TargetHost = sslHostName
                };
                TlsTransportProvider tlsTransportProvider = new TlsTransportProvider(tlsTransportSetting);
                tlsTransportProvider.Versions.Add(new Microsoft.ServiceBus.Messaging.Amqp.AmqpVersion(1, 0, 0));
                amqpSetting.TransportProviders.Add(tlsTransportProvider);
            }
            if (this.TokenProvider != null || this.NetworkCredential != null)
            {
                SaslTransportProvider saslTransportProvider = new SaslTransportProvider();
                saslTransportProvider.Versions.Add(new Microsoft.ServiceBus.Messaging.Amqp.AmqpVersion(1, 0, 0));
                amqpSetting.TransportProviders.Add(saslTransportProvider);
                if (this.NetworkCredential == null)
                {
                    saslTransportProvider.AddHandler(new SaslExternalHandler());
                }
                else
                {
                    SaslPlainHandler saslPlainHandler = new SaslPlainHandler()
                    {
                        AuthenticationIdentity = this.NetworkCredential.UserName,
                        Password = this.NetworkCredential.Password
                    };
                    saslTransportProvider.AddHandler(saslPlainHandler);
                }
            }
            AmqpTransportProvider amqpTransportProvider = new AmqpTransportProvider();

            amqpTransportProvider.Versions.Add(new Microsoft.ServiceBus.Messaging.Amqp.AmqpVersion(this.AmqpVersion));
            amqpSetting.TransportProviders.Add(amqpTransportProvider);
            return(amqpSetting);
        }
예제 #13
0
        public static AmqpSettings GetAmqpSettings(bool client, string sslValue, bool doSslUpgrade, params SaslHandler[] saslHandlers)
        {
            AmqpSettings settings = new AmqpSettings();
            if ((client && doSslUpgrade) || (!client && sslValue != null))
            {
                TlsTransportSettings tlsSettings = new TlsTransportSettings();
                if (client)
                {
                    tlsSettings.TargetHost = sslValue;
                    tlsSettings.CertificateValidationCallback = (s, c, h, e) => { return true; };
                }
                else
                {
                    tlsSettings.IsInitiator = false;
                    tlsSettings.Certificate = GetCertificate(sslValue); ;
                }

                TlsTransportProvider tlsProvider = new TlsTransportProvider(tlsSettings);
                tlsProvider.Versions.Add(new AmqpVersion(1, 0, 0));
                settings.TransportProviders.Add(tlsProvider);
            }

            if (saslHandlers != null && saslHandlers.Length >= 1 && saslHandlers[0] != null)
            {
                SaslTransportProvider saslProvider = new SaslTransportProvider();
                saslProvider.Versions.Add(new AmqpVersion(1, 0, 0));
                foreach (SaslHandler handler in saslHandlers)
                {
                    saslProvider.AddHandler(handler);
                }

                settings.TransportProviders.Add(saslProvider);
            }

            AmqpTransportProvider amqpProvider = new AmqpTransportProvider();
            amqpProvider.Versions.Add(new AmqpVersion(1, 0, 0));
            settings.TransportProviders.Add(amqpProvider);

            return settings;
        }
예제 #14
0
        public void Start()
        {
            // create and initialize AmqpSettings
            AmqpSettings     settings    = new AmqpSettings();
            X509Certificate2 certificate = this.sslValue == null ? null : GetCertificate(this.sslValue);

            settings.RuntimeProvider = this;

            SaslHandler saslHandler;

            if (this.userInfo != null)
            {
                string[] creds     = this.userInfo.Split(':');
                string   usernanme = Uri.UnescapeDataString(creds[0]);
                string   password  = creds.Length == 1 ? string.Empty : Uri.UnescapeDataString(creds[1]);
                saslHandler = new SaslPlainHandler(new TestPlainAuthenticator(this.userInfo, password));
            }
            else
            {
                saslHandler = new SaslAnonymousHandler();
            }

            SaslTransportProvider saslProvider = new SaslTransportProvider(AmqpVersion.V100);

            saslProvider.AddHandler(saslHandler);
            settings.TransportProviders.Add(saslProvider);

            AmqpTransportProvider amqpProvider = new AmqpTransportProvider(AmqpVersion.V100);

            settings.TransportProviders.Add(amqpProvider);

            // create and initialize transport listeners
            TransportListener[] listeners = new TransportListener[this.endpoints.Count];
            for (int i = 0; i < this.endpoints.Count; i++)
            {
                Uri addressUri = new Uri(this.endpoints[i]);

                if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqps, StringComparison.OrdinalIgnoreCase))
                {
                    if (certificate == null)
                    {
                        throw new InvalidOperationException("/cert option was not set when amqps address is specified.");
                    }

                    TcpTransportSettings tcpSettings = new TcpTransportSettings()
                    {
                        Host = addressUri.Host, Port = addressUri.Port
                    };
                    TlsTransportSettings tlsSettings = new TlsTransportSettings(tcpSettings)
                    {
                        Certificate = certificate, IsInitiator = false
                    };
                    listeners[i] = tlsSettings.CreateListener();
                }
                else if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqp, StringComparison.OrdinalIgnoreCase))
                {
                    TcpTransportSettings tcpSettings = new TcpTransportSettings()
                    {
                        Host = addressUri.Host, Port = addressUri.Port
                    };
                    listeners[i] = tcpSettings.CreateListener();
                }
                else if (addressUri.Scheme.Equals("ws", StringComparison.OrdinalIgnoreCase))
                {
                    WebSocketTransportSettings wsSettings = new WebSocketTransportSettings()
                    {
                        Uri = addressUri
                    };
                    listeners[i] = wsSettings.CreateListener();
                }
                else
                {
                    throw new NotSupportedException(addressUri.Scheme);
                }
            }

            this.settings          = settings;
            this.transportListener = new AmqpTransportListener(listeners, settings);
            this.transportListener.Listen(this.OnAcceptTransport);
        }
예제 #15
0
        private async Task <TransportBase> InitializeTransport(TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, $"{nameof(InitializeTransport)}");
            }
            TransportBase transport;

            switch (AmqpTransportSettings.GetTransportType())
            {
            case TransportType.Amqp_WebSocket_Only:
                transport = await CreateClientWebSocketTransportAsync(timeout).ConfigureAwait(false);

                SaslTransportProvider provider = AmqpSettings.GetTransportProvider <SaslTransportProvider>();
                if (provider != null)
                {
                    if (Logging.IsEnabled)
                    {
                        Logging.Info(this, $"{nameof(InitializeTransport)}: Using SaslTransport");
                    }
                    SentProtocolHeader = new ProtocolHeader(provider.ProtocolId, provider.DefaultVersion);
                    ByteBuffer buffer = new ByteBuffer(new byte[AmqpConstants.ProtocolHeaderSize]);
                    SentProtocolHeader.Encode(buffer);

                    TaskCompletionSource = new TaskCompletionSource <TransportBase>();

                    var args = new TransportAsyncCallbackArgs();
                    args.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Length);
                    args.CompletedCallback = OnWriteHeaderComplete;
                    args.Transport         = transport;
                    bool operationPending = transport.WriteAsync(args);

                    if (Logging.IsEnabled)
                    {
                        Logging.Info(this, $"{nameof(InitializeTransport)}: Sent Protocol Header: {SentProtocolHeader.ToString()} operationPending: {operationPending} completedSynchronously: {args.CompletedSynchronously}");
                    }

                    if (!operationPending)
                    {
                        args.CompletedCallback(args);
                    }

                    transport = await TaskCompletionSource.Task.ConfigureAwait(false);

                    await transport.OpenAsync(timeout).ConfigureAwait(false);
                }
                break;

            case TransportType.Amqp_Tcp_Only:
                var amqpTransportInitiator = new AmqpTransportInitiator(AmqpSettings, TlsTransportSettings);
                transport = await amqpTransportInitiator.ConnectTaskAsync(timeout).ConfigureAwait(false);

                break;

            default:
                throw new InvalidOperationException("AmqpTransportSettings must specify WebSocketOnly or TcpOnly");
            }
            if (Logging.IsEnabled)
            {
                Logging.Exit(this, timeout, $"{nameof(InitializeTransport)}");
            }
            return(transport);
        }
예제 #16
0
        public async Task <AmqpConnection> OpenConnectionAsync(Uri addressUri, SaslHandler saslHandler, TimeSpan timeout)
        {
            TransportSettings transportSettings;

            if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqp, StringComparison.OrdinalIgnoreCase))
            {
                transportSettings = new TcpTransportSettings()
                {
                    Host = addressUri.Host,
                    Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultPort
                };
            }
            else if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqps, StringComparison.OrdinalIgnoreCase))
            {
                TcpTransportSettings tcpSettings = new TcpTransportSettings()
                {
                    Host = addressUri.Host,
                    Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultSecurePort
                };

                transportSettings = new TlsTransportSettings(tcpSettings)
                {
                    TargetHost = addressUri.Host
                };
            }
#if NET45
            else if (addressUri.Scheme.Equals(WebSocketTransport.WebSockets, StringComparison.OrdinalIgnoreCase) ||
                     addressUri.Scheme.Equals(WebSocketTransport.SecureWebSockets, StringComparison.OrdinalIgnoreCase))
            {
                transportSettings = new WebSocketTransportSettings()
                {
                    Uri = addressUri
                };
            }
#endif
            else
            {
                throw new NotSupportedException(addressUri.Scheme);
            }

            AmqpSettings settings = new AmqpSettings();

            if (saslHandler != null)
            {
                // Provider for "AMQP3100"
                SaslTransportProvider saslProvider = new SaslTransportProvider();
                saslProvider.Versions.Add(new AmqpVersion(1, 0, 0));
                saslProvider.AddHandler(saslHandler);
                settings.TransportProviders.Add(saslProvider);
            }

            // Provider for "AMQP0100"
            AmqpTransportProvider amqpProvider = new AmqpTransportProvider();
            amqpProvider.Versions.Add(new AmqpVersion(new Version(1, 0, 0, 0)));
            settings.TransportProviders.Add(amqpProvider);

            AmqpTransportInitiator initiator = new AmqpTransportInitiator(settings, transportSettings);
            TransportBase          transport = await Task.Factory.FromAsync(
                (c, s) => initiator.BeginConnect(timeout, c, s),
                (r) => initiator.EndConnect(r),
                null);

            try
            {
                AmqpConnectionSettings connectionSettings = new AmqpConnectionSettings()
                {
                    ContainerId = Guid.NewGuid().ToString(),
                    HostName    = addressUri.Host
                };

                AmqpConnection connection = new AmqpConnection(transport, settings, connectionSettings);
                await connection.OpenAsync(timeout);

                return(connection);
            }
            catch
            {
                transport.Abort();
                throw;
            }
        }
        public async Task OpenAsync(TimeSpan timeout, bool useWebSocket, X509Certificate2 clientCert, IWebProxy proxy, RemoteCertificateValidationCallback remoteCerificateValidationCallback)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, $"{nameof(AmqpClientConnection)}.{nameof(OpenAsync)}");
            }

            var hostName = _uri.Host;

            var tcpSettings = new TcpTransportSettings {
                Host = hostName, Port = _uri.Port != -1 ? _uri.Port : AmqpConstants.DefaultSecurePort
            };

            TransportSettings = new TlsTransportSettings(tcpSettings)
            {
                TargetHost  = hostName,
                Certificate = clientCert,
                CertificateValidationCallback = remoteCerificateValidationCallback,
            };

            TransportBase transport;

            if (useWebSocket)
            {
                transport = await CreateClientWebSocketTransportAsync(timeout, proxy).ConfigureAwait(false);

                SaslTransportProvider provider = _amqpSettings.GetTransportProvider <SaslTransportProvider>();
                if (provider != null)
                {
                    if (Logging.IsEnabled)
                    {
                        Logging.Info(this, $"{nameof(AmqpClientConnection)}.{nameof(OpenAsync)}: Using SaslTransport");
                    }

                    _sentHeader = new ProtocolHeader(provider.ProtocolId, provider.DefaultVersion);
                    ByteBuffer buffer = new ByteBuffer(new byte[AmqpConstants.ProtocolHeaderSize]);
                    _sentHeader.Encode(buffer);

                    _tcs = new TaskCompletionSource <TransportBase>();

                    var args = new TransportAsyncCallbackArgs();
                    args.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Length);
                    args.CompletedCallback = OnWriteHeaderComplete;
                    args.Transport         = transport;
                    bool operationPending = transport.WriteAsync(args);

                    if (Logging.IsEnabled)
                    {
                        Logging.Info(this, $"{nameof(AmqpClientConnection)}.{nameof(OpenAsync)}: Sent Protocol Header: {_sentHeader.ToString()} operationPending: {operationPending} completedSynchronously: {args.CompletedSynchronously}");
                    }

                    if (!operationPending)
                    {
                        args.CompletedCallback(args);
                    }

                    transport = await _tcs.Task.ConfigureAwait(false);

                    await transport.OpenAsync(timeout).ConfigureAwait(false);
                }
            }
            else
            {
                var tcpInitiator = new AmqpTransportInitiator(_amqpSettings, TransportSettings);
                transport = await tcpInitiator.ConnectTaskAsync(timeout).ConfigureAwait(false);
            }

            AmqpConnection         = new AmqpConnection(transport, _amqpSettings, AmqpConnectionSettings);
            AmqpConnection.Closed += OnConnectionClosed;
            await AmqpConnection.OpenAsync(timeout).ConfigureAwait(false);

            _isConnectionClosed = false;
        }
        /// <summary>
        /// Performs the tasks needed to build and open a connection to the IoT Hub
        /// service.
        /// </summary>
        /// <param name="serviceEndpoint">The endpoint of the IoT Hub service to connect to.</param>
        /// <param name="iotHubName">The name of the IoT Hub to connect to.</param>
        /// <param name="sharedAccessKeyName">The name of the shared access key being used for authentication.</param>
        /// <param name="sharedAccessKey">The shared access key being used for authentication.</param>
        /// <param name="timeout">The maximum amount of time that establishing the connection should be allowed to take.</param>
        /// <returns>An <see cref="AmqpConnection" /> to the requested IoT Hub.</returns>
        /// <seealso href="https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-amqp-support"/>
        private static async Task <AmqpConnection> CreateAndOpenConnectionAsync(
            Uri serviceEndpoint,
            string iotHubName,
            string sharedAccessKeyName,
            string sharedAccessKey,
            TimeSpan timeout)
        {
            var hostName  = serviceEndpoint.Host;
            var userName  = $"{ sharedAccessKeyName }@sas.root.{ iotHubName }";
            var signature = BuildSignature($"{ hostName }{ serviceEndpoint.AbsolutePath }", sharedAccessKeyName, sharedAccessKey, TimeSpan.FromMinutes(5));
            var port      = 5671;

            // Create the layers of settings needed to establish the connection.

            var amqpVersion = new Version(1, 0, 0, 0);

            var tcpSettings = new TcpTransportSettings
            {
                Host = hostName,
                Port = port,
                ReceiveBufferSize = AmqpConstants.TransportBufferSize,
                SendBufferSize    = AmqpConstants.TransportBufferSize
            };

            var transportSettings = new TlsTransportSettings(tcpSettings)
            {
                TargetHost = hostName,
            };

            var connectionSettings = new AmqpConnectionSettings
            {
                IdleTimeOut  = (uint)TimeSpan.FromMinutes(1).TotalMilliseconds,
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId  = Guid.NewGuid().ToString(),
                HostName     = hostName
            };

            var saslProvider = new SaslTransportProvider();

            saslProvider.Versions.Add(new AmqpVersion(amqpVersion));
            saslProvider.AddHandler(new SaslPlainHandler {
                AuthenticationIdentity = userName, Password = signature
            });

            var amqpProvider = new AmqpTransportProvider();

            amqpProvider.Versions.Add(new AmqpVersion(amqpVersion));

            var amqpSettings = new AmqpSettings();

            amqpSettings.TransportProviders.Add(saslProvider);
            amqpSettings.TransportProviders.Add(amqpProvider);

            // Create and open the connection, respecting the timeout constraint
            // that was received.

            var stopWatch = Stopwatch.StartNew();
            var initiator = new AmqpTransportInitiator(amqpSettings, transportSettings);
            var transport = await initiator.ConnectTaskAsync(timeout).ConfigureAwait(false);

            try
            {
                var connection = new AmqpConnection(transport, amqpSettings, connectionSettings);
                await connection.OpenAsync(timeout.Subtract(stopWatch.Elapsed)).ConfigureAwait(false);

                return(connection);
            }
            catch
            {
                transport.Abort();
                throw;
            }
            finally
            {
                stopWatch.Stop();
            }
        }
예제 #19
0
        /// <summary>
        /// Opens a connection to the specified address.
        /// </summary>
        /// <param name="addressUri">The address Uri. User info is ignored.</param>
        /// <param name="saslHandler">The SASL handler which determines the SASL mechanism. Null means no SASL handshake.</param>
        /// <param name="timeout">The operation timeout.</param>
        /// <returns>An AMQP connection.</returns>
        public async Task <AmqpConnection> OpenConnectionAsync(Uri addressUri, SaslHandler saslHandler, TimeSpan timeout)
        {
            TransportSettings transportSettings;

            if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqp, StringComparison.OrdinalIgnoreCase))
            {
                transportSettings = new TcpTransportSettings()
                {
                    Host = addressUri.Host,
                    Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultPort
                };
            }
            else if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqps, StringComparison.OrdinalIgnoreCase))
            {
                TcpTransportSettings tcpSettings = new TcpTransportSettings()
                {
                    Host = addressUri.Host,
                    Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultSecurePort
                };

                var tls = new TlsTransportSettings(tcpSettings)
                {
                    TargetHost = addressUri.Host
                };
                TlsTransportProvider tlsProvider = this.settings.GetTransportProvider <TlsTransportProvider>();
                if (tlsProvider != null)
                {
                    tls.CertificateValidationCallback = tlsProvider.Settings.CertificateValidationCallback;
                    tls.CheckCertificateRevocation    = tlsProvider.Settings.CheckCertificateRevocation;
                    tls.Certificate = tlsProvider.Settings.Certificate;
                    tls.Protocols   = tlsProvider.Settings.Protocols;
                }

                transportSettings = tls;
            }
            else if (addressUri.Scheme.Equals(WebSocketTransportSettings.WebSockets, StringComparison.OrdinalIgnoreCase) ||
                     addressUri.Scheme.Equals(WebSocketTransportSettings.SecureWebSockets, StringComparison.OrdinalIgnoreCase))
            {
                transportSettings = new WebSocketTransportSettings()
                {
                    Uri = addressUri
                };
            }
            else
            {
                throw new NotSupportedException(addressUri.Scheme);
            }

            AmqpSettings settings = this.settings.Clone();

            settings.TransportProviders.Clear();

            if (saslHandler != null)
            {
                // Provider for "AMQP3100"
                SaslTransportProvider saslProvider = new SaslTransportProvider(AmqpVersion.V100);
                saslProvider.AddHandler(saslHandler);
                settings.TransportProviders.Add(saslProvider);
            }

            // Provider for "AMQP0100"
            AmqpTransportProvider amqpProvider = new AmqpTransportProvider(AmqpVersion.V100);

            settings.TransportProviders.Add(amqpProvider);

            AmqpTransportInitiator initiator = new AmqpTransportInitiator(settings, transportSettings);
            TransportBase          transport = await Task.Factory.FromAsync(
                (c, s) => initiator.BeginConnect(timeout, c, s),
                (r) => initiator.EndConnect(r),
                null).ConfigureAwait(false);

            try
            {
                AmqpConnectionSettings connectionSettings = new AmqpConnectionSettings()
                {
                    ContainerId = Guid.NewGuid().ToString(),
                    HostName    = addressUri.Host
                };

                AmqpConnection connection = new AmqpConnection(transport, settings, connectionSettings);
                await connection.OpenAsync(timeout).ConfigureAwait(false);

                return(connection);
            }
            catch
            {
                transport.Abort();
                throw;
            }
        }
예제 #20
0
        public TestAmqpBroker(IList <string> endpoints, string userInfo, string sslValue, string[] queues)
        {
            this.containerId  = "TestAmqpBroker-P" + Process.GetCurrentProcess().Id;
            this.maxFrameSize = 64 * 1024;
            this.txnManager   = new TxnManager();
            this.connections  = new Dictionary <SequenceNumber, AmqpConnection>();
            this.queues       = new Dictionary <string, TestQueue>();
            if (queues != null)
            {
                foreach (string q in queues)
                {
                    this.queues.Add(q, new TestQueue(this));
                }
            }
            else
            {
                this.implicitQueue = true;
            }

            // create and initialize AmqpSettings
            AmqpSettings     settings    = new AmqpSettings();
            X509Certificate2 certificate = sslValue == null ? null : GetCertificate(sslValue);

            settings.RuntimeProvider = this;

            SaslHandler saslHandler;

            if (userInfo != null)
            {
                string[] creds     = userInfo.Split(':');
                string   usernanme = Uri.UnescapeDataString(creds[0]);
                string   password  = creds.Length == 1 ? string.Empty : Uri.UnescapeDataString(creds[1]);
                saslHandler = new SaslPlainHandler(new TestPlainAuthenticator(userInfo, password));
            }
            else
            {
                saslHandler = new SaslAnonymousHandler();
            }

            SaslTransportProvider saslProvider = new SaslTransportProvider();

            saslProvider.AddHandler(saslHandler);
            saslProvider.Versions.Add(new AmqpVersion(1, 0, 0));
            settings.TransportProviders.Add(saslProvider);

            AmqpTransportProvider amqpProvider = new AmqpTransportProvider();

            amqpProvider.Versions.Add(new AmqpVersion(1, 0, 0));
            settings.TransportProviders.Add(amqpProvider);

            // create and initialize transport listeners
            TransportListener[] listeners = new TransportListener[endpoints.Count];
            for (int i = 0; i < endpoints.Count; i++)
            {
                Uri addressUri = new Uri(endpoints[i]);

                if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqps, StringComparison.OrdinalIgnoreCase))
                {
                    if (certificate == null)
                    {
                        throw new InvalidOperationException("/cert option was not set when amqps address is specified.");
                    }

                    TcpTransportSettings tcpSettings = new TcpTransportSettings()
                    {
                        Host = addressUri.Host, Port = addressUri.Port
                    };
                    TlsTransportSettings tlsSettings = new TlsTransportSettings(tcpSettings)
                    {
                        Certificate = certificate, IsInitiator = false
                    };
                    listeners[i] = tlsSettings.CreateListener();
                }
                else if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqp, StringComparison.OrdinalIgnoreCase))
                {
                    TcpTransportSettings tcpSettings = new TcpTransportSettings()
                    {
                        Host = addressUri.Host, Port = addressUri.Port
                    };
                    listeners[i] = tcpSettings.CreateListener();
                }
#if !NETSTANDARD
                else if (addressUri.Scheme.Equals("ws", StringComparison.OrdinalIgnoreCase))
                {
                    WebSocketTransportSettings wsSettings = new WebSocketTransportSettings()
                    {
                        Uri = addressUri
                    };
                    listeners[i] = wsSettings.CreateListener();
                }
#endif
                else
                {
                    throw new NotSupportedException(addressUri.Scheme);
                }
            }

            this.transportListener = new AmqpTransportListener(listeners, settings);
            this.settings          = settings;
        }