// 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.