示例#1
0
        ClientWebSocket CreateConnectedClient(ServiceEndPoint endPoint)
        {
            if (!endPoint.IsWebSocketEndpoint)
            {
                throw new Exception("Only wss:// endpoints are supported");
            }

            var connectionId = Guid.NewGuid().ToString();

            var client = new ClientWebSocket();

            client.Options.ClientCertificates = new X509Certificate2Collection(new X509Certificate2Collection(clientCertificate));
            client.Options.AddSubProtocol("Octopus");
            client.Options.SetRequestHeader(ServerCertificateInterceptor.Header, connectionId);
            if (endPoint.Proxy != null)
            {
                client.Options.Proxy = new WebSocketProxy(endPoint.Proxy);
            }

            try
            {
                ServerCertificateInterceptor.Expect(connectionId);
                using (var cts = new CancellationTokenSource(endPoint.TcpClientConnectTimeout))
                    client.ConnectAsync(endPoint.BaseUri, cts.Token)
                    .ConfigureAwait(false).GetAwaiter().GetResult();
                ServerCertificateInterceptor.Validate(connectionId, endPoint);
            }
            finally
            {
                ServerCertificateInterceptor.Remove(connectionId);
            }


            return(client);
        }
示例#2
0
 public SecureClient(ServiceEndPoint serviceEndpoint, X509Certificate2 clientCertificate, ILog log, ConnectionPool<ServiceEndPoint, SecureConnection> pool)
 {
     this.serviceEndpoint = serviceEndpoint;
     this.clientCertificate = clientCertificate;
     this.log = log;
     this.pool = pool;
 }
示例#3
0
 public HalibutProxy(Func<RequestMessage, ResponseMessage> messageRouter, Type contractType, ServiceEndPoint endPoint)
     : base(contractType)
 {
     this.messageRouter = messageRouter;
     this.contractType = contractType;
     this.endPoint = endPoint;
 }
示例#4
0
        public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
        {
            int index = random.Next(0, endPoints.Length);

            endPoint = endPoints[index];
            return(true);
        }
示例#5
0
 public HalibutProxy(Func <RequestMessage, ResponseMessage> messageRouter, Type contractType, ServiceEndPoint endPoint)
     : base(contractType)
 {
     this.messageRouter = messageRouter;
     this.contractType  = contractType;
     this.endPoint      = endPoint;
 }
示例#6
0
        public void DiscoveringNonExistantEndpointThrows()
        {
            var client       = new DiscoveryClient();
            var fakeEndpoint = new ServiceEndPoint("https://fake-tentacle.example", "");

            Assert.Throws <HalibutClientException>(() => client.Discover(fakeEndpoint), "No such host is known");
        }
示例#7
0
        public ServiceEndPoint Discover(ServiceEndPoint serviceEndpoint)
        {
            try
            {
                using (var client = CreateConnectedTcpClient(serviceEndpoint))
                {
                    using (var stream = client.GetStream())
                    {
                        using (var ssl = new SslStream(stream, false, ValidateCertificate))
                        {
                            ssl.AuthenticateAsClientAsync(serviceEndpoint.BaseUri.Host, new X509Certificate2Collection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false)
                            .GetAwaiter()
                            .GetResult();
                            ssl.Write(HelloLine, 0, HelloLine.Length);
                            ssl.Flush();

                            if (ssl.RemoteCertificate == null)
                            {
                                throw new Exception("The server did not provide an SSL certificate");
                            }

                            return(new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert)).Thumbprint));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new HalibutClientException(ex.Message, ex);
            }
        }
示例#8
0
        private static IServiceTopology ParseMapServiceTopology(string endPointsText)
        {
            var             pairStrings  = endPointsText.Split(Comma, StringSplitOptions.RemoveEmptyEntries);
            ServiceEndPoint?nullEndPoint = null;
            var             pairs        = new List <KeyValuePair <string, ServiceEndPoint> >(pairStrings.Length);

            foreach (var pairString in pairStrings)
            {
                var match = MapElementRegex.Match(pairString.Trim());
                if (!match.Success)
                {
                    throw new InvalidDataException(string.Format("'{0}' is not a valid map service topology element", pairString.Trim()));
                }
                var key      = match.Groups[1].Value;
                var endPoint = ServiceEndPoint.Parse(match.Groups[2].Value);
                if (key == "@null")
                {
                    nullEndPoint = endPoint;
                }
                else
                {
                    pairs.Add(new KeyValuePair <string, ServiceEndPoint>(key, endPoint));
                }
            }
            return(new MapServiceTopology(nullEndPoint, pairs));
        }
示例#9
0
 public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
 {
     endPoint = scope == null
         ? endPoints[0]
         : endPoints[(uint)scope.GetHashCode() % endPoints.Length];
     return(true);
 }
示例#10
0
 public UnexpectedCertificateException(X509Certificate2 providedCert, ServiceEndPoint endPoint)
     : base(string.Format(Text, endPoint.BaseUri, endPoint.RemoteThumbprint, providedCert.Thumbprint, providedCert.Subject))
 {
     ServerUrl          = endPoint.BaseUri;
     ProvidedCert       = providedCert;
     ExpectedThumbprint = endPoint.RemoteThumbprint;
 }
示例#11
0
 public SecureWebSocketClient(ServiceEndPoint serviceEndpoint, X509Certificate2 clientCertificate, ILog log, ConnectionManager connectionManager)
 {
     this.serviceEndpoint   = serviceEndpoint;
     this.clientCertificate = clientCertificate;
     this.log = log;
     this.connectionManager = connectionManager;
 }
示例#12
0
        public ServiceEndPoint Discover(ServiceEndPoint serviceEndpoint, CancellationToken cancellationToken)
        {
            try
            {
                var log = logs.ForEndpoint(serviceEndpoint.BaseUri);
                using (var client = TcpConnectionFactory.CreateConnectedTcpClient(serviceEndpoint, log, cancellationToken))
                {
                    using (var stream = client.GetStream())
                    {
                        using (var ssl = new SslStream(stream, false, ValidateCertificate))
                        {
                            ssl.AuthenticateAsClient(serviceEndpoint.BaseUri.Host, new X509Certificate2Collection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false);
                            ssl.Write(HelloLine, 0, HelloLine.Length);
                            ssl.Flush();

                            if (ssl.RemoteCertificate == null)
                            {
                                throw new Exception("The server did not provide an SSL certificate");
                            }

#pragma warning disable PC001 // API not supported on all platforms - X509Certificate2 not supported on macOS
                            return(new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert)).Thumbprint));

#pragma warning restore PC001 // API not supported on all platforms - X509Certificate2 not supported on macOS
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new HalibutClientException(ex.Message, ex);
            }
        }
示例#13
0
 public SecureClient(ServiceEndPoint serviceEndpoint, X509Certificate2 clientCertificate, ILog log, ConnectionPool <ServiceEndPoint, IConnection> pool)
 {
     this.serviceEndpoint   = serviceEndpoint;
     this.clientCertificate = clientCertificate;
     this.log  = log;
     this.pool = pool;
 }
 public UnexpectedCertificateException(X509Certificate2 providedCert, ServiceEndPoint endPoint)
     : base(string.Format(Text, endPoint.BaseUri, endPoint.RemoteThumbprint, providedCert.Thumbprint, providedCert.Subject))
 {
     ServerUrl = endPoint.BaseUri;
     ProvidedCert = providedCert;
     ExpectedThumbprint = endPoint.RemoteThumbprint;
 }
示例#15
0
 public void ClearPooledConnections(ServiceEndPoint serviceEndPoint, ILog log)
 {
     lock (activeConnections)
     {
         pool.Clear(serviceEndPoint, log);
     }
 }
 public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
 {
     endPoint = scope == null
         ? endPoints[0]
         : endPoints[scope.GetHashCode() % endPoints.Length];
     return true;
 }
示例#17
0
        public IConnection AcquireConnection(IConnectionFactory connectionFactory, ServiceEndPoint serviceEndpoint, ILog log, CancellationToken cancellationToken)
        {
            var openableConnection = GetConnection(connectionFactory, serviceEndpoint, log, cancellationToken);

            openableConnection.Item2(); // Since this involves IO, this should never be done inside a lock
            return(openableConnection.Item1);
        }
示例#18
0
        public ServiceEndPoint Discover(ServiceEndPoint serviceEndpoint)
        {
            try
            {
                using (var client = CreateConnectedTcpClient(serviceEndpoint))
                {
                    using (var stream = client.GetStream())
                    {
                        using (var ssl = new SslStream(stream, false, ValidateCertificate))
                        {
                            ssl.AuthenticateAsClientAsync(serviceEndpoint.BaseUri.Host, new X509Certificate2Collection(), SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false)
                                .GetAwaiter()
                                .GetResult();
                            ssl.Write(HelloLine, 0, HelloLine.Length);
                            ssl.Flush();

                            if (ssl.RemoteCertificate == null)
                                throw new Exception("The server did not provide an SSL certificate");

                            return new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert)).Thumbprint);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new HalibutClientException(ex.Message, ex);
            }
        }
 public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
 {
     endPoint = scope == null
         ? endPoints[0]
         : endPoints[(uint)GetStableHashCode(scope) % endPoints.Length];
     return true;
 }
示例#20
0
 public override bool Equals(object obj)
 {
     if (obj == null)
     {
         return(false);
     }
     return(ServiceEndPoint.Equals(((PeerInfo)obj).ServiceEndPoint));
 }
示例#21
0
 public bool Equals(PeerInfo other)
 {
     if (other == null)
     {
         return(false);
     }
     return(ServiceEndPoint.Equals(other.ServiceEndPoint));
 }
示例#22
0
 public HalibutProxy(Func <RequestMessage, CancellationToken, ResponseMessage> messageRouter, Type contractType, ServiceEndPoint endPoint, CancellationToken cancellationToken)
     : base(contractType)
 {
     this.messageRouter     = messageRouter;
     this.contractType      = contractType;
     this.endPoint          = endPoint;
     this.cancellationToken = cancellationToken;
 }
示例#23
0
 private EventsPublishedByService(ServiceEndPoint serviceEndPoint,
                                  IEnumerable <EventSchema> publishedEventTypes,
                                  bool isReachable)
 {
     ServiceEndPoint     = serviceEndPoint;
     PublishedEventTypes = publishedEventTypes;
     IsReachable         = isReachable;
 }
示例#24
0
        public void EndPoint()
        {
            ServiceEndPoint endPoint;

            Assert.That(ServiceEndPoint.TryParse(@"http://some-host.com:12345", out endPoint), Is.True);
            Assert.That(endPoint.Protocol, Is.EqualTo("http"));
            Assert.That(endPoint.Host, Is.EqualTo("some-host.com"));
            Assert.That(endPoint.Port, Is.EqualTo(12345));
        }
        public IConnection AcquireConnection(IConnectionFactory connectionFactory, ServiceEndPoint serviceEndpoint, ILog log)
        {
            lock (activeConnections)
            {
                var connection = pool.Take(serviceEndpoint) ?? CreateConnection(connectionFactory, serviceEndpoint, log);
                AddConnectionToActiveConnections(serviceEndpoint, connection);

                return(connection);
            }
        }
示例#26
0
 public void SetUp()
 {
     var services = new DelegateServiceFactory();
     services.Register<IEchoService>(() => new EchoService());
     tentacle = new HalibutRuntime(services, Certificates.TentacleListening);
     var tentaclePort = tentacle.Listen();
     tentacle.Trust(Certificates.OctopusPublicThumbprint);
     endpoint = new ServiceEndPoint("https://localhost:" + tentaclePort, Certificates.TentacleListeningPublicThumbprint);
     log = new InMemoryConnectionLog(endpoint.ToString());
     HalibutLimits.ConnectionErrorRetryTimeout = TimeSpan.MaxValue;
 }
示例#27
0
 public void ReleaseConnection(ServiceEndPoint serviceEndpoint, IConnection connection)
 {
     lock (activeConnections)
     {
         pool.Return(serviceEndpoint, connection);
         if (activeConnections.TryGetValue(serviceEndpoint, out var connections))
         {
             connections.Remove(connection);
         }
     }
 }
示例#28
0
        public IReadOnlyCollection <IConnection> GetActiveConnections(ServiceEndPoint serviceEndPoint)
        {
            lock (activeConnections)
            {
                if (activeConnections.TryGetValue(serviceEndPoint, out var value))
                {
                    return(value.ToArray());
                }
            }

            return(NoConnections);
        }
        public void DisconnectDisposesActiveConnections()
        {
            var serviceEndpoint   = new ServiceEndPoint("https://localhost:42", Certificates.TentacleListeningPublicThumbprint);
            var connectionManager = new ConnectionManager();

            var activeConnection = connectionManager.AcquireConnection(connectionFactory, serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString()));

            connectionManager.GetActiveConnections(serviceEndpoint).Should().OnlyContain(c => c == activeConnection);

            connectionManager.Disconnect(serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString()));
            connectionManager.GetActiveConnections(serviceEndpoint).Should().BeNullOrEmpty();
        }
        public void DisposedConnectionsAreRemovedFromActive_WhenMultipleConnectionsAreActive()
        {
            var serviceEndpoint   = new ServiceEndPoint("https://localhost:42", Certificates.TentacleListeningPublicThumbprint);
            var connectionManager = new ConnectionManager();

            //do it twice because this bug only triggers on multiple enumeration, having 1 in the collection doesn't trigger the bug
            connectionManager.AcquireConnection(connectionFactory, serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString()));
            connectionManager.AcquireConnection(connectionFactory, serviceEndpoint, new InMemoryConnectionLog(serviceEndpoint.ToString()));

            connectionManager.Disconnect(serviceEndpoint, null);
            connectionManager.GetActiveConnections(serviceEndpoint).Should().BeNullOrEmpty();
        }
示例#31
0
 void ClearActiveConnections(ServiceEndPoint serviceEndPoint, ILog log)
 {
     lock (activeConnections)
     {
         if (activeConnections.TryGetValue(serviceEndPoint, out var activeConnectionsForEndpoint))
         {
             foreach (var connection in activeConnectionsForEndpoint.ToArray())
             {
                 SafelyDisposeConnection(connection, log);
             }
         }
     }
 }
示例#32
0
        public SecureClientFixture()
        {
            var services = new DelegateServiceFactory();

            services.Register <IEchoService>(() => new EchoService());
            tentacle = new HalibutRuntime(services, Certificates.TentacleListening);
            var tentaclePort = tentacle.Listen();

            tentacle.Trust(Certificates.OctopusPublicThumbprint);
            endpoint = new ServiceEndPoint("https://localhost:" + tentaclePort, Certificates.TentacleListeningPublicThumbprint);
            log      = new InMemoryConnectionLog(endpoint.ToString());
            HalibutLimits.ConnectionErrorRetryTimeout = TimeSpan.MaxValue;
        }
示例#33
0
 void AddConnectionToActiveConnections(ServiceEndPoint serviceEndpoint, IConnection connection)
 {
     if (activeConnections.TryGetValue(serviceEndpoint, out var connections))
     {
         connections.Add(connection);
     }
     else
     {
         connections = new HashSet <IConnection> {
             connection
         };
         activeConnections.Add(serviceEndpoint, connections);
     }
 }
示例#34
0
        public void SetUp()
        {
            var services = new DelegateServiceFactory();

            services.Register <IEchoService>(() => new EchoService());
            tentacle = new HalibutRuntime(services, Certificates.TentacleListening);
            var tentaclePort = tentacle.Listen();

            tentacle.Trust(Certificates.OctopusPublicThumbprint);
            endpoint = new ServiceEndPoint("https://localhost:" + tentaclePort, Certificates.TentacleListeningPublicThumbprint)
            {
                ConnectionErrorRetryTimeout = TimeSpan.MaxValue
            };
        }
        ClientWebSocket CreateConnectedClient(ServiceEndPoint serviceEndpoint, CancellationToken cancellationToken)
        {
            if (!serviceEndpoint.IsWebSocketEndpoint)
            {
                throw new Exception("Only wss:// endpoints are supported");
            }

            var connectionId = Guid.NewGuid().ToString();

            var client = new ClientWebSocket();

            client.Options.ClientCertificates = new X509Certificate2Collection(new X509Certificate2Collection(clientCertificate));
            client.Options.AddSubProtocol("Octopus");
            client.Options.SetRequestHeader(ServerCertificateInterceptor.Header, connectionId);
            if (serviceEndpoint.Proxy != null)
            {
                client.Options.Proxy = new WebSocketProxy(serviceEndpoint.Proxy);
            }

            try
            {
                ServerCertificateInterceptor.Expect(connectionId);
                using (var cts = new CancellationTokenSource(serviceEndpoint.TcpClientConnectTimeout))
                {
                    using (cancellationToken.Register(() => cts?.Cancel()))
                        client.ConnectAsync(serviceEndpoint.BaseUri, cts.Token)
                        .ConfigureAwait(false).GetAwaiter().GetResult();
                }
                ServerCertificateInterceptor.Validate(connectionId, serviceEndpoint);
            }
            catch
            {
                if (client.State == WebSocketState.Open)
                {
                    using (var sendCancel = new CancellationTokenSource(TimeSpan.FromSeconds(1)))
                        client.CloseAsync(WebSocketCloseStatus.ProtocolError, "Certificate thumbprint not recognised", sendCancel.Token)
                        .ConfigureAwait(false).GetAwaiter().GetResult();
                }

                client.Dispose();
                throw;
            }
            finally
            {
                ServerCertificateInterceptor.Remove(connectionId);
            }

            return(client);
        }
示例#36
0
        public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
        {
            if (scope == null)
            {
                if (nullEndPoint.HasValue)
                {
                    endPoint = nullEndPoint.Value;
                    return(true);
                }
                endPoint = default(ServiceEndPoint);
                return(false);
            }

            return(endPoints.TryGetValue(scope, out endPoint));
        }
        public static void Validate(string connectionId, ServiceEndPoint endPoint)
        {
            X509Certificate2 providedCertificate;

            lock (certificates)
                if (!certificates.TryGetValue(connectionId, out providedCertificate))
                {
                    throw new Exception("Did not recieve a certificate from the server");
                }

            if (providedCertificate.Thumbprint != endPoint.RemoteThumbprint)
            {
                throw new UnexpectedCertificateException(providedCertificate, endPoint);
            }
        }
示例#38
0
        public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
        {
            if (scope == null)
            {
                if (nullEndPoint.HasValue)
                {
                    endPoint = nullEndPoint.Value;
                    return true;
                }
                endPoint = default(ServiceEndPoint);
                return false;
            }

            return endPoints.TryGetValue(scope, out endPoint);
        }
示例#39
0
 TcpClient CreateConnectedTcpClient(ServiceEndPoint endPoint)
 {
     TcpClient client;
     if (endPoint.Proxy == null)
     {
         client = CreateTcpClient();
         client.ConnectWithTimeout(endPoint.BaseUri, HalibutLimits.TcpClientConnectTimeout);
     }
     else
     {
         var log = logs.ForEndpoint(endPoint.BaseUri);
         log.Write(EventType.Diagnostic, "Creating a proxy client");
         client = new ProxyClientFactory()
             .CreateProxyClient(log, endPoint.Proxy)
             .WithTcpClientFactory(CreateTcpClient)
             .CreateConnection(endPoint.BaseUri.Host, endPoint.BaseUri.Port, HalibutLimits.TcpClientConnectTimeout);
     }
     return client;
 }
示例#40
0
 private static void AssertEndPoint(IReadOnlyDictionary<string, IServiceTopology> topology, string serviceName, string scope, ServiceEndPoint expectedEndPoint)
 {
     IServiceTopology serviceTopology;
     ServiceEndPoint endPoint;
     Assert.That(topology.TryGetValue(serviceName, out serviceTopology), Is.True);
     Assert.That(serviceTopology.TryGetEndPoint(scope, out endPoint), Is.True);
     Assert.That(endPoint, Is.EqualTo(expectedEndPoint));
 }
 public SingleHostServiceTopology(ServiceEndPoint endPoint)
 {
     this.endPoint = endPoint;
 }
示例#42
0
 public HostSettings(ServiceEndPoint endPoint, IEnumerable<InterfaceImplementationTypePair> interfaceImplementationTypePairs)
 {
     this.endPoint = endPoint;
     this.interfaceImplementationTypePairs = interfaceImplementationTypePairs.ToArray();
 }
示例#43
0
 public MapServiceTopology(ServiceEndPoint? nullEndPoint, IEnumerable<KeyValuePair<string, ServiceEndPoint>> endPoints)
 {
     this.nullEndPoint = nullEndPoint;
     this.endPoints = endPoints.ToDictionary(x => x.Key, x => x.Value);
 }
 public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
 {
     return ServiceEndPoint.TryParse(scope, out endPoint);
 }
 public ClientCertificateValidator(ServiceEndPoint endPoint)
 {
     this.endPoint = endPoint;
 }
 public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
 {
     endPoint = this.endPoint;
     return true;
 }
示例#47
0
 public bool TryGetEndPoint(string scope, out ServiceEndPoint endPoint)
 {
     int index = random.Next(0, endPoints.Length);
     endPoint = endPoints[index];
     return true;
 }
示例#48
0
 public void PollingMode(Uri subscription, ServiceEndPoint octopusServer)
 {
     tentacleHalibutRuntime.Poll(subscription, octopusServer);
     Text = "Tentacle: polling, subscription: " + subscription;
 }