Пример #1
0
        private void SendDispatchLoop()
        {
            while (true)
            {
                if (scheduler.Verbose)
                {
                    Console.WriteLine("Waiting for the next send to dispatch");
                }

                SendTask sendTask = sendQueue.Receive();

                if (scheduler.Verbose)
                {
                    Console.WriteLine("Dispatching send of message of size {0} to {1}",
                                      sendTask.Message.Length, IoScheduler.PublicKeyToString(sendTask.DestinationPublicKey));
                }

                SenderThread senderThread = scheduler.FindSenderForDestinationPublicKey(sendTask.DestinationPublicKey);

                if (senderThread == null)
                {
                    senderThread = ClientSenderThread.Create(scheduler, sendTask.DestinationPublicKey);
                }

                senderThread.EnqueueSendTask(sendTask);
            }
        }
Пример #2
0
        protected override bool Connect()
        {
            var destinationPublicIdentity = scheduler.LookupPublicKey(destinationPublicKey);

            if (destinationPublicIdentity == null)
            {
                if (scheduler.Verbose)
                {
                    Console.Error.WriteLine("Could not connect to destination public key {0} because we don't know its address.",
                                            IoScheduler.PublicKeyToString(destinationPublicKey));
                }
                return(false);
            }

            if (scheduler.Verbose)
            {
                Console.WriteLine("Starting connection to {0}", IoScheduler.PublicIdentityToString(destinationPublicIdentity));
            }

            TcpClient client;

            try
            {
                client = new TcpClient(destinationPublicIdentity.HostNameOrAddress, destinationPublicIdentity.Port);
            }
            catch (Exception e)
            {
                scheduler.ReportException(e, "connecting to " + IoScheduler.PublicIdentityToString(destinationPublicIdentity));
                return(false);
            }

            var myCertificateCollection = new X509CertificateCollection();

            myCertificateCollection.Add(scheduler.MyCert);
            var myValidator = new CertificateValidator(scheduler, destinationPublicIdentity);

            try {
                stream = new SslStream(client.GetStream(), leaveInnerStreamOpen: false, myValidator.ValidateSSLCertificate);
                stream.AuthenticateAsClient(destinationPublicIdentity.FriendlyName, myCertificateCollection,
                                            checkCertificateRevocation: false);
            }
            catch (Exception e) {
                scheduler.ReportException(e, "authenticating connection to " + IoScheduler.PublicIdentityToString(destinationPublicIdentity));
                return(false);
            }

            remoteCert = stream.RemoteCertificate as X509Certificate2;

            if (!ByteArrayComparer.Default().Equals(IoScheduler.GetCertificatePublicKey(remoteCert), destinationPublicKey))
            {
                Console.Error.WriteLine("Connected to {0} expecting public key {1} but found public key {2}, so disconnecting.",
                                        IoScheduler.PublicIdentityToString(destinationPublicIdentity),
                                        IoScheduler.PublicKeyToString(destinationPublicKey),
                                        IoScheduler.PublicKeyToString(IoScheduler.GetCertificatePublicKey(remoteCert)));
                return(false);
            }

            if (scheduler.Verbose)
            {
                Console.WriteLine("Successfully connected to {0} and got certificate identifying it as {1}",
                                  IoScheduler.PublicIdentityToString(destinationPublicIdentity),
                                  IoScheduler.CertificateToString(remoteCert));
            }

            // Now that the connection is successful, create a thread to
            // receive packets on it.

            ReceiverThread receiverThread = ReceiverThread.Create(scheduler, stream);

            return(true);
        }
Пример #3
0
        public bool ValidateSSLCertificate(object sender, X509Certificate certificate, X509Chain chain,
                                           SslPolicyErrors sslPolicyErrors)
        {
            const SslPolicyErrors ignoredErrors = SslPolicyErrors.RemoteCertificateChainErrors;

            if ((sslPolicyErrors & ~ignoredErrors) != SslPolicyErrors.None)
            {
                Console.Error.WriteLine("Could not validate SSL certificate for {0} due to errors {1}",
                                        IoScheduler.GetCertificatePublicKey(certificate as X509Certificate2),
                                        sslPolicyErrors & ~ignoredErrors);
                return(false);
            }

            var cert2 = certificate as X509Certificate2;

            // If we were expecting a specific public identity, check that
            // the key in the certificate matches what we were expecting.

            if (expectedPublicIdentity != null)
            {
                if (!ByteArrayComparer.Default().Equals(IoScheduler.GetCertificatePublicKey(cert2), expectedPublicIdentity.PublicKey))
                {
                    Console.Error.WriteLine("Connected to {0} expecting public key {1} but found public key {2}, so disconnecting.",
                                            IoScheduler.PublicIdentityToString(expectedPublicIdentity),
                                            IoScheduler.PublicKeyToString(expectedPublicIdentity.PublicKey),
                                            IoScheduler.PublicKeyToString(IoScheduler.GetCertificatePublicKey(cert2)));
                    return(false);
                }

                if (cert2.SubjectName.Name != "CN=" + expectedPublicIdentity.FriendlyName)
                {
                    Console.Error.WriteLine("Connected to {0} expecting subject CN={1} but found {2}, so disconnecting.",
                                            IoScheduler.PublicIdentityToString(expectedPublicIdentity),
                                            expectedPublicIdentity.FriendlyName,
                                            cert2.SubjectName.Name);
                    return(false);
                }
            }
            else
            {
                // If we weren't expecting any particular public identity,
                // consider the expected public identity to be the known one
                // matching the public key in the certificate we got.  If
                // there is no known one, then this is just an anonymous
                // client, which is fine.  Otherwise, check that the subject
                // matches what we expect.  This is just a paranoid check; it
                // should never fail.

                expectedPublicIdentity = scheduler.LookupPublicKey(IoScheduler.GetCertificatePublicKey(cert2));
                if (expectedPublicIdentity != null)
                {
                    if (cert2.SubjectName.Name != "CN=" + expectedPublicIdentity.FriendlyName)
                    {
                        Console.Error.WriteLine("Received a certificate we expected to have subject CN={1} but found {2}, so disconnecting.",
                                                IoScheduler.PublicIdentityToString(expectedPublicIdentity),
                                                expectedPublicIdentity.FriendlyName,
                                                cert2.SubjectName.Name);
                        return(false);
                    }
                }
            }

            return(true);
        }