From 2db289a6585aa92cd1d89816d1488076f5d83047 Mon Sep 17 00:00:00 2001 From: Zazzmatazz Date: Fri, 2 Jun 2017 09:19:47 -0400 Subject: [PATCH] Added TLS1.2 support to client and server. Added MqttClientSslChannel and MqttServerSslChannel which both utilize an SSL stream. Added options to both MqttCLientOptions and MqttServerOptions. I was unable to update the code in MQTTnet.UniversalWindows due to my lack of Windows 10. --- .../MQTTnet.NetCoreApp/MqttClientFactory.cs | 7 +- .../MqttClientSslChannel.cs | 122 +++++++++++++++++ .../MQTTnet.NetCoreApp/MqttServerFactory.cs | 4 +- .../MqttServerSslChannel.cs | 123 ++++++++++++++++++ .../MqttSslServerAdapter.cs | 64 +++++++++ .../MQTTnet.NetFramework.csproj | 3 + .../MQTTnet.NetFramework/MqttClientFactory.cs | 9 +- .../MqttClientSslChannel.cs | 122 +++++++++++++++++ .../MQTTnet.NetFramework/MqttServerFactory.cs | 6 +- .../MqttServerSslChannel.cs | 123 ++++++++++++++++++ .../MqttSslServerAdapter.cs | 64 +++++++++ MQTTnet.Core/Client/MqttClientOptions.cs | 19 +++ MQTTnet.Core/Server/MqttServerOptions.cs | 7 + 13 files changed, 667 insertions(+), 6 deletions(-) create mode 100644 Frameworks/MQTTnet.NetCoreApp/MqttClientSslChannel.cs create mode 100644 Frameworks/MQTTnet.NetCoreApp/MqttServerSslChannel.cs create mode 100644 Frameworks/MQTTnet.NetCoreApp/MqttSslServerAdapter.cs create mode 100644 Frameworks/MQTTnet.NetFramework/MqttClientSslChannel.cs create mode 100644 Frameworks/MQTTnet.NetFramework/MqttServerSslChannel.cs create mode 100644 Frameworks/MQTTnet.NetFramework/MqttSslServerAdapter.cs diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs b/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs index 4da24a1..62b6569 100644 --- a/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs +++ b/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs @@ -1,5 +1,6 @@ using System; using MQTTnet.Core.Adapter; +using MQTTnet.Core.Channel; using MQTTnet.Core.Client; using MQTTnet.Core.Serializer; @@ -11,7 +12,11 @@ namespace MQTTnet { if (options == null) throw new ArgumentNullException(nameof(options)); - return new MqttClient(options, new MqttChannelCommunicationAdapter(new MqttTcpChannel(), new DefaultMqttV311PacketSerializer())); + return new MqttClient(options, + // The cast to IMqttCommunicationChannel is required... Roslyn is too stupid to + // figure out how to cast back to the base type + new MqttChannelCommunicationAdapter(options.UseSSL ? new MqttClientSslChannel() : (IMqttCommunicationChannel) new MqttTcpChannel(), + new DefaultMqttV311PacketSerializer())); } } } diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttClientSslChannel.cs b/Frameworks/MQTTnet.NetCoreApp/MqttClientSslChannel.cs new file mode 100644 index 0000000..26b12fb --- /dev/null +++ b/Frameworks/MQTTnet.NetCoreApp/MqttClientSslChannel.cs @@ -0,0 +1,122 @@ +using System; +using System.IO; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Authentication; +using System.Threading.Tasks; +using MQTTnet.Core.Channel; +using MQTTnet.Core.Client; +using MQTTnet.Core.Exceptions; + +namespace MQTTnet +{ + /// + /// Describes an SSL channel to an MQTT server. + /// + public class MqttClientSslChannel : IMqttCommunicationChannel, IDisposable + { + private readonly Socket _socket; + private SslStream _sslStream; + + /// + /// Creates a new . + /// + public MqttClientSslChannel() + { + _socket = new Socket(SocketType.Stream, ProtocolType.Tcp); + } + + /// + /// Creates a new with a predefined . + /// + /// + public MqttClientSslChannel(Socket socket) + { + _socket = socket ?? throw new ArgumentNullException(nameof(socket)); + } + + /// + /// Asynchronously connects to the host described in the . + /// + /// The describing the connection. + public async Task ConnectAsync(MqttClientOptions options) + { + try + { + await _socket.ConnectAsync(options.Server, options.Port); + + NetworkStream ns = new NetworkStream(_socket, true); + _sslStream = new SslStream(ns); + + await _sslStream.AuthenticateAsClientAsync(options.Server, null, SslProtocols.Tls12, false); + + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously disconnects the client from the server. + /// + public Task DisconnectAsync() + { + try + { + _socket.Dispose(); + return Task.FromResult(0); + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously writes a sequence of bytes to the socket. + /// + /// The buffer to write data from. + public async Task WriteAsync(byte[] buffer) + { + if (buffer == null) + throw new ArgumentNullException(nameof(buffer)); + + try + { + await _sslStream.WriteAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Asynchronously reads a sequence of bytes from the socket. + /// + /// The buffer to write the data into. + public async Task ReadAsync(byte[] buffer) + { + try + { + await _sslStream.ReadAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Releases all resources used by the . + /// + public void Dispose() + { + _sslStream?.Dispose(); + _socket?.Dispose(); + } + } +} \ No newline at end of file diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs b/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs index a725426..5098ea2 100644 --- a/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs +++ b/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs @@ -1,4 +1,5 @@ using System; +using MQTTnet.Core.Adapter; using MQTTnet.Core.Server; namespace MQTTnet @@ -9,7 +10,8 @@ namespace MQTTnet { if (options == null) throw new ArgumentNullException(nameof(options)); - return new MqttServer(options, new MqttServerAdapter()); + // The cast to IMqttServerAdapter is required... stupidly... + return new MqttServer(options, options.UseSSL ? (IMqttServerAdapter)new MqttSslServerAdapter() : new MqttServerAdapter()); } } } diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttServerSslChannel.cs b/Frameworks/MQTTnet.NetCoreApp/MqttServerSslChannel.cs new file mode 100644 index 0000000..c4c5713 --- /dev/null +++ b/Frameworks/MQTTnet.NetCoreApp/MqttServerSslChannel.cs @@ -0,0 +1,123 @@ +using System; +using System.IO; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; +using MQTTnet.Core.Channel; +using MQTTnet.Core.Client; +using MQTTnet.Core.Exceptions; + +namespace MQTTnet +{ + /// + /// Describes an SSL channel to a client. + /// + public class MqttServerSslChannel : IMqttCommunicationChannel, IDisposable + { + private readonly Socket _socket; + private readonly SslStream _sslStream; + private readonly X509Certificate2 _cert; + + /// + /// Creates a new with a predefined . + /// + /// The client socket. + /// The X509 certificate used to authenticate as a server. + public MqttServerSslChannel(Socket socket, X509Certificate2 cert) + { + _socket = socket ?? throw new ArgumentNullException(nameof(socket)); + _cert = cert ?? throw new ArgumentNullException(nameof(cert)); + + if (_socket.Connected) + { + NetworkStream ns = new NetworkStream(_socket, true); + _sslStream = new SslStream(ns); + } + } + + public async Task Authenticate() + { + await _sslStream.AuthenticateAsServerAsync(_cert, false, SslProtocols.Tls12, false); + } + + /// + /// Asynchronously connects to the client described in the . + /// + /// The describing the connection. + public async Task ConnectAsync(MqttClientOptions options) + { + try + { + await _socket.ConnectAsync(options.Server, options.Port); + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously disconnects the client from the server. + /// + public Task DisconnectAsync() + { + try + { + _socket.Dispose(); + return Task.FromResult(0); + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously writes a sequence of bytes to the socket. + /// + /// The buffer to write data from. + public async Task WriteAsync(byte[] buffer) + { + if (buffer == null) + throw new ArgumentNullException(nameof(buffer)); + + try + { + await _sslStream.WriteAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Asynchronously reads a sequence of bytes from the socket. + /// + /// The buffer to write the data into. + public async Task ReadAsync(byte[] buffer) + { + try + { + await _sslStream.ReadAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Releases all resources used by the . + /// + public void Dispose() + { + _sslStream?.Dispose(); + _socket?.Dispose(); + } + } +} \ No newline at end of file diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttSslServerAdapter.cs b/Frameworks/MQTTnet.NetCoreApp/MqttSslServerAdapter.cs new file mode 100644 index 0000000..58b0a3b --- /dev/null +++ b/Frameworks/MQTTnet.NetCoreApp/MqttSslServerAdapter.cs @@ -0,0 +1,64 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using MQTTnet.Core.Adapter; +using MQTTnet.Core.Serializer; +using MQTTnet.Core.Server; + +namespace MQTTnet +{ + public class MqttSslServerAdapter : IMqttServerAdapter, IDisposable + { + private CancellationTokenSource _cancellationTokenSource; + private Socket _socket; + private X509Certificate2 _x590Certificate2; + + public event EventHandler ClientConnected; + + public void Start(MqttServerOptions options) + { + if (_socket != null) throw new InvalidOperationException("Server is already started."); + + _cancellationTokenSource = new CancellationTokenSource(); + + _socket = new Socket(SocketType.Stream, ProtocolType.Tcp); + _socket.Bind(new IPEndPoint(IPAddress.Any, options.Port)); + _socket.Listen(options.ConnectionBacklog); + + Task.Run(async () => await AcceptConnectionsAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token); + + _x590Certificate2 = new X509Certificate2(options.CertificatePath); + } + + public void Stop() + { + _cancellationTokenSource?.Dispose(); + _cancellationTokenSource = null; + + _socket?.Dispose(); + _socket = null; + } + + public void Dispose() + { + Stop(); + } + + private async Task AcceptConnectionsAsync(CancellationToken cancellationToken) + { + while (!cancellationToken.IsCancellationRequested) + { + var clientSocket = await _socket.AcceptAsync(); + + MqttServerSslChannel mssc = new MqttServerSslChannel(clientSocket, _x590Certificate2); + await mssc.Authenticate(); + + var clientAdapter = new MqttChannelCommunicationAdapter(mssc, new DefaultMqttV311PacketSerializer()); + ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter)); + } + } + } +} \ No newline at end of file diff --git a/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj b/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj index 0c63762..314c158 100644 --- a/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj +++ b/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj @@ -103,6 +103,9 @@ + + + diff --git a/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs b/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs index 4da24a1..048112f 100644 --- a/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs +++ b/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs @@ -1,5 +1,6 @@ using System; using MQTTnet.Core.Adapter; +using MQTTnet.Core.Channel; using MQTTnet.Core.Client; using MQTTnet.Core.Serializer; @@ -10,8 +11,12 @@ namespace MQTTnet public MqttClient CreateMqttClient(MqttClientOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); - - return new MqttClient(options, new MqttChannelCommunicationAdapter(new MqttTcpChannel(), new DefaultMqttV311PacketSerializer())); + + return new MqttClient(options, + // The cast to IMqttCommunicationChannel is required... Roslyn is too stupid to + // figure out how to cast back to the base type + new MqttChannelCommunicationAdapter(options.UseSSL ? new MqttClientSslChannel() : (IMqttCommunicationChannel)new MqttTcpChannel(), + new DefaultMqttV311PacketSerializer())); } } } diff --git a/Frameworks/MQTTnet.NetFramework/MqttClientSslChannel.cs b/Frameworks/MQTTnet.NetFramework/MqttClientSslChannel.cs new file mode 100644 index 0000000..8adf14b --- /dev/null +++ b/Frameworks/MQTTnet.NetFramework/MqttClientSslChannel.cs @@ -0,0 +1,122 @@ +using System; +using System.IO; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Authentication; +using System.Threading.Tasks; +using MQTTnet.Core.Channel; +using MQTTnet.Core.Client; +using MQTTnet.Core.Exceptions; + +namespace MQTTnet +{ + /// + /// Describes an SSL channel to an MQTT server. + /// + public class MqttClientSslChannel : IMqttCommunicationChannel, IDisposable + { + private readonly Socket _socket; + private SslStream _sslStream; + + /// + /// Creates a new . + /// + public MqttClientSslChannel() + { + _socket = new Socket(SocketType.Stream, ProtocolType.Tcp); + } + + /// + /// Creates a new with a predefined . + /// + /// + public MqttClientSslChannel(Socket socket) + { + _socket = socket ?? throw new ArgumentNullException(nameof(socket)); + } + + /// + /// Asynchronously connects to the host described in the . + /// + /// The describing the connection. + public async Task ConnectAsync(MqttClientOptions options) + { + try + { + await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.Port, + null); + + NetworkStream ns = new NetworkStream(_socket, true); + _sslStream = new SslStream(ns); + + await _sslStream.AuthenticateAsClientAsync(options.Server, null, SslProtocols.Tls12, false); + + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously disconnects the client from the server. + /// + public async Task DisconnectAsync() + { + try + { + await Task.Factory.FromAsync(_socket.BeginDisconnect, _socket.EndDisconnect, true, null); + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously writes a sequence of bytes to the socket. + /// + /// The buffer to write data from. + public async Task WriteAsync(byte[] buffer) + { + if (buffer == null) + throw new ArgumentNullException(nameof(buffer)); + + try + { + await _sslStream.WriteAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Asynchronously reads a sequence of bytes from the socket. + /// + /// The buffer to write the data into. + public async Task ReadAsync(byte[] buffer) + { + try + { + await _sslStream.ReadAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Releases all resources used by the . + /// + public void Dispose() + { + _sslStream?.Dispose(); + _socket?.Dispose(); + } + } +} \ No newline at end of file diff --git a/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs b/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs index a725426..a26fbdb 100644 --- a/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs +++ b/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs @@ -1,4 +1,5 @@ using System; +using MQTTnet.Core.Adapter; using MQTTnet.Core.Server; namespace MQTTnet @@ -8,8 +9,9 @@ namespace MQTTnet public MqttServer CreateMqttServer(MqttServerOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); - - return new MqttServer(options, new MqttServerAdapter()); + + // The cast to IMqttServerAdapter is required... stupidly... + return new MqttServer(options, options.UseSSL ? (IMqttServerAdapter) new MqttSslServerAdapter() : new MqttServerAdapter()); } } } diff --git a/Frameworks/MQTTnet.NetFramework/MqttServerSslChannel.cs b/Frameworks/MQTTnet.NetFramework/MqttServerSslChannel.cs new file mode 100644 index 0000000..2f01462 --- /dev/null +++ b/Frameworks/MQTTnet.NetFramework/MqttServerSslChannel.cs @@ -0,0 +1,123 @@ +using System; +using System.IO; +using System.Net.Security; +using System.Net.Sockets; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; +using MQTTnet.Core.Channel; +using MQTTnet.Core.Client; +using MQTTnet.Core.Exceptions; + +namespace MQTTnet +{ + /// + /// Describes an SSL channel to a client. + /// + public class MqttServerSslChannel : IMqttCommunicationChannel, IDisposable + { + private readonly Socket _socket; + private SslStream _sslStream; + private X509Certificate2 _cert; + + /// + /// Creates a new with a predefined . + /// + /// The client socket. + /// The X509 certificate used to authenticate as a server. + public MqttServerSslChannel(Socket socket, X509Certificate2 cert) + { + _socket = socket ?? throw new ArgumentNullException(nameof(socket)); + _cert = cert ?? throw new ArgumentNullException(nameof(cert)); + + if (_socket.Connected) + { + NetworkStream ns = new NetworkStream(_socket, true); + _sslStream = new SslStream(ns); + } + } + + public async Task Authenticate() + { + await _sslStream.AuthenticateAsServerAsync(_cert, false, SslProtocols.Tls12, false); + } + + /// + /// Asynchronously connects to the client described in the . + /// + /// The describing the connection. + public async Task ConnectAsync(MqttClientOptions options) + { + try + { + await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.Port, + null); + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously disconnects the client from the server. + /// + public async Task DisconnectAsync() + { + try + { + await Task.Factory.FromAsync(_socket.BeginDisconnect, _socket.EndDisconnect, true, null); + } + catch (SocketException exception) + { + throw new MqttCommunicationException(exception); + } + } + + /// + /// Asynchronously writes a sequence of bytes to the socket. + /// + /// The buffer to write data from. + public async Task WriteAsync(byte[] buffer) + { + if (buffer == null) + throw new ArgumentNullException(nameof(buffer)); + + try + { + await _sslStream.WriteAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Asynchronously reads a sequence of bytes from the socket. + /// + /// The buffer to write the data into. + public async Task ReadAsync(byte[] buffer) + { + try + { + await _sslStream.ReadAsync(buffer, 0, buffer.Length); + } + catch (Exception ex) + when (ex is SocketException || ex is IOException) + { + throw new MqttCommunicationException(ex); + } + } + + /// + /// Releases all resources used by the . + /// + public void Dispose() + { + _sslStream?.Dispose(); + _socket?.Dispose(); + } + } +} \ No newline at end of file diff --git a/Frameworks/MQTTnet.NetFramework/MqttSslServerAdapter.cs b/Frameworks/MQTTnet.NetFramework/MqttSslServerAdapter.cs new file mode 100644 index 0000000..f02c74b --- /dev/null +++ b/Frameworks/MQTTnet.NetFramework/MqttSslServerAdapter.cs @@ -0,0 +1,64 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using MQTTnet.Core.Adapter; +using MQTTnet.Core.Serializer; +using MQTTnet.Core.Server; + +namespace MQTTnet +{ + public class MqttSslServerAdapter : IMqttServerAdapter, IDisposable + { + private CancellationTokenSource _cancellationTokenSource; + private Socket _socket; + private X509Certificate2 _x590Certificate2; + + public event EventHandler ClientConnected; + + public void Start(MqttServerOptions options) + { + if (_socket != null) throw new InvalidOperationException("Server is already started."); + + _cancellationTokenSource = new CancellationTokenSource(); + + _socket = new Socket(SocketType.Stream, ProtocolType.Tcp); + _socket.Bind(new IPEndPoint(IPAddress.Any, options.Port)); + _socket.Listen(options.ConnectionBacklog); + + Task.Run(async () => await AcceptConnectionsAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token); + + _x590Certificate2 = new X509Certificate2(options.CertificatePath); + } + + public void Stop() + { + _cancellationTokenSource?.Dispose(); + _cancellationTokenSource = null; + + _socket?.Dispose(); + _socket = null; + } + + public void Dispose() + { + Stop(); + } + + private async Task AcceptConnectionsAsync(CancellationToken cancellationToken) + { + while (!cancellationToken.IsCancellationRequested) + { + var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null); + + MqttServerSslChannel mssc = new MqttServerSslChannel(clientSocket, _x590Certificate2); + await mssc.Authenticate(); + + var clientAdapter = new MqttChannelCommunicationAdapter(mssc, new DefaultMqttV311PacketSerializer()); + ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter)); + } + } + } +} \ No newline at end of file diff --git a/MQTTnet.Core/Client/MqttClientOptions.cs b/MQTTnet.Core/Client/MqttClientOptions.cs index 830fef5..d306bfe 100644 --- a/MQTTnet.Core/Client/MqttClientOptions.cs +++ b/MQTTnet.Core/Client/MqttClientOptions.cs @@ -19,5 +19,24 @@ namespace MQTTnet.Core.Client public TimeSpan KeepAlivePeriod { get; set; } = TimeSpan.FromSeconds(5); public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10); + + /// + /// Use SSL to communicate with the MQTT server. + /// + /// Setting this value to true will also set to 8883 if its value was 1883 (not set). + public bool UseSSL + { + get => _useSSL; + set + { + // Automatically set the port to the MQTT SSL port (8883) if it wasn't set already + if (value && Port == 1883) + Port = 8883; + + _useSSL = value; + } + } + + private bool _useSSL; } } diff --git a/MQTTnet.Core/Server/MqttServerOptions.cs b/MQTTnet.Core/Server/MqttServerOptions.cs index 0ce2309..0638700 100644 --- a/MQTTnet.Core/Server/MqttServerOptions.cs +++ b/MQTTnet.Core/Server/MqttServerOptions.cs @@ -13,5 +13,12 @@ namespace MQTTnet.Core.Server public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10); public Func ConnectionValidator { get; set; } + + public bool UseSSL = false; + + /// + /// The path to the X509 SSL certificate. + /// + public string CertificatePath = string.Empty; } }