Commit 01b1ba66 authored by Marc Gravell's avatar Marc Gravell

Support for adding client-cert via environment variable

parent c80675a8
...@@ -159,14 +159,15 @@ private static void TestConcurrent(IDatabase db, RedisKey key, int SyncLoop, int ...@@ -159,14 +159,15 @@ private static void TestConcurrent(IDatabase db, RedisKey key, int SyncLoop, int
} }
const string RedisLabsSslHostFile = @"d:\RedisLabsSslHost.txt";
const string RedisLabsPfxPath = @"d:\RedisLabsUser.pfx";
[Test] [Test]
public void RedisLabsSSL() public void RedisLabsSSL()
{ {
const string path = @"d:\RedisLabsSslHost.txt"; if (!File.Exists(RedisLabsSslHostFile)) Assert.Inconclusive();
const string pfxPath = @"d:\RedisLabsUser.pfx"; string hostAndPort = File.ReadAllText(RedisLabsSslHostFile);
if (!File.Exists(path)) Assert.Inconclusive();
string hostAndPort = File.ReadAllText(path);
int timeout = 5000; int timeout = 5000;
if (Debugger.IsAttached) timeout *= 100; if (Debugger.IsAttached) timeout *= 100;
var options = new ConfigurationOptions var options = new ConfigurationOptions
...@@ -184,7 +185,7 @@ public void RedisLabsSSL() ...@@ -184,7 +185,7 @@ public void RedisLabsSSL()
#endif #endif
options.Ssl = true; options.Ssl = true;
options.CertificateSelection += delegate { options.CertificateSelection += delegate {
return new X509Certificate2(pfxPath, ""); return new X509Certificate2(RedisLabsPfxPath, "");
}; };
RedisKey key = Me(); RedisKey key = Me();
using(var conn = ConnectionMultiplexer.Connect(options)) using(var conn = ConnectionMultiplexer.Connect(options))
...@@ -207,5 +208,70 @@ public void RedisLabsSSL() ...@@ -207,5 +208,70 @@ public void RedisLabsSSL()
} }
} }
[Test]
[TestCase(false)]
[TestCase(true)]
public void RedisLabsEnvironmentVariableClientCertificate(bool setEnv)
{
try
{
if (setEnv)
{
Environment.SetEnvironmentVariable("SERedis_ClientCertPfxPath", RedisLabsPfxPath);
}
if (!File.Exists(RedisLabsSslHostFile)) Assert.Inconclusive();
string hostAndPort = File.ReadAllText(RedisLabsSslHostFile);
int timeout = 5000;
if (Debugger.IsAttached) timeout *= 100;
var options = new ConfigurationOptions
{
EndPoints = { hostAndPort },
ConnectTimeout = timeout,
AllowAdmin = true,
CommandMap = CommandMap.Create(new HashSet<string> {
"subscribe", "unsubscribe", "cluster"
}, false)
};
if (!Directory.Exists(Me())) Directory.CreateDirectory(Me());
#if LOGOUTPUT
ConnectionMultiplexer.EchoPath = Me();
#endif
options.Ssl = true;
RedisKey key = Me();
using (var conn = ConnectionMultiplexer.Connect(options))
{
if (!setEnv) Assert.Fail();
var db = conn.GetDatabase();
db.KeyDelete(key);
string s = db.StringGet(key);
Assert.IsNull(s);
db.StringSet(key, "abc");
s = db.StringGet(key);
Assert.AreEqual("abc", s);
var latency = db.Ping();
Console.WriteLine("RedisLabs latency: {0:###,##0.##}ms", latency.TotalMilliseconds);
using (var file = File.Create("RedisLabs.zip"))
{
conn.ExportConfiguration(file);
}
}
}
catch(RedisConnectionException ex)
{
if(setEnv || ex.FailureType != ConnectionFailureType.UnableToConnect)
{
throw;
}
}
finally
{
Environment.SetEnvironmentVariable("SERedis_ClientCertPfxPath", null);
}
}
} }
} }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
...@@ -543,6 +544,20 @@ internal int GetAvailableInboundBytes(out int activeReaders) ...@@ -543,6 +544,20 @@ internal int GetAvailableInboundBytes(out int activeReaders)
return this.socketToken.Available; return this.socketToken.Available;
} }
static LocalCertificateSelectionCallback GetAmbientCertificateCallback()
{
try
{
var pfxPath = Environment.GetEnvironmentVariable("SERedis_ClientCertPfxPath");
var pfxPassword = Environment.GetEnvironmentVariable("SERedis_ClientCertPassword");
if (!string.IsNullOrEmpty(pfxPath) && File.Exists(pfxPath))
{
return delegate { return new X509Certificate2(pfxPath, pfxPassword ?? ""); };
}
} catch
{ }
return null;
}
SocketMode ISocketCallback.Connected(Stream stream) SocketMode ISocketCallback.Connected(Stream stream)
{ {
try try
...@@ -561,7 +576,8 @@ SocketMode ISocketCallback.Connected(Stream stream) ...@@ -561,7 +576,8 @@ SocketMode ISocketCallback.Connected(Stream stream)
var host = config.SslHost; var host = config.SslHost;
if (string.IsNullOrWhiteSpace(host)) host = Format.ToStringHostOnly(bridge.ServerEndPoint.EndPoint); 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 ?? GetAmbientCertificateCallback()
#if !__MonoCS__ #if !__MonoCS__
, EncryptionPolicy.RequireEncryption , EncryptionPolicy.RequireEncryption
#endif #endif
......
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