Skip to content

Commit

Permalink
Added server certificate validation support and supplying a client ce…
Browse files Browse the repository at this point in the history
…rtificate.
  • Loading branch information
meebey committed Aug 28, 2010
1 parent b7d15a0 commit bce846e
Showing 1 changed file with 82 additions and 5 deletions.
87 changes: 82 additions & 5 deletions src/IrcConnection/IrcConnection.cs
Expand Up @@ -35,6 +35,8 @@
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Security.Authentication;
using System.Threading;
using Starksoft.Net.Proxy;

Expand All @@ -52,6 +54,8 @@ public class IrcConnection
private int _CurrentAddress;
private int _Port;
private bool _UseSsl;
private bool _ValidateServerCertificate;
private X509Certificate _SslClientCertificate;
private StreamReader _Reader;
private StreamWriter _Writer;
private ReadThread _ReadThread;
Expand Down Expand Up @@ -310,6 +314,32 @@ public class IrcConnection
}
}

/// <summary>
/// Specifies if the certificate of the server is validated
/// Default: true
/// </summary>
public bool ValidateServerCertificate {
get {
return _ValidateServerCertificate;
}
set {
_ValidateServerCertificate = value;
}
}

/// <summary>
/// Specifies the client certificate used for the SSL connection
/// Default: null
/// </summary>
public X509Certificate SslClientCertificate {
get {
return _SslClientCertificate;
}
set {
_SslClientCertificate = value;
}
}

/// <summary>
/// Timeout in seconds for receiving data from the socket
/// Default: 600
Expand Down Expand Up @@ -560,10 +590,47 @@ public void Connect(string[] addresslist, int port)

Stream stream = _TcpClient.GetStream();
if (_UseSsl) {
SslStream sslStream = new SslStream(stream, false, delegate {
return true;
});
sslStream.AuthenticateAsClient(Address);
RemoteCertificateValidationCallback certValidation;
if (_ValidateServerCertificate) {
certValidation = delegate(object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors) {
if (sslPolicyErrors == SslPolicyErrors.None) {
return true;
}

#if LOG4NET
Logger.Connection.Error(
"Connect(): Certificate error: " +
sslPolicyErrors
);
#endif
return false;
};
} else {
certValidation = delegate { return true; };
}
SslStream sslStream = new SslStream(stream, false,
certValidation);
try {
if (_SslClientCertificate != null) {
var certs = new X509Certificate2Collection();
certs.Add(_SslClientCertificate);
sslStream.AuthenticateAsClient(Address, certs,
SslProtocols.Default,
false);
} else {
sslStream.AuthenticateAsClient(Address);
}
} catch (IOException ex) {
#if LOG4NET
Logger.Connection.Error(
"Connect(): AuthenticateAsClient() failed!"
);
#endif
throw new CouldNotConnectException("Could not connect to: " + Address + ":" + Port + " " + ex.Message, ex);
}
stream = sslStream;
}
_Reader = new StreamReader(stream, _Encoding);
Expand Down Expand Up @@ -597,6 +664,11 @@ public void Connect(string[] addresslist, int port)
if (OnConnected != null) {
OnConnected(this, EventArgs.Empty);
}
} catch (AuthenticationException ex) {
#if LOG4NET
Logger.Connection.Error("Connect(): Exception", ex);
#endif
throw new CouldNotConnectException("Could not connect to: " + Address + ":" + Port + " " + ex.Message, ex);
} catch (Exception e) {
if (_Reader != null) {
try {
Expand All @@ -617,8 +689,13 @@ public void Connect(string[] addresslist, int port)
IsConnectionError = true;

#if LOG4NET
Logger.Connection.Info("connection failed: "+e.Message);
Logger.Connection.Info("connection failed: "+e.Message, e);
#endif
if (e is CouldNotConnectException) {
// error was fatal, bail out
throw;
}

if (_AutoRetry &&
_ConnectTries <= 3) {
if (OnAutoConnectError != null) {
Expand Down

0 comments on commit bce846e

Please sign in to comment.