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
}
const string RedisLabsSslHostFile = @"d:\RedisLabsSslHost.txt";
const string RedisLabsPfxPath = @"d:\RedisLabsUser.pfx";
[Test]
public void RedisLabsSSL()
{
const string path = @"d:\RedisLabsSslHost.txt";
const string pfxPath = @"d:\RedisLabsUser.pfx";
if (!File.Exists(path)) Assert.Inconclusive();
string hostAndPort = File.ReadAllText(path);
if (!File.Exists(RedisLabsSslHostFile)) Assert.Inconclusive();
string hostAndPort = File.ReadAllText(RedisLabsSslHostFile);
int timeout = 5000;
if (Debugger.IsAttached) timeout *= 100;
var options = new ConfigurationOptions
......@@ -184,7 +185,7 @@ public void RedisLabsSSL()
#endif
options.Ssl = true;
options.CertificateSelection += delegate {
return new X509Certificate2(pfxPath, "");
return new X509Certificate2(RedisLabsPfxPath, "");
};
RedisKey key = Me();
using(var conn = ConnectionMultiplexer.Connect(options))
......@@ -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 @@
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
......@@ -543,6 +544,20 @@ internal int GetAvailableInboundBytes(out int activeReaders)
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)
{
try
......@@ -561,7 +576,8 @@ SocketMode ISocketCallback.Connected(Stream stream)
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 ?? GetAmbientCertificateCallback()
#if !__MonoCS__
, EncryptionPolicy.RequireEncryption
#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