Skip to content

Commit

Permalink
Resolve Issue #158 TLS 1.2 Support in Fleck and WebSocket4Net (#170)
Browse files Browse the repository at this point in the history
* Resolve Issue #158 "TLS 1.2 Support in Fleck and WebSocket4Net" by adding overloads to Fleck and WebSocket4Net. Also added convienence overloads for WAMP2 DefaultRouter (Fleck) and for WAMP1 Channel Factory extensions (WebSocket4Net). Added overloads where defaults would also be acceptable for backwards binary compatibility - these can be removed if this is undesired. I was unable to validate the Mono build.

* Add missing space.
  • Loading branch information
StevenBonePgh authored and darkl committed Jan 11, 2017
1 parent a5db89c commit dc6b466
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Security.Cryptography.X509Certificates;
using System;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using WampSharp.V2.Authentication;

namespace WampSharp.Fleck
Expand All @@ -9,7 +11,16 @@ public FleckAuthenticatedWebSocketTransport
(string location,
ICookieAuthenticatorFactory cookieAuthenticatorFactory = null,
X509Certificate2 certificate = null)
: base(location, cookieAuthenticatorFactory, certificate)
: this(location: location, cookieAuthenticatorFactory: cookieAuthenticatorFactory, certificate: certificate, getEnabledSslProtocols: null)
{
}

public FleckAuthenticatedWebSocketTransport
(string location,
ICookieAuthenticatorFactory cookieAuthenticatorFactory = null,
X509Certificate2 certificate = null,
Func<SslProtocols> getEnabledSslProtocols = null)
: base(location, cookieAuthenticatorFactory, certificate, getEnabledSslProtocols)
{
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using Fleck;
using WampSharp.Core.Listener;
Expand All @@ -17,15 +18,25 @@ public class FleckWampConnectionListener<TMessage> : IWampConnectionListener<TMe
private readonly string mLocation;
private readonly IWampTextBinding<TMessage> mBinding;
private readonly X509Certificate2 mCertificate;
private readonly Func<SslProtocols> mGetEnabledSslProtocols;
private readonly object mLock = new object();

public FleckWampConnectionListener(string location,
IWampTextBinding<TMessage> binding,
X509Certificate2 certificate = null)
:this(location: location, binding: binding, certificate: certificate, getEnabledSslProtocols: null)
{
}

public FleckWampConnectionListener(string location,
IWampTextBinding<TMessage> binding,
X509Certificate2 certificate,
Func<SslProtocols> getEnabledSslProtocols)
{
mLocation = location;
mBinding = binding;
mCertificate = certificate;
mGetEnabledSslProtocols = getEnabledSslProtocols;
}

public IDisposable Subscribe(IObserver<IWampConnection<TMessage>> observer)
Expand Down Expand Up @@ -65,6 +76,11 @@ private void StartServer()
server.Certificate = mCertificate;
}

if (mGetEnabledSslProtocols != null)
{
server.EnabledSslProtocols = mGetEnabledSslProtocols();
}

mServer.Start(connection =>
{
FleckWampTextConnection<TMessage> wampConnection =
Expand Down
42 changes: 38 additions & 4 deletions src/net45/Default/WampSharp.Fleck/Fleck/FleckWebSocketTransport.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using Fleck;
using WampSharp.Core.Listener;
Expand All @@ -22,9 +23,21 @@ public class FleckWebSocketTransport : WebSocketTransport<IWebSocketConnection>
/// given the server address to run at.
/// </summary>
/// <param name="location">The given server address.</param>
/// <param name="certificate"></param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
public FleckWebSocketTransport(string location, X509Certificate2 certificate = null)
: this(location, null, certificate)
: this(location: location, cookieAuthenticatorFactory: null, certificate: certificate, getEnabledSslProtocols: null)
{
}

/// <summary>
/// Creates a new instance of <see cref="FleckWebSocketTransport"/>
/// given the server address to run at.
/// </summary>
/// <param name="location">The given server address.</param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
/// <param name="getEnabledSslProtocols"> If non-null, used to set Fleck's EnabledSslProtocols. </param>
public FleckWebSocketTransport(string location, X509Certificate2 certificate, Func<SslProtocols> getEnabledSslProtocols)
: this(location: location, cookieAuthenticatorFactory: null, certificate: certificate, getEnabledSslProtocols: getEnabledSslProtocols)
{
}

Expand All @@ -34,15 +47,36 @@ public FleckWebSocketTransport(string location, X509Certificate2 certificate = n
/// </summary>
/// <param name="location">The given server address.</param>
/// <param name="cookieAuthenticatorFactory"></param>
/// <param name="certificate"></param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
protected FleckWebSocketTransport(string location,
ICookieAuthenticatorFactory cookieAuthenticatorFactory = null,
X509Certificate2 certificate = null)
: this(location: location, cookieAuthenticatorFactory: null, certificate: certificate, getEnabledSslProtocols: null)
{
}

/// <summary>
/// Creates a new instance of <see cref="FleckWebSocketTransport"/>
/// given the server address to run at.
/// </summary>
/// <param name="location">The given server address.</param>
/// <param name="cookieAuthenticatorFactory"></param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
/// <param name="getEnabledSslProtocols"> If non-null, used to set Fleck's EnabledSslProtocols. </param>
protected FleckWebSocketTransport(string location,
ICookieAuthenticatorFactory cookieAuthenticatorFactory = null,
X509Certificate2 certificate = null,
Func<SslProtocols> getEnabledSslProtocols = null)
: base(cookieAuthenticatorFactory)
{
mServer = new WebSocketServer(location);
mServer.Certificate = certificate;


if (getEnabledSslProtocols != null)
{
mServer.EnabledSslProtocols = getEnabledSslProtocols();
}

RouteLogs();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using WampSharp.Core.Message;
using System;
using SuperSocket.ClientEngine;
using WampSharp.Core.Message;
using WampSharp.V2.Binding;
using WebSocket4Net;

Expand Down Expand Up @@ -32,7 +34,20 @@ public WebSocket4NetBinaryConnection(WebSocket webSocket, IWampBinaryBinding<TMe
/// <param name="serverAddress">The server address to connect to.</param>
/// <param name="binding">The <see cref="IWampBinaryBinding{TMessage}"/> to use.</param>
public WebSocket4NetBinaryConnection(string serverAddress, IWampBinaryBinding<TMessage> binding)
: base(serverAddress, binding)
: this(serverAddress: serverAddress, binding: binding, configureSecurityOptions: null)
{
}

/// <summary>
/// Creates a new instance of <see cref="WebSocket4NetBinaryConnection{TMessage}"/>
/// given the server address to connect to, the binary binding to use, and an Action
/// to configure WebSocket Security Options.
/// </summary>
/// <param name="serverAddress">The server address to connect to.</param>
/// <param name="binding">The <see cref="IWampBinaryBinding{TMessage}"/> to use.</param>
/// <param name="configureSecurityOptions">If non-null, called to allow custom setup of the WebSocket security options.</param>
public WebSocket4NetBinaryConnection(string serverAddress, IWampBinaryBinding<TMessage> binding, Action<SecurityOption> configureSecurityOptions)
: base(serverAddress, binding, configureSecurityOptions)
{
mBinding = binding;
WebSocket.DataReceived += OnDataReceived;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,19 @@ public WebSocket4NetConnection(WebSocket webSocket,

public WebSocket4NetConnection(string serverAddress,
IWampBinding<TMessage> binding)
: this(serverAddress: serverAddress, binding: binding, configureSecurityOptions: null)
{
}

public WebSocket4NetConnection(string serverAddress,
IWampBinding<TMessage> binding,
Action<SecurityOption> configureSecurityOptions)
: this(new WebSocket(serverAddress, binding.Name, WebSocketVersion.None), binding)
{
if (configureSecurityOptions != null)
{
configureSecurityOptions(WebSocket.Security);
}
}

public IWampBinding<TMessage> Binding
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using WampSharp.Core.Message;
using System;
using SuperSocket.ClientEngine;
using WampSharp.Core.Message;
using WampSharp.V2.Binding;
using WebSocket4Net;

Expand Down Expand Up @@ -32,7 +34,20 @@ public WebSocket4NetTextConnection(WebSocket webSocket, IWampTextBinding<TMessag
/// <param name="serverAddress">The server address to connect to.</param>
/// <param name="binding">The <see cref="IWampTextBinding{TMessage}"/> to use.</param>
public WebSocket4NetTextConnection(string serverAddress, IWampTextBinding<TMessage> binding)
: base(serverAddress, binding)
: this(serverAddress: serverAddress, binding: binding, configureSecurityOptions: null)
{
}

/// <summary>
/// Creates a new instance of <see cref="WebSocket4NetTextConnection{TMessage}"/>
/// given the server address to connect to, the text binding to use, and an Action
/// to configure WebSocket Security Options.
/// </summary>
/// <param name="serverAddress">The server address to connect to.</param>
/// <param name="binding">The <see cref="IWampTextBinding{TMessage}"/> to use.</param>
/// <param name="configureSecurityOptions">If non-null, called to allow custom setup of the WebSocket security options.</param>
public WebSocket4NetTextConnection(string serverAddress, IWampTextBinding<TMessage> binding, Action<SecurityOption> configureSecurityOptions)
: base(serverAddress, binding, configureSecurityOptions)
{
mBinding = binding;
WebSocket.MessageReceived += OnMessageReceived;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using WampSharp.Binding;
using WampSharp.Fleck;
Expand Down Expand Up @@ -68,7 +70,7 @@ public DefaultWampAuthenticationHost
/// <param name="sessionAuthenticationFactory"></param>
/// <param name="bindings">The given bindings.</param>
/// <param name="cookieAuthenticatorFactory"></param>
/// <param name="certificate"></param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
public DefaultWampAuthenticationHost
(string location,
IWampSessionAuthenticatorFactory sessionAuthenticationFactory,
Expand Down Expand Up @@ -99,19 +101,54 @@ public DefaultWampAuthenticationHost
/// <param name="cookieAuthenticatorFactory">The given <see cref="ICookieAuthenticatorFactory"/> used to authenticate
/// users given their cookies.</param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
public DefaultWampAuthenticationHost(string location,
IWampSessionAuthenticatorFactory sessionAuthenticationFactory,
IWampRealmContainer realmContainer = null,
IWampUriValidator uriValidator = null,
IEnumerable<IWampBinding> bindings = null,
ICookieAuthenticatorFactory cookieAuthenticatorFactory = null,
X509Certificate2 certificate = null)
: this(location: location,
sessionAuthenticationFactory: sessionAuthenticationFactory,
realmContainer: null,
uriValidator: null,
bindings: bindings,
cookieAuthenticatorFactory: cookieAuthenticatorFactory,
certificate: certificate,
getEnabledSslProtocols: null)
{
}

/// <summary>
/// Initializes a new instance of <see cref="DefaultWampHost"/> listening at
/// the given location with the given bindings and the given
/// <see cref="IWampRealmContainer"/>.
/// </summary>
/// <param name="location">The given location.</param>
/// <param name="sessionAuthenticationFactory">The <see cref="IWampSessionAuthenticatorFactory"/>
/// used to accept pending clients.</param>
/// <param name="realmContainer">The <see cref="IWampRealmContainer"/> associated with this
/// host.</param>
/// <param name="uriValidator">The <see cref="IWampUriValidator"/> used to validate uris.</param>
/// <param name="bindings">The given bindings.</param>
/// <param name="cookieAuthenticatorFactory">The given <see cref="ICookieAuthenticatorFactory"/> used to authenticate
/// users given their cookies.</param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
/// <param name="getEnabledSslProtocols"> If non-null, used to set Fleck's EnabledSslProtocols. </param>
public DefaultWampAuthenticationHost(string location,
IWampSessionAuthenticatorFactory sessionAuthenticationFactory,
IWampRealmContainer realmContainer = null,
IWampUriValidator uriValidator = null,
IEnumerable<IWampBinding> bindings = null,
ICookieAuthenticatorFactory cookieAuthenticatorFactory = null,
X509Certificate2 certificate = null)
X509Certificate2 certificate = null,
Func<SslProtocols> getEnabledSslProtocols = null)
: base(sessionAuthenticationFactory, realmContainer, uriValidator)
{
bindings = bindings ?? new IWampBinding[] {new JTokenJsonBinding(), new JTokenMsgpackBinding()};
bindings = bindings ?? new IWampBinding[] { new JTokenJsonBinding(), new JTokenMsgpackBinding() };

this.RegisterTransport(
new FleckAuthenticatedWebSocketTransport(location, cookieAuthenticatorFactory, certificate),
new FleckAuthenticatedWebSocketTransport(location, cookieAuthenticatorFactory, certificate, getEnabledSslProtocols),
bindings.ToArray());
}

Expand Down
33 changes: 28 additions & 5 deletions src/net45/WampSharp.Default.Router/WAMP2/V2/DefaultWampHost.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using WampSharp.Binding;
using WampSharp.Fleck;
Expand Down Expand Up @@ -33,7 +35,7 @@ public DefaultWampHost(string location)
/// <see cref="IWampRealmContainer"/>.
/// </summary>
/// <param name="location">The given location.</param>
/// <param name="certificate"></param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
public DefaultWampHost(string location, X509Certificate2 certificate = null)
: this(location: location, bindings: null, certificate: certificate)
{
Expand All @@ -46,7 +48,7 @@ public DefaultWampHost(string location, X509Certificate2 certificate = null)
/// </summary>
/// <param name="location">The given location.</param>
/// <param name="bindings">The given bindings.</param>
/// <param name="certificate"></param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
public DefaultWampHost(string location, IEnumerable<IWampBinding> bindings, X509Certificate2 certificate = null)
: this(location: location, realmContainer: null, uriValidator: null, bindings: bindings, certificate: certificate)
{
Expand All @@ -61,17 +63,38 @@ public DefaultWampHost(string location, IEnumerable<IWampBinding> bindings, X509
/// <param name="realmContainer">The given <see cref="IWampRealmContainer"/>.</param>
/// <param name="uriValidator">The <see cref="IWampUriValidator"/> to use to validate uris.</param>
/// <param name="bindings">The given bindings.</param>
/// <param name="certificate"></param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
public DefaultWampHost(string location,
IWampRealmContainer realmContainer = null,
IWampUriValidator uriValidator = null,
IEnumerable<IWampBinding> bindings = null,
X509Certificate2 certificate = null)
: this(location: location, realmContainer: null, uriValidator: null, bindings: bindings, certificate: certificate, getEnabledSslProtocols: null)
{
}

/// <summary>
/// Initializes a new instance of <see cref="DefaultWampHost"/> listening at
/// the given location with the given bindings and the given
/// <see cref="IWampRealmContainer"/>.
/// </summary>
/// <param name="location">The given location.</param>
/// <param name="realmContainer">The given <see cref="IWampRealmContainer"/>.</param>
/// <param name="uriValidator">The <see cref="IWampUriValidator"/> to use to validate uris.</param>
/// <param name="bindings">The given bindings.</param>
/// <param name="certificate">The <see cref="X509Certificate2"/> certificate to use for secured websockets.</param>
/// <param name="getEnabledSslProtocols"> If non-null, used to set Fleck's EnabledSslProtocols. </param>
public DefaultWampHost(string location,
IWampRealmContainer realmContainer = null,
IWampUriValidator uriValidator = null,
IEnumerable<IWampBinding> bindings = null,
X509Certificate2 certificate = null,
Func<SslProtocols> getEnabledSslProtocols = null)
: base(realmContainer, uriValidator)
{
bindings = bindings ?? new IWampBinding[] {new JTokenJsonBinding(), new JTokenMsgpackBinding()};

this.RegisterTransport(new FleckWebSocketTransport(location, certificate),
this.RegisterTransport(new FleckWebSocketTransport(location, certificate, getEnabledSslProtocols),
bindings.ToArray());
}

Expand Down
Loading

0 comments on commit dc6b466

Please sign in to comment.