Commit d0880697 authored by Marc Gravell's avatar Marc Gravell

Simpler SSL connect

parent bc9e4fe2
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
using System.IO; using System.IO;
using System.Net; using System.Net;
using NUnit.Framework; using NUnit.Framework;
using System.Linq;
namespace StackExchange.Redis.Tests namespace StackExchange.Redis.Tests
{ {
...@@ -11,10 +12,17 @@ namespace StackExchange.Redis.Tests ...@@ -11,10 +12,17 @@ namespace StackExchange.Redis.Tests
public class SSL : TestBase public class SSL : TestBase
{ {
[Test] [Test]
[TestCase(6379, null)] [TestCase(6379, false, false)]
[TestCase(6380, "as if we care")] [TestCase(6380, true, false)]
public void ConnectToSSLServer(int port, string sslHost) [TestCase(6380, true, true)]
public void ConnectToSSLServer(int port, bool useSsl, bool specifyHost)
{ {
string host = null;
const string path = @"D:\RedisSslHost.txt"; // because I choose not to advertise my server here!
if (File.Exists(path)) host = File.ReadLines(path).First();
if (string.IsNullOrWhiteSpace(host)) Assert.Inconclusive("no ssl host specified at: " + path);
var config = new ConfigurationOptions var config = new ConfigurationOptions
{ {
CommandMap = CommandMap.Create( // looks like "config" is disabled CommandMap = CommandMap.Create( // looks like "config" is disabled
...@@ -24,18 +32,36 @@ public void ConnectToSSLServer(int port, string sslHost) ...@@ -24,18 +32,36 @@ public void ConnectToSSLServer(int port, string sslHost)
{ "cluster", null } { "cluster", null }
} }
), ),
SslHost = sslHost, EndPoints = { { host, port} },
EndPoints = { { "sslredis", port} },
AllowAdmin = true, AllowAdmin = true,
SyncTimeout = Debugger.IsAttached ? int.MaxValue : 5000 SyncTimeout = Debugger.IsAttached ? int.MaxValue : 5000
}; };
config.CertificateValidation += (sender, cert, chain, errors) => if(useSsl)
{ {
Console.WriteLine("cert issued to: " + cert.Subject); config.UseSsl = useSsl;
return true; // fingers in ears, pretend we don't know this is wrong if (specifyHost)
}; {
using (var muxer = ConnectionMultiplexer.Connect(config, Console.Out)) config.SslHost = host;
}
config.CertificateValidation += (sender, cert, chain, errors) =>
{
Console.WriteLine("errors: " + errors);
Console.WriteLine("cert issued to: " + cert.Subject);
return true; // fingers in ears, pretend we don't know this is wrong
};
}
var configString = config.ToString();
Console.WriteLine("config: " + configString);
var clone = ConfigurationOptions.Parse(configString);
Assert.AreEqual(configString, clone.ToString(), "config string");
using(var log = new StringWriter())
using (var muxer = ConnectionMultiplexer.Connect(config, log))
{ {
Console.WriteLine("Connect log:");
Console.WriteLine(log);
Console.WriteLine("====");
muxer.ConnectionFailed += OnConnectionFailed; muxer.ConnectionFailed += OnConnectionFailed;
muxer.InternalError += OnInternalError; muxer.InternalError += OnInternalError;
var db = muxer.GetDatabase(); var db = muxer.GetDatabase();
...@@ -66,13 +92,14 @@ public void ConnectToSSLServer(int port, string sslHost) ...@@ -66,13 +92,14 @@ public void ConnectToSSLServer(int port, string sslHost)
// perf: sync/multi-threaded // perf: sync/multi-threaded
TestConcurrent(db, key, 30, 10); TestConcurrent(db, key, 30, 10);
TestConcurrent(db, key, 30, 20); //TestConcurrent(db, key, 30, 20);
TestConcurrent(db, key, 30, 30); //TestConcurrent(db, key, 30, 30);
TestConcurrent(db, key, 30, 40); //TestConcurrent(db, key, 30, 40);
TestConcurrent(db, key, 30, 50); //TestConcurrent(db, key, 30, 50);
} }
} }
private static void TestConcurrent(IDatabase db, RedisKey key, int SyncLoop, int Threads) private static void TestConcurrent(IDatabase db, RedisKey key, int SyncLoop, int Threads)
{ {
long value; long value;
......
...@@ -79,6 +79,20 @@ internal static string ToString(EndPoint endpoint) ...@@ -79,6 +79,20 @@ internal static string ToString(EndPoint endpoint)
return dns.Host + ":" + Format.ToString(dns.Port); return dns.Host + ":" + Format.ToString(dns.Port);
} }
} }
internal static string ToStringHostOnly(EndPoint endpoint)
{
var dns = endpoint as DnsEndPoint;
if (dns != null)
{
return dns.Host;
}
var ip = endpoint as IPEndPoint;
if(ip != null)
{
return ip.Address.ToString();
}
return "";
}
internal static bool TryGetHostPort(EndPoint endpoint, out string host, out int port) internal static bool TryGetHostPort(EndPoint endpoint, out string host, out int port)
{ {
......
...@@ -522,14 +522,17 @@ SocketMode ISocketCallback.Connected(Stream stream) ...@@ -522,14 +522,17 @@ SocketMode ISocketCallback.Connected(Stream stream)
// [network]<==[ssl]<==[logging]<==[buffered] // [network]<==[ssl]<==[logging]<==[buffered]
var config = multiplexer.RawConfig; var config = multiplexer.RawConfig;
if (!string.IsNullOrWhiteSpace(config.SslHost)) if(config.UseSsl)
{ {
var host = config.SslHost;
if (string.IsNullOrWhiteSpace(host)) host = Format.ToStringHostOnly(bridge.ServerEndPoint.EndPoint);
var ssl = new SslStream(stream, false, config.CertificateValidationCallback, config.CertificateSelectionCallback var ssl = new SslStream(stream, false, config.CertificateValidationCallback, config.CertificateSelectionCallback
#if !MONO #if !MONO
, EncryptionPolicy.RequireEncryption , EncryptionPolicy.RequireEncryption
#endif #endif
); );
ssl.AuthenticateAsClient(config.SslHost); ssl.AuthenticateAsClient(host);
if (!ssl.IsEncrypted) if (!ssl.IsEncrypted)
{ {
RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure); RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment