All pastes #830770 Raw Edit

SmartIrc4net SSL

public text v1 · immutable
#830770 ·published 2007-12-24 06:54 UTC
rendered paste body
// Meebey: Short blurb on adding SSL support to SmartIrc4net

// Inside of IrcConnection.cs...
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

// I created a public boolean property called Ssl, defaults to false, that determines whether you connect via SSL or not.

// Now, inside of:
        public void Connect(string[] addresslist, int port)
        {
            [...]
                // Up to this line:
                _TcpClient.Connect(ip, port);

                //My code:
                Stream stream = _TcpClient.GetStream();
                // Added:
                if (_Ssl)
                {
                    // Create a new SSL stream from the TCP stream, giving a delegate to approve the validity of the server certificate.
                    SslStream ssl = new SslStream(stream, false, new RemoteCertificateValidationCallback(ValidateServerCertificate));

                    // Authenticate (this is required to continue connection)
                    ssl.AuthenticateAsClient(Address);

                    // Replace the old stream with the SSL one
                    stream = (Stream)ssl;
                }

                _Reader = new StreamReader(stream, _Encoding);
                _Writer = new StreamWriter(stream, _Encoding);

                //etc...
                [...]
        }

        // This allows you to specify whether you wish to accept or deny the certificate, by returning true or false.
        // In my code, and for my purposes, I simply returned true to accept all SSL certificates, valid or not.
        // Now, for your library, I would suggest forwarding this check as an event of IrcConnection that one can hook
        // a handler to (if you've used a client like mIRC before on SSL you might have seen a notice about self-signed
        //               certificates and a prompt asking whether you wish to accept it or not). You could also just change
        // the Connect() method to optionally pass a delegate to be used to check, which you can simply pass to SslStream's
        // constructor. In that case you might want to ditch the class' Ssl property altogether and create a separate ConnectSsl()
        // method instead.
        private bool ValidateServerCertificate(
              object sender,
              X509Certificate certificate,
              X509Chain chain,
              SslPolicyErrors sslPolicyErrors)
        {
            // Instead of my blatant return true, either hook this up to a ValidateCertificate event or ignore this method and
            // do as I said above and have the user pass a delegate to Connect().
            return true;
        }

// And that should be enough, it's pretty simple, and just a matter of choosing a way to validate SSL certificates.
// As a final note: If you have anywhere that specifies the default port of 6667 when connecting, 6697 is the "standard" SSL IRC port, btw.