Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 8fe903d

Browse files
authored
Merge pull request #247 from amohtashami12307/TesterToCheckWetherTheSslProtocolsReallyWork
Tester to check wether the ssl protocols really work
2 parents 771f5ba + 8834c3d commit 8fe903d

File tree

9 files changed

+158
-3
lines changed

9 files changed

+158
-3
lines changed

src/ServiceStack.Redis/RedisEndpoint.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.ComponentModel;
4+
using System.Security.Authentication;
45
using System.Text;
56
using ServiceStack.IO;
67
using ServiceStack.Text;
@@ -34,6 +35,7 @@ public RedisEndpoint(string host, int port, string password = null, long db = Re
3435
public string Host { get; set; }
3536
public int Port { get; set; }
3637
public bool Ssl { get; set; }
38+
public SslProtocols? SslProtocols {get; set;}
3739
public int ConnectTimeout { get; set; }
3840
public int SendTimeout { get; set; }
3941
public int ReceiveTimeout { get; set; }
@@ -59,6 +61,8 @@ public override string ToString()
5961
args.Add("Db=" + Db);
6062
if (Ssl)
6163
args.Add("Ssl=true");
64+
if (SslProtocols != null)
65+
args.Add("SslProtocols=" + SslProtocols.ToString());
6266
if (ConnectTimeout != RedisConfig.DefaultConnectTimeout)
6367
args.Add("ConnectTimeout=" + ConnectTimeout);
6468
if (SendTimeout != RedisConfig.DefaultSendTimeout)
@@ -83,6 +87,7 @@ protected bool Equals(RedisEndpoint other)
8387
return string.Equals(Host, other.Host)
8488
&& Port == other.Port
8589
&& Ssl.Equals(other.Ssl)
90+
&& SslProtocols.Equals(other.SslProtocols)
8691
&& ConnectTimeout == other.ConnectTimeout
8792
&& SendTimeout == other.SendTimeout
8893
&& ReceiveTimeout == other.ReceiveTimeout
@@ -109,6 +114,7 @@ public override int GetHashCode()
109114
var hashCode = (Host != null ? Host.GetHashCode() : 0);
110115
hashCode = (hashCode * 397) ^ Port;
111116
hashCode = (hashCode * 397) ^ Ssl.GetHashCode();
117+
hashCode = (hashCode * 397) ^ SslProtocols.GetHashCode();
112118
hashCode = (hashCode * 397) ^ ConnectTimeout;
113119
hashCode = (hashCode * 397) ^ SendTimeout;
114120
hashCode = (hashCode * 397) ^ ReceiveTimeout;

src/ServiceStack.Redis/RedisExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System.Globalization;
1616
using System.Linq;
1717
using System.Net.Sockets;
18+
using System.Security.Authentication;
1819
using ServiceStack.Model;
1920
using ServiceStack.Text;
2021

@@ -76,6 +77,12 @@ public static RedisEndpoint ToRedisEndpoint(this string connectionString, int? d
7677
if (useDefaultPort)
7778
endpoint.Port = RedisConfig.DefaultPortSsl;
7879
break;
80+
case "sslprotocols":
81+
SslProtocols protocols;
82+
value = value?.Replace("|", ",");
83+
if (!Enum.TryParse(value, true, out protocols)) throw new ArgumentOutOfRangeException("Keyword '" + name + "' requires an SslProtocol value (multiple values separated by '|').");
84+
endpoint.SslProtocols = protocols;
85+
break;
7986
case "client":
8087
endpoint.Client = value;
8188
break;

src/ServiceStack.Redis/RedisNativeClient.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using ServiceStack.Logging;
2222
using ServiceStack.Redis.Pipeline;
2323
using ServiceStack.Text;
24+
using System.Security.Authentication;
2425

2526
namespace ServiceStack.Redis
2627
{
@@ -91,6 +92,7 @@ internal bool Active
9192
public string Host { get; private set; }
9293
public int Port { get; private set; }
9394
public bool Ssl { get; private set; }
95+
public SslProtocols? SslProtocols { get; private set; }
9496

9597
/// <summary>
9698
/// Gets or sets object key prefix.
@@ -177,6 +179,7 @@ private void Init(RedisEndpoint config)
177179
Client = config.Client;
178180
Db = config.Db;
179181
Ssl = config.Ssl;
182+
SslProtocols = config.SslProtocols;
180183
IdleTimeOutSecs = config.IdleTimeOutSecs;
181184
ServerVersionNumber = RedisConfig.AssumeServerVersion.GetValueOrDefault();
182185
LogPrefix = "#" + ClientId + " ";

src/ServiceStack.Redis/RedisNativeClient_Utils.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
using System.Net;
1919
using System.Net.Security;
2020
using System.Net.Sockets;
21+
using System.Security.Authentication;
2122
using System.Security.Cryptography;
23+
using System.Security.Cryptography.X509Certificates;
2224
using System.Text;
2325
using System.Threading;
2426
using System.Threading.Tasks;
@@ -167,7 +169,14 @@ private void Connect()
167169
#if NETSTANDARD2_0
168170
sslStream.AuthenticateAsClientAsync(Host).Wait();
169171
#else
170-
sslStream.AuthenticateAsClient(Host);
172+
if (SslProtocols != null)
173+
{
174+
sslStream.AuthenticateAsClient(Host, new X509CertificateCollection(), SslProtocols ?? System.Security.Authentication.SslProtocols.Default, checkCertificateRevocation: true);
175+
} else
176+
{
177+
sslStream.AuthenticateAsClient(Host);
178+
}
179+
171180
#endif
172181

173182
if (!sslStream.IsEncrypted)

src/StackExchangeTester/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
5+
</startup>
6+
</configuration>

src/StackExchangeTester/Program.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using ServiceStack.Redis;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace StackExchangeTester
9+
{
10+
class Program
11+
{
12+
static void Main(string[] args)
13+
{
14+
var x = new RedisManagerPool("MQHnkdl402DScXzhZIxHwDaA7s8nziy45okp84ykShA=@tls-11.redis.cache.windows.net:6380?ssl=true&sslprotocols=Tls11");
15+
var y = x.GetClient();
16+
y.Ping();
17+
y.Set<string>("keyServiceStackSllChangesIStillHave512mb", "value");
18+
y.Dispose();
19+
x.Dispose();
20+
}
21+
}
22+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{0214D0F0-EA41-4593-B558-71F974CF7C62}</ProjectGuid>
8+
<OutputType>Exe</OutputType>
9+
<RootNamespace>StackExchangeTester</RootNamespace>
10+
<AssemblyName>StackExchangeTester</AssemblyName>
11+
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
12+
<FileAlignment>512</FileAlignment>
13+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
14+
<Deterministic>true</Deterministic>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<PlatformTarget>AnyCPU</PlatformTarget>
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<PlatformTarget>AnyCPU</PlatformTarget>
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>bin\Release\</OutputPath>
31+
<DefineConstants>TRACE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
34+
</PropertyGroup>
35+
<ItemGroup>
36+
<Reference Include="System" />
37+
<Reference Include="System.Core" />
38+
<Reference Include="System.Xml.Linq" />
39+
<Reference Include="System.Data.DataSetExtensions" />
40+
<Reference Include="Microsoft.CSharp" />
41+
<Reference Include="System.Data" />
42+
<Reference Include="System.Net.Http" />
43+
<Reference Include="System.Xml" />
44+
</ItemGroup>
45+
<ItemGroup>
46+
<Compile Include="Program.cs" />
47+
<Compile Include="Properties\AssemblyInfo.cs" />
48+
</ItemGroup>
49+
<ItemGroup>
50+
<None Include="App.config" />
51+
</ItemGroup>
52+
<ItemGroup>
53+
<ProjectReference Include="..\..\tests\Console.Tests\Console.Tests.csproj">
54+
<Project>{8368c965-b4f6-4263-9abb-731a175b2e77}</Project>
55+
<Name>Console.Tests</Name>
56+
</ProjectReference>
57+
<ProjectReference Include="..\..\tests\ServiceStack.Redis.Tests.Sentinel\ServiceStack.Redis.Tests.Sentinel.csproj">
58+
<Project>{91c55091-a946-49b5-9517-8794ebcc5784}</Project>
59+
<Name>ServiceStack.Redis.Tests.Sentinel</Name>
60+
</ProjectReference>
61+
<ProjectReference Include="..\..\tests\ServiceStack.Redis.Tests\ServiceStack.Redis.Tests.csproj">
62+
<Project>{951d28ee-5d22-4c62-ac0f-1661a8ceec5a}</Project>
63+
<Name>ServiceStack.Redis.Tests</Name>
64+
</ProjectReference>
65+
<ProjectReference Include="..\ServiceStack.Redis\ServiceStack.Redis.csproj">
66+
<Project>{af99f19b-4c04-4f58-81ef-b092f1fcc540}</Project>
67+
<Name>ServiceStack.Redis</Name>
68+
</ProjectReference>
69+
</ItemGroup>
70+
<ItemGroup>
71+
<COMReference Include="DCMAssemblyProviderLib">
72+
<Guid>{EDE973DE-4C9A-11DE-A33F-06DC55D89593}</Guid>
73+
<VersionMajor>1</VersionMajor>
74+
<VersionMinor>0</VersionMinor>
75+
<Lcid>0</Lcid>
76+
<WrapperTool>tlbimp</WrapperTool>
77+
<Isolated>False</Isolated>
78+
<EmbedInteropTypes>True</EmbedInteropTypes>
79+
</COMReference>
80+
</ItemGroup>
81+
<ItemGroup>
82+
<Content Include="azureconfig.txt" />
83+
</ItemGroup>
84+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
85+
</Project>

tests/ServiceStack.Redis.Tests/ConfigTests.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ public void OneTimeTearDown()
2727
[TestCase("host:1?password=pass&client=nunit", "{Host:host,Port:1,Client:nunit,Password:pass}")]
2828
[TestCase("host:1?db=2", "{Host:host,Port:1,Db:2}")]
2929
[TestCase("host?ssl=true", "{Host:host,Port:6380,Ssl:True}")]
30+
[TestCase("host:6380?ssl=true&password=pass&sslprotocols=Tls12", "{Host:host,Port:6380,Ssl:True,Password:pass,SslProtocols:Tls12}")]
3031
[TestCase("host:1?ssl=true", "{Host:host,Port:1,Ssl:True}")]
3132
[TestCase("host:1?connectTimeout=1&sendtimeout=2&receiveTimeout=3&idletimeoutsecs=4",
3233
"{Host:host,Port:1,ConnectTimeout:1,SendTimeout:2,ReceiveTimeout:3,IdleTimeOutSecs:4}")]
3334
[TestCase("redis://nunit:pass@host:1?ssl=true&db=1&connectTimeout=2&sendtimeout=3&receiveTimeout=4&retryTimeout=5&idletimeoutsecs=5&NamespacePrefix=prefix.",
3435
"{Host:host,Port:1,Ssl:True,Client:nunit,Password:pass,Db:1,ConnectTimeout:2,SendTimeout:3,ReceiveTimeout:4,RetryTimeout:5,IdleTimeOutSecs:5,NamespacePrefix:prefix.}")]
36+
[TestCase("redis://nunit:pass@host:1?ssl=true&sslprotocols=Tls12&db=1&connectTimeout=2&sendtimeout=3&receiveTimeout=4&retryTimeout=5&idletimeoutsecs=5&NamespacePrefix=prefix.",
37+
"{Host:host,Port:1,Ssl:True,Client:nunit,Password:pass,SslProtocols:Tls12,Db:1,ConnectTimeout:2,SendTimeout:3,ReceiveTimeout:4,RetryTimeout:5,IdleTimeOutSecs:5,NamespacePrefix:prefix.}")]
3538
public void Does_handle_different_connection_strings_settings(string connString, string expectedJsv)
3639
{
3740
var actual = connString.ToRedisEndpoint();
@@ -55,6 +58,7 @@ public void Does_handle_different_connection_strings_settings(string connString,
5558
"host:1?ConnectTimeout=1&SendTimeout=2&ReceiveTimeout=3&IdleTimeOutSecs=4")]
5659
[TestCase("redis://nunit:pass@host:1?ssl=true&db=1&connectTimeout=2&sendtimeout=3&receiveTimeout=4&idletimeoutsecs=5&NamespacePrefix=prefix.",
5760
"host:1?Client=nunit&Password=pass&Db=1&Ssl=true&ConnectTimeout=2&SendTimeout=3&ReceiveTimeout=4&IdleTimeOutSecs=5&NamespacePrefix=prefix.")]
61+
[TestCase("password@host:6380?ssl=true&sslprotocols=Tls12", "host:6380?Password=password&Ssl=true&SslProtocols=Tls12")]
5862
public void Does_Serialize_RedisEndpoint(string connString, string expectedString)
5963
{
6064
var actual = connString.ToRedisEndpoint();
@@ -64,8 +68,8 @@ public void Does_Serialize_RedisEndpoint(string connString, string expectedStrin
6468
[Test]
6569
public void Does_set_all_properties_on_Client_using_ClientsManagers()
6670
{
67-
var connStr = "redis://nunit:pass@host:1?ssl=true&db=0&connectTimeout=2&sendtimeout=3&receiveTimeout=4&idletimeoutsecs=5&NamespacePrefix=prefix.";
68-
var expected = "{Host:host,Port:1,Ssl:True,Client:nunit,Password:pass,Db:0,ConnectTimeout:2,SendTimeout:3,ReceiveTimeout:4,IdleTimeOutSecs:5,NamespacePrefix:prefix.}"
71+
var connStr = "redis://nunit:pass@host:1?ssl=true&sslprotocols=Tls12&db=0&connectTimeout=2&sendtimeout=3&receiveTimeout=4&idletimeoutsecs=5&NamespacePrefix=prefix.";
72+
var expected = "{Host:host,Port:1,Ssl:True,SslProtocols:Tls12,Client:nunit,Password:pass,Db:0,ConnectTimeout:2,SendTimeout:3,ReceiveTimeout:4,IdleTimeOutSecs:5,NamespacePrefix:prefix.}"
6973
.FromJsv<RedisEndpoint>();
7074

7175
using (var pooledManager = new RedisManagerPool(connStr))
@@ -122,6 +126,7 @@ private static void AssertClient(RedisClient redis, RedisEndpoint expected)
122126
Assert.That(redis.Host, Is.EqualTo(expected.Host));
123127
Assert.That(redis.Port, Is.EqualTo(expected.Port));
124128
Assert.That(redis.Ssl, Is.EqualTo(expected.Ssl));
129+
Assert.That(redis.SslProtocols, Is.EqualTo(expected.SslProtocols));
125130
Assert.That(redis.Client, Is.EqualTo(expected.Client));
126131
Assert.That(redis.Password, Is.EqualTo(expected.Password));
127132
Assert.That(redis.Db, Is.EqualTo(expected.Db));

tests/ServiceStack.Redis.Tests/SslTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ public void Can_connect_to_ssl_azure_redis_with_UrlFormat()
6767
}
6868
}
6969

70+
[Test]
71+
public void Can_connect_to_ssl_azure_redis_with_UrlFormat_Custom_SSL_Protocol ()
72+
{
73+
var url = "redis://{0}?ssl=true&sslprotocols=Tls12&password={1}".Fmt(Host, Password.UrlEncode());
74+
using (var client = new RedisClient(url))
75+
{
76+
client.Set("foo", "bar");
77+
var foo = client.GetValue("foo");
78+
foo.Print();
79+
}
80+
}
81+
7082
[Test]
7183
public void Can_connect_to_ssl_azure_redis_with_PooledClientsManager()
7284
{

0 commit comments

Comments
 (0)