コード例 #1
0
        private URLEndpointListenerConfiguration CreateListenerConfig(bool tls = true, bool useDynamicPort = true,
                                                                      IListenerAuthenticator auth = null, TLSIdentity id = null, bool stopListener = true)
        {
            if (stopListener)
            {
                _listener?.Stop();
            }

            var config = new URLEndpointListenerConfiguration(OtherDb);

            if (useDynamicPort)
            {
                config.Port = 0;
            }
            else
            {
                config.Port = tls ? WssPort : WsPort;
            }

            config.DisableTLS    = !tls;
            config.Authenticator = auth;
            config.TlsIdentity   = id;

            return(config);
        }
コード例 #2
0
        public void TestTLSIdentity()
        {
            // TLS is disabled
            _listener = CreateListener(false);
            _listener.TlsIdentity.Should().BeNull();
            _listener.Stop();
            _listener.TlsIdentity.Should().BeNull();

            // Anonymous Identity
            _listener = CreateListener(true);
            _listener.TlsIdentity.Should().NotBeNull();
            _listener.Stop();
            _listener.TlsIdentity.Should().BeNull();

            // User Identity
            TLSIdentity.DeleteIdentity(_store, ServerCertLabel, null);
            var id = TLSIdentity.CreateIdentity(false,
                                                new Dictionary <string, string>()
            {
                { Certificate.CommonNameAttribute, "CBL-Server" }
            },
                                                null,
                                                _store,
                                                ServerCertLabel,
                                                null);
            var config = CreateListenerConfig(true, true, null, id);

            _listener = new URLEndpointListener(config);
            _listener.TlsIdentity.Should().BeNull();
            _listener.Start();
            _listener.TlsIdentity.Should().NotBeNull();
            _listener.TlsIdentity.Should().BeEquivalentTo(config.TlsIdentity);
            _listener.Stop();
            _listener.TlsIdentity.Should().BeNull();
        }
コード例 #3
0
        public void TestAcceptSelfSignedCertWithPinnedCertificate()
        {
            _listener = CreateListener();
            _listener.TlsIdentity.Should()
            .NotBeNull("because otherwise the TLS identity was not created for the listener");
            _listener.TlsIdentity.Certs.Should().HaveCount(1,
                                                           "because otherwise bogus certs were used");

            // listener = cert1; replicator.pin = cert2; acceptSelfSigned = true => fail
            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,              //authenticator
                true,              //accept only self signed server cert
                DefaultServerCert, //server cert
                (int)CouchbaseLiteError.TLSCertUnknownRoot,
                CouchbaseLiteErrorType.CouchbaseLite
                );

            // listener = cert1; replicator.pin = cert1; acceptSelfSigned = false => pass
            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,
                false,                          //accept only self signed server cert
                _listener.TlsIdentity.Certs[0], //server cert
                0,
                0
                );

            _listener.Stop();
        }
コード例 #4
0
        private void ExecuteStartListenerCommand()
        {
            if (!IsListening)
            {
                try {
                    CreateListener();
                    //tag::StartListener[]
                    _urlEndpointListener.Start();
                    //end::StartListener[]
                    if (CoreApp.IsDebugging)
                    {
                        PrintListener(_urlEndpointListener);
                    }
                } catch (Exception ex) {
                    Debug.WriteLine($"Fail starting listener : {ex}");
                    return;
                }

                IsListening = true;
                Broadcast();
                ListenerStatus = $"Listening on {_urlEndpointListener.Urls[0]}";
            }
            else
            {
                //tag::StopListener[]
                _urlEndpointListener.Stop();
                _urlEndpointListener.Dispose();
                //end::StopListener[]
                IsListening    = false;
                ListenerStatus = "";
            }
        }
コード例 #5
0
        public void TestAcceptOnlySelfSignedCertMode()
        {
            _listener = CreateListener();
            _listener.TlsIdentity.Should()
            .NotBeNull("because otherwise the TLS identity was not created for the listener");
            _listener.TlsIdentity.Certs.Should().HaveCount(1,
                                                           "because otherwise bogus certs were used");

            DisableDefaultServerCertPinning = true;

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,
                false,//accept only self signed server cert
                null,
                //TODO: Need to handle Linux throwing different error TLSCertUntrusted (5008)
                (int)CouchbaseLiteError.TLSCertUnknownRoot,
                CouchbaseLiteErrorType.CouchbaseLite
                );

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,
                true, //accept only self signed server cert
                null,
                0,
                0
                );

            _listener.Stop();
        }
コード例 #6
0
        public void TestEmptyNetworkInterface()
        {
            var config = CreateListenerConfig(tls: false, networkInterface: "0.0.0.0");

            _listener = Listen(config, 0, 0);
            _listener.Stop();
        }
コード例 #7
0
        public void TestMultipleListenersOnSameDatabase()
        {
            _listener = CreateListener();
            var _listener2 = CreateNewListener();

            using (var doc1 = new MutableDocument("doc1"))
                using (var doc2 = new MutableDocument("doc2")) {
                    doc1.SetString("name", "Sam");
                    Db.Save(doc1);
                    doc2.SetString("name", "Mary");
                    OtherDb.Save(doc2);
                }

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,
                false, //accept only self signed server cert
                _listener.TlsIdentity.Certs[0],
                0,
                0
                );

            _listener.Stop();
            _listener2.Stop();

            OtherDb.Count.Should().Be(2);
        }
コード例 #8
0
        private URLEndpointListenerConfiguration CreateListenerConfig(bool tls = true, bool useDynamicPort = true,
                                                                      IListenerAuthenticator auth = null, TLSIdentity id = null, bool readOnly = false, string networkInterface = null)
        {
            _listener?.Stop();

            var config = new URLEndpointListenerConfiguration(OtherDb)
            {
                Port          = useDynamicPort ? (ushort)0 : tls ? WssPort : WsPort,
                DisableTLS    = !tls,
                Authenticator = auth,
                TlsIdentity   = id,
                ReadOnly      = readOnly
            };

            return(config);
        }
コード例 #9
0
        public void TestEmptyNetworkInterface()
        {
            var config = CreateListenerConfig(false);

            config.NetworkInterface = "0.0.0.0";
            _listener = Listen(config, 0, 0);
            _listener.Stop();
        }
コード例 #10
0
        public void TestUrls()
        {
            _listener = CreateListener(false);

            _listener.Urls.Count.Should().NotBe(0);
            _listener.Stop();
            _listener.Urls.Count.Should().Be(0);
        }
コード例 #11
0
        public void TestBusyPort()
        {
            _listener = CreateListener(false);
            //listener1 uses the same port as listener
            var config    = CreateListenerConfig(false);
            var listener1 = Listen(config, PosixBase.GetCode(nameof(PosixWindows.EADDRINUSE)), CouchbaseLiteErrorType.POSIX);

            _listener.Stop();
            listener1.Stop();
            listener1.Dispose();
        }
コード例 #12
0
 public void TestPort()
 {
     //init and start a listener
     _listener = CreateListener(false);
     //In order to get the test to pass on Linux, temp modify to this:
     _listener.Port.Should().BeGreaterThan(0);
     //_listener.Port.Should().Be(WsPort);
     //stop the listener
     _listener.Stop();
     _listener.Port.Should().Be(0, "Listener's port should be 0 because the listener is stopped.");
 }
コード例 #13
0
        public void TestBusyPort()
        {
            _listener = CreateListener(false, false);
            _listener.Start();

            //listener1 uses the same port as listener
            var config    = CreateListenerConfig(false, false, stopListener: false);
            var listener1 = Listen(config, GetEADDRINUSECode(), CouchbaseLiteErrorType.POSIX, stopListener: false);

            _listener.Stop();
            listener1.Stop();
            listener1.Dispose();
        }
コード例 #14
0
        public void TestEmptyPort()
        {
            //init and start a listener
            var config = CreateListenerConfig(false);

            _listener = Listen(config, 0, 0);

            _listener.Port.Should().NotBe(0, "Because the port is dynamically assigned.");

            //stop the listener
            _listener.Stop();
            _listener.Port.Should().Be(0, "Listener's port should be 0 because the listener is stopped.");
        }
コード例 #15
0
        public void TestPasswordAuthenticator()
        {
            var auth = new ListenerPasswordAuthenticator((sender, username, password) =>
            {
                return(username == "daniel" && new NetworkCredential(string.Empty, password).Password == "123");
            });

            _listener = CreateListener(false, true, auth);

            // Replicator - No authenticator
            var targetEndpoint = _listener.LocalEndpoint();
            var config         = new ReplicatorConfiguration(Db, targetEndpoint);

            RunReplication(config, (int)CouchbaseLiteError.HTTPAuthRequired, CouchbaseLiteErrorType.CouchbaseLite);
            var          pw                  = "123";
            var          wrongPw             = "456";
            SecureString pwSecureString      = null;
            SecureString wrongPwSecureString = null;

            unsafe
            {
                fixed(char *pw_ = pw)
                fixed(char *wrongPw_ = wrongPw)
                {
                    pwSecureString      = new SecureString(pw_, pw.Length);
                    wrongPwSecureString = new SecureString(wrongPw_, wrongPw.Length);
                }
            }

            // Replicator - Wrong Credentials
            config = new ReplicatorConfiguration(Db, targetEndpoint)
            {
                Authenticator = new BasicAuthenticator("daniel", wrongPwSecureString)
            };
            RunReplication(config, (int)CouchbaseLiteError.HTTPAuthRequired, CouchbaseLiteErrorType.CouchbaseLite);

            // Replicator - Success
            config = new ReplicatorConfiguration(Db, targetEndpoint)
            {
                Authenticator = new BasicAuthenticator("daniel", pwSecureString)
            };
            RunReplication(config, 0, 0);

            _listener.Stop();
            pwSecureString.Dispose();
            wrongPwSecureString.Dispose();
        }
コード例 #16
0
        public void TestListenerWithImportIdentity()
        {
            byte[] serverData = null;
            using (var stream = typeof(URLEndpointListenerTest).Assembly.GetManifestResourceStream("client.p12"))
                using (var reader = new BinaryReader(stream)) {
                    serverData = reader.ReadBytes((int)stream.Length);
                }

            // Cleanup
            TLSIdentity.DeleteIdentity(_store, ClientCertLabel, null);

            // Import identity
            var id = TLSIdentity.ImportIdentity(_store, serverData, "123", ServerCertLabel, null);

            // Create listener and start
            var config = CreateListenerConfig(true, true, null, id);

            _listener = Listen(config);

            _listener.TlsIdentity.Should().NotBeNull();

            using (var doc1 = new MutableDocument("doc1")) {
                doc1.SetString("name", "Sam");
                Db.Save(doc1);
            }

            OtherDb.Count.Should().Be(0);

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,                           //authenticator
                false,                          //accept only self signed server cert
                _listener.TlsIdentity.Certs[0], //server cert
                0,
                0
                );

            OtherDb.Count.Should().Be(1);

            _listener.Stop();
        }
コード例 #17
0
 //[Fact] //CouchbaseLiteException (POSIXDomain / 101): The requested address is not valid in its context.
 public void TestNetworkInterfaceName()
 {
     foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
     {
         if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 ||
             ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
         {
             foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
             {
                 if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                 {
                     var config = CreateListenerConfig(tls: false, networkInterface: ip.Address.ToString());
                     _listener = Listen(config, 0, 0);
                     _listener.Stop();
                 }
             }
         }
     }
 }
コード例 #18
0
        public void TestStopListener()
        {
            ManualResetEventSlim waitIdleAssert    = new ManualResetEventSlim();
            ManualResetEventSlim waitStoppedAssert = new ManualResetEventSlim();

            var config = CreateListenerConfig(false);

            _listener = Listen(config);

            var target  = _listener.LocalEndpoint();
            var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true,
                                       serverCert: null);

            using (var repl = new Replicator(config1)) {
                var token = repl.AddChangeListener((sender, args) =>
                {
                    if (args.Status.Activity == ReplicatorActivityLevel.Idle)
                    {
                        waitIdleAssert.Set();
                        // Stop listener aka server
                        _listener.Stop();
                    }
                    else if (args.Status.Activity == ReplicatorActivityLevel.Stopped)
                    {
                        waitStoppedAssert.Set();
                    }
                });

                repl.Start();

                // Wait until idle then stop the listener
                waitIdleAssert.Wait(TimeSpan.FromSeconds(15)).Should().BeTrue();

                // Wait for the replicator to be stopped
                waitStoppedAssert.Wait(TimeSpan.FromSeconds(20)).Should().BeTrue();

                // Check error
                var error = repl.Status.Error.As <CouchbaseWebsocketException>();
                error.Error.Should().Be((int)CouchbaseLiteError.WebSocketGoingAway);
            }
        }
コード例 #19
0
        public void TestClientCertAuthRootCertsError()
        {
            byte[] caData;
            using (var stream = typeof(URLEndpointListenerTest).Assembly.GetManifestResourceStream("client-ca.der"))
                using (var reader = new BinaryReader(stream)) {
                    caData = reader.ReadBytes((int)stream.Length);
                }

            var rootCert = new X509Certificate2(caData);
            var auth     = new ListenerCertificateAuthenticator(new X509Certificate2Collection(rootCert));

            _listener = CreateListener(true, true, auth);

            TLSIdentity.DeleteIdentity(_store, ClientCertLabel, null);
            // Create wrong client identity
            var id = TLSIdentity.CreateIdentity(false,
                                                new Dictionary <string, string>()
            {
                { Certificate.CommonNameAttribute, "daniel" }
            },
                                                null,
                                                _store,
                                                ClientCertLabel,
                                                null);

            id.Should().NotBeNull();
            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                new ClientCertificateAuthenticator(id),
                true,
                _listener.TlsIdentity.Certs[0],
                (int)CouchbaseLiteError.TLSHandshakeFailed,  //not TLSClientCertRejected as mac has..
                CouchbaseLiteErrorType.CouchbaseLite
                );

            TLSIdentity.DeleteIdentity(_store, ClientCertLabel, null);
            _listener.Stop();
        }
コード例 #20
0
        public void TestClientCertAuthenticatorRootCerts()
        {
            byte[] caData, clientData;
            using (var stream = typeof(URLEndpointListenerTest).Assembly.GetManifestResourceStream("client-ca.der"))
                using (var reader = new BinaryReader(stream)) {
                    caData = reader.ReadBytes((int)stream.Length);
                }

            using (var stream = typeof(URLEndpointListenerTest).Assembly.GetManifestResourceStream("client.p12"))
                using (var reader = new BinaryReader(stream)) {
                    clientData = reader.ReadBytes((int)stream.Length);
                }

            var rootCert = new X509Certificate2(caData);
            var auth     = new ListenerCertificateAuthenticator(new X509Certificate2Collection(rootCert));

            _listener = CreateListener(true, true, auth);
            var serverCert = _listener.TlsIdentity.Certs[0];

            // Cleanup
            TLSIdentity.DeleteIdentity(_store, ClientCertLabel, null);

            // Create client identity
            var id = TLSIdentity.ImportIdentity(_store, clientData, "123", ClientCertLabel, null);

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                new ClientCertificateAuthenticator(id),
                true,
                serverCert,
                0,
                0
                );

            TLSIdentity.DeleteIdentity(_store, ClientCertLabel, null);
            _listener.Stop();
        }
コード例 #21
0
        public void TestDoNotAcceptSelfSignedMode() //aka testPinnedServerCertificate in iOS
        {
            _listener = CreateListener();
            _listener.TlsIdentity.Should()
            .NotBeNull("because otherwise the TLS identity was not created for the listener");
            _listener.TlsIdentity.Certs.Should().HaveCount(1,
                                                           "because otherwise bogus certs were used");

            DisableDefaultServerCertPinning = true;

            // Replicator - TLS Error
            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,
                false, //accept only self signed server cert
                null,
                (int)CouchbaseLiteError.TLSCertUnknownRoot,
                CouchbaseLiteErrorType.CouchbaseLite
                );

            // Replicator - Success
            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null,
                false, //accept only self signed server cert
                _listener.TlsIdentity.Certs[0],
                0,
                0
                );

            _listener.Stop();
        }
コード例 #22
0
        public void TestStatus()
        {
            ulong maxConnectionCount = 0UL;
            ulong maxActiveCount     = 0UL;

            //init and start a listener
            _listener = CreateListener(false);

            //listener is started at this point
            _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because no client connection has been established.");
            _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because no client connection has been established.");

            using (var doc1 = new MutableDocument())
                using (var doc2 = new MutableDocument()) {
                    doc1.SetString("name", "Sam");
                    Db.Save(doc1);
                    doc2.SetString("name", "Mary");
                    OtherDb.Save(doc2);
                }

            var targetEndpoint = _listener.LocalEndpoint();
            var config         = new ReplicatorConfiguration(Db, targetEndpoint);

            using (var repl = new Replicator(config)) {
                var waitAssert = new WaitAssert();
                var token      = repl.AddChangeListener((sender, args) =>
                {
                    WriteLine($"Yeehaw {_listener.Status.ConnectionCount} / {_listener.Status.ActiveConnectionCount}");

                    maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount);
                    maxActiveCount     = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount);

                    waitAssert.RunConditionalAssert(() =>
                    {
                        return(args.Status.Activity == ReplicatorActivityLevel.Stopped);
                    });
                });

                repl.Start();
                while (repl.Status.Activity != ReplicatorActivityLevel.Busy)
                {
                    Thread.Sleep(100);
                }

                // For some reason running on mac throws off the timing enough so that the active connection count
                // of 1 is never seen.  So record the value right after it becomes busy.
                maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount);
                maxActiveCount     = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount);

                try {
                    waitAssert.WaitForResult(TimeSpan.FromSeconds(100));
                } finally {
                    repl.RemoveChangeListener(token);
                }
            }

            maxConnectionCount.Should().Be(1);
            maxActiveCount.Should().Be(1);

            //stop the listener
            _listener.Stop();
            _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because the connection is stopped.");
            _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because the connection is stopped.");
        }
コード例 #23
0
        public void TestReplicatorAndListenerOnSameDatabase()
        {
            using (var doc = new MutableDocument()) {
                OtherDb.Save(doc);
            }

            CreateListener();
            using (var doc1 = new MutableDocument()) {
                Db.Save(doc1);
            }

            var target  = new DatabaseEndpoint(Db);
            var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true, sourceDb: OtherDb);
            var repl1   = new Replicator(config1);

            Database.Delete("urlepTestDb", Directory);
            var urlepTestDb = OpenDB("urlepTestDb");

            using (var doc2 = new MutableDocument()) {
                urlepTestDb.Save(doc2);
            }

            var config2 = CreateConfig(_listener.LocalEndpoint(), ReplicatorType.PushAndPull, true,
                                       serverCert: _listener.TlsIdentity.Certs[0], sourceDb: urlepTestDb);
            var repl2 = new Replicator(config2);

            var wait1 = new ManualResetEventSlim();
            var wait2 = new ManualResetEventSlim();
            EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) =>
            {
                if (args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed ==
                    args.Status.Progress.Total)
                {
                    if (OtherDb.Count == 3 && Db.Count == 3 && urlepTestDb.Count == 3)
                    {
                        ((Replicator)sender).Stop();
                    }
                }
                else if (args.Status.Activity == ReplicatorActivityLevel.Stopped)
                {
                    if (sender == repl1)
                    {
                        wait1.Set();
                    }
                    else
                    {
                        wait2.Set();
                    }
                }
            };

            var token1 = repl1.AddChangeListener(changeListener);
            var token2 = repl2.AddChangeListener(changeListener);

            repl1.Start();
            repl2.Start();
            WaitHandle.WaitAll(new[] { wait1.WaitHandle, wait2.WaitHandle }, TimeSpan.FromSeconds(20))
            .Should().BeTrue();

            repl1.RemoveChangeListener(token1);
            repl2.RemoveChangeListener(token2);

            Db.Count.Should().Be(3, "because otherwise not all docs were received into Db");
            OtherDb.Count.Should().Be(3, "because otherwise not all docs were received into OtherDb");
            urlepTestDb.Count.Should().Be(3, "because otherwise not all docs were received into urlepTestDb");

            repl1.Dispose();
            repl2.Dispose();
            wait1.Dispose();
            wait2.Dispose();
            urlepTestDb.Delete();

            _listener.Stop();

            Thread.Sleep(500); // wait for everything to stop
        }
コード例 #24
0
        public void TestClientCertAuthWithCallback()
        {
            var auth = new ListenerCertificateAuthenticator((sender, cert) =>
            {
                if (cert.Count != 1)
                {
                    return(false);
                }

                return(cert[0].SubjectName.Name?.Replace("CN=", "") == "daniel");
            });

            var badAuth = new ListenerCertificateAuthenticator((sender, cert) =>
            {
                return(cert.Count == 100); // Obviously fail
            });

            _listener = CreateListener(true, true, auth);

            // User Identity
            TLSIdentity.DeleteIdentity(_store, ClientCertLabel, null);
            var id = TLSIdentity.CreateIdentity(false,
                                                new Dictionary <string, string>()
            {
                { Certificate.CommonNameAttribute, "daniel" }
            },
                                                null,
                                                _store,
                                                ClientCertLabel,
                                                null);

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                new ClientCertificateAuthenticator(id),
                false,
                _listener.TlsIdentity.Certs[0],
                0,
                0
                );

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                null, // Don't send client cert
                false,
                _listener.TlsIdentity.Certs[0],
                (int)CouchbaseLiteError.TLSHandshakeFailed,
                CouchbaseLiteErrorType.CouchbaseLite
                );

            _listener.Stop();
            _listener = CreateListener(true, true, badAuth);

            RunReplication(
                _listener.LocalEndpoint(),
                ReplicatorType.PushAndPull,
                false,
                new ClientCertificateAuthenticator(id), // send wrong client cert
                false,
                _listener.TlsIdentity.Certs[0],
                (int)CouchbaseLiteError.TLSHandshakeFailed,
                CouchbaseLiteErrorType.CouchbaseLite
                );

            TLSIdentity.DeleteIdentity(_store, ClientCertLabel, null);
        }