mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-11-05 22:16:32 +08:00
Add support for certificate validation callback for Web Socket connections.
This commit is contained in:
+13
-4
@@ -14,12 +14,12 @@
|
|||||||
<releaseNotes>
|
<releaseNotes>
|
||||||
* [Core] Renamed some topic filter relevant classes (BREAKING CHANGE!).
|
* [Core] Renamed some topic filter relevant classes (BREAKING CHANGE!).
|
||||||
* [Core] Improved task management for UWP connections (thanks to @xgstation).
|
* [Core] Improved task management for UWP connections (thanks to @xgstation).
|
||||||
* [LowLevelMqttClient]
|
|
||||||
* [Client] Added method to trigger PING/PONG manually (connection check etc.).
|
* [Client] Added method to trigger PING/PONG manually (connection check etc.).
|
||||||
|
* [Client] Added support for certificate validation callback when using Web Sockets (requires netstandard2.1+).
|
||||||
|
* [Client] Fixed a memory leak when web socket based connections trying to reconnect with an offline server.
|
||||||
* [ManagedClient] Added method to trigger PING/PONG manually (connection check etc.).
|
* [ManagedClient] Added method to trigger PING/PONG manually (connection check etc.).
|
||||||
* [Server]
|
* [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1.
|
||||||
* [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1
|
* [MQTTnet.Server] Fixed wrong version output.
|
||||||
* [MQTTnet.Server]
|
|
||||||
</releaseNotes>
|
</releaseNotes>
|
||||||
<copyright>Copyright Christian Kratky 2016-2020</copyright>
|
<copyright>Copyright Christian Kratky 2016-2020</copyright>
|
||||||
<tags>MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin</tags>
|
<tags>MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin</tags>
|
||||||
@@ -36,6 +36,12 @@
|
|||||||
<dependency id="System.Net.WebSockets" version="4.3.0" />
|
<dependency id="System.Net.WebSockets" version="4.3.0" />
|
||||||
<dependency id="System.Net.WebSockets.Client" version="4.3.2" />
|
<dependency id="System.Net.WebSockets.Client" version="4.3.2" />
|
||||||
</group>
|
</group>
|
||||||
|
<group targetFramework="netstandard2.1">
|
||||||
|
<dependency id="NETStandard.Library" version="2.0.0" />
|
||||||
|
<dependency id="System.Net.Security" version="4.3.2" />
|
||||||
|
<dependency id="System.Net.WebSockets" version="4.3.0" />
|
||||||
|
<dependency id="System.Net.WebSockets.Client" version="4.3.2" />
|
||||||
|
</group>
|
||||||
<group targetFramework="uap10.0">
|
<group targetFramework="uap10.0">
|
||||||
<dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.10" />
|
<dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.10" />
|
||||||
</group>
|
</group>
|
||||||
@@ -55,6 +61,9 @@
|
|||||||
<!-- .NET Standard 2.0 -->
|
<!-- .NET Standard 2.0 -->
|
||||||
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\netstandard2.0\"/>
|
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\netstandard2.0\"/>
|
||||||
|
|
||||||
|
<!-- .NET Standard 2.1 -->
|
||||||
|
<file src="..\Source\MQTTnet\bin\Release\netstandard2.1\MQTTnet.*" target="lib\netstandard2.1\"/>
|
||||||
|
|
||||||
<!-- Universal Windows -->
|
<!-- Universal Windows -->
|
||||||
<file src="..\Source\MQTTnet\bin\Release\uap10.0\MQTTnet.*" target="lib\uap10.0\"/>
|
<file src="..\Source\MQTTnet\bin\Release\uap10.0\MQTTnet.*" target="lib\uap10.0\"/>
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
|
|||||||
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.1" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
|
||||||
# Build the ASP.NET Core 2.0 extension
|
# Build the ASP.NET Core 2.0 extension
|
||||||
@@ -38,6 +39,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
|
|||||||
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.1" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
|
||||||
# Build the Managed Client extension
|
# Build the Managed Client extension
|
||||||
@@ -45,6 +47,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
|
|||||||
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.1" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
|
||||||
# Build the WebSocket4Net extension
|
# Build the WebSocket4Net extension
|
||||||
@@ -52,6 +55,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
|
|||||||
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.1" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
|
||||||
|
|
||||||
# Create NuGet packages.
|
# Create NuGet packages.
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _isConnected || Interlocked.Read(ref _isDisconnectPending) != 0;
|
return _isConnected && Interlocked.Read(ref _isDisconnectPending) == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System.Net.Security;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
|
namespace MQTTnet.Client.Options
|
||||||
|
{
|
||||||
|
public class MqttClientCertificateValidationCallbackContext
|
||||||
|
{
|
||||||
|
public X509Certificate Certificate { get; set; }
|
||||||
|
|
||||||
|
public X509Chain Chain { get; set; }
|
||||||
|
|
||||||
|
public SslPolicyErrors SslPolicyErrors { get; set; }
|
||||||
|
|
||||||
|
public IMqttClientChannelOptions ClientOptions { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -262,6 +262,7 @@ namespace MQTTnet.Client.Options
|
|||||||
Certificates = _tlsParameters.Certificates?.ToList(),
|
Certificates = _tlsParameters.Certificates?.ToList(),
|
||||||
#endif
|
#endif
|
||||||
CertificateValidationCallback = _tlsParameters.CertificateValidationCallback,
|
CertificateValidationCallback = _tlsParameters.CertificateValidationCallback,
|
||||||
|
CertificateValidationHandler = _tlsParameters.CertificateValidationHandler,
|
||||||
IgnoreCertificateChainErrors = _tlsParameters.IgnoreCertificateChainErrors,
|
IgnoreCertificateChainErrors = _tlsParameters.IgnoreCertificateChainErrors,
|
||||||
IgnoreCertificateRevocationErrors = _tlsParameters.IgnoreCertificateRevocationErrors
|
IgnoreCertificateRevocationErrors = _tlsParameters.IgnoreCertificateRevocationErrors
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,12 +10,15 @@ namespace MQTTnet.Client.Options
|
|||||||
{
|
{
|
||||||
public bool UseTls { get; set; }
|
public bool UseTls { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("This property will be removed soon. Use CertificateValidationHandler instead.")]
|
||||||
public Func<X509Certificate, X509Chain, SslPolicyErrors, IMqttClientOptions, bool> CertificateValidationCallback
|
public Func<X509Certificate, X509Chain, SslPolicyErrors, IMqttClientOptions, bool> CertificateValidationCallback
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Func<MqttClientCertificateValidationCallbackContext, bool> CertificateValidationHandler { get; set; }
|
||||||
|
|
||||||
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
|
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
|
||||||
|
|
||||||
#if WINDOWS_UWP
|
#if WINDOWS_UWP
|
||||||
@@ -23,7 +26,6 @@ namespace MQTTnet.Client.Options
|
|||||||
#else
|
#else
|
||||||
public IEnumerable<X509Certificate> Certificates { get; set; }
|
public IEnumerable<X509Certificate> Certificates { get; set; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public bool AllowUntrustedCertificates { get; set; }
|
public bool AllowUntrustedCertificates { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace MQTTnet.Client.Options
|
|||||||
public bool IgnoreCertificateChainErrors { get; set; }
|
public bool IgnoreCertificateChainErrors { get; set; }
|
||||||
|
|
||||||
public bool AllowUntrustedCertificates { get; set; }
|
public bool AllowUntrustedCertificates { get; set; }
|
||||||
|
|
||||||
#if WINDOWS_UWP
|
#if WINDOWS_UWP
|
||||||
public List<byte[]> Certificates { get; set; }
|
public List<byte[]> Certificates { get; set; }
|
||||||
#else
|
#else
|
||||||
@@ -23,6 +24,9 @@ namespace MQTTnet.Client.Options
|
|||||||
|
|
||||||
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
|
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
|
||||||
|
|
||||||
|
[Obsolete("This property will be removed soon. Use CertificateValidationHandler instead.")]
|
||||||
public Func<X509Certificate, X509Chain, SslPolicyErrors, IMqttClientOptions, bool> CertificateValidationCallback { get; set; }
|
public Func<X509Certificate, X509Chain, SslPolicyErrors, IMqttClientOptions, bool> CertificateValidationCallback { get; set; }
|
||||||
|
|
||||||
|
public Func<MqttClientCertificateValidationCallbackContext, bool> CertificateValidationHandler { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
return "netstandard1.3";
|
return "netstandard1.3";
|
||||||
#elif NETSTANDARD2_0
|
#elif NETSTANDARD2_0
|
||||||
return "netstandard2.0";
|
return "netstandard2.0";
|
||||||
|
#elif NETSTANDARD2_1
|
||||||
|
return "netstandard2.1";
|
||||||
#elif WINDOWS_UWP
|
#elif WINDOWS_UWP
|
||||||
return "uap10.0";
|
return "uap10.0";
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace MQTTnet.Implementations
|
|||||||
|
|
||||||
var networkStream = socket.GetStream();
|
var networkStream = socket.GetStream();
|
||||||
|
|
||||||
if (_options.TlsOptions.UseTls)
|
if (_options.TlsOptions?.UseTls == true)
|
||||||
{
|
{
|
||||||
var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback);
|
var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback);
|
||||||
try
|
try
|
||||||
@@ -181,9 +181,28 @@ namespace MQTTnet.Implementations
|
|||||||
|
|
||||||
bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
||||||
{
|
{
|
||||||
if (_options.TlsOptions.CertificateValidationCallback != null)
|
#region OBSOLETE
|
||||||
|
|
||||||
|
var certificateValidationCallback = _options?.TlsOptions?.CertificateValidationCallback;
|
||||||
|
if (certificateValidationCallback != null)
|
||||||
{
|
{
|
||||||
return _options.TlsOptions.CertificateValidationCallback(x509Certificate, chain, sslPolicyErrors, _clientOptions);
|
return certificateValidationCallback(x509Certificate, chain, sslPolicyErrors, _clientOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var certificateValidationHandler = _options?.TlsOptions?.CertificateValidationHandler;
|
||||||
|
if (certificateValidationHandler != null)
|
||||||
|
{
|
||||||
|
var context = new MqttClientCertificateValidationCallbackContext
|
||||||
|
{
|
||||||
|
Certificate = x509Certificate,
|
||||||
|
Chain = chain,
|
||||||
|
SslPolicyErrors = sslPolicyErrors,
|
||||||
|
ClientOptions = _options
|
||||||
|
};
|
||||||
|
|
||||||
|
return certificateValidationHandler(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sslPolicyErrors == SslPolicyErrors.None)
|
if (sslPolicyErrors == SslPolicyErrors.None)
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
using System;
|
using MQTTnet.Channel;
|
||||||
|
using MQTTnet.Client.Options;
|
||||||
|
using MQTTnet.Internal;
|
||||||
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MQTTnet.Channel;
|
|
||||||
using MQTTnet.Client.Options;
|
|
||||||
using MQTTnet.Internal;
|
|
||||||
|
|
||||||
namespace MQTTnet.Implementations
|
namespace MQTTnet.Implementations
|
||||||
{
|
{
|
||||||
public class MqttWebSocketChannel : Disposable, IMqttChannel
|
public sealed class MqttWebSocketChannel : IMqttChannel
|
||||||
{
|
{
|
||||||
private readonly MqttClientWebSocketOptions _options;
|
readonly MqttClientWebSocketOptions _options;
|
||||||
|
|
||||||
private SemaphoreSlim _sendLock = new SemaphoreSlim(1, 1);
|
AsyncLock _sendLock = new AsyncLock();
|
||||||
private WebSocket _webSocket;
|
WebSocket _webSocket;
|
||||||
|
|
||||||
public MqttWebSocketChannel(MqttClientWebSocketOptions options)
|
public MqttWebSocketChannel(MqttClientWebSocketOptions options)
|
||||||
{
|
{
|
||||||
@@ -53,6 +53,67 @@ namespace MQTTnet.Implementations
|
|||||||
}
|
}
|
||||||
|
|
||||||
var clientWebSocket = new ClientWebSocket();
|
var clientWebSocket = new ClientWebSocket();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetupClientWebSocket(clientWebSocket);
|
||||||
|
|
||||||
|
await clientWebSocket.ConnectAsync(new Uri(uri), cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Prevent a memory leak when always creating new instance which will fail while connecting.
|
||||||
|
clientWebSocket.Dispose();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_webSocket = clientWebSocket;
|
||||||
|
IsSecureConnection = uri.StartsWith("wss://", StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DisconnectAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (_webSocket == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_webSocket.State == WebSocketState.Open || _webSocket.State == WebSocketState.Connecting)
|
||||||
|
{
|
||||||
|
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken).ConfigureAwait(false);
|
||||||
|
return response.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// The lock is required because the client will throw an exception if _SendAsync_ is
|
||||||
|
// called from multiple threads at the same time. But this issue only happens with several
|
||||||
|
// framework versions.
|
||||||
|
if (_sendLock == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
await _webSocket.SendAsync(new ArraySegment<byte>(buffer, offset, count), WebSocketMessageType.Binary, true, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupClientWebSocket(ClientWebSocket clientWebSocket)
|
||||||
|
{
|
||||||
|
|
||||||
if (_options.ProxyOptions != null)
|
if (_options.ProxyOptions != null)
|
||||||
{
|
{
|
||||||
@@ -90,68 +151,37 @@ namespace MQTTnet.Implementations
|
|||||||
#else
|
#else
|
||||||
clientWebSocket.Options.ClientCertificates.Add(certificate);
|
clientWebSocket.Options.ClientCertificates.Add(certificate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await clientWebSocket.ConnectAsync(new Uri(uri), cancellationToken).ConfigureAwait(false);
|
var certificateValidationHandler = _options.TlsOptions?.CertificateValidationHandler;
|
||||||
_webSocket = clientWebSocket;
|
#if NETSTANDARD2_1
|
||||||
|
if (certificateValidationHandler != null)
|
||||||
|
{
|
||||||
|
clientWebSocket.Options.RemoteCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback((sender, certificate, chain, sslPolicyErrors) =>
|
||||||
|
{
|
||||||
|
// TODO: Find a way to add client options to same callback. Problem is that they have a different type.
|
||||||
|
var context = new MqttClientCertificateValidationCallbackContext
|
||||||
|
{
|
||||||
|
Certificate = certificate,
|
||||||
|
Chain = chain,
|
||||||
|
SslPolicyErrors = sslPolicyErrors,
|
||||||
|
ClientOptions = _options
|
||||||
|
};
|
||||||
|
|
||||||
IsSecureConnection = uri.StartsWith("wss://", StringComparison.OrdinalIgnoreCase);
|
return certificateValidationHandler(context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (certificateValidationHandler != null)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("The remote certificate validation callback for Web Sockets is only supported for netstandard 2.1+");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DisconnectAsync(CancellationToken cancellationToken)
|
void Cleanup()
|
||||||
{
|
|
||||||
if (_webSocket == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_webSocket.State == WebSocketState.Open || _webSocket.State == WebSocketState.Connecting)
|
|
||||||
{
|
|
||||||
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken).ConfigureAwait(false);
|
|
||||||
return response.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// The lock is required because the client will throw an exception if _SendAsync_ is
|
|
||||||
// called from multiple threads at the same time. But this issue only happens with several
|
|
||||||
// framework versions.
|
|
||||||
if (_sendLock == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await _webSocket.SendAsync(new ArraySegment<byte>(buffer, offset, count), WebSocketMessageType.Binary, true, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_sendLock?.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
Cleanup();
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Cleanup()
|
|
||||||
{
|
{
|
||||||
_sendLock?.Dispose();
|
_sendLock?.Dispose();
|
||||||
_sendLock = null;
|
_sendLock = null;
|
||||||
@@ -169,7 +199,7 @@ namespace MQTTnet.Implementations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IWebProxy CreateProxy()
|
IWebProxy CreateProxy()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_options.ProxyOptions?.Address))
|
if (string.IsNullOrEmpty(_options.ProxyOptions?.Address))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace MQTTnet.Internal
|
namespace MQTTnet.Internal
|
||||||
{
|
{
|
||||||
public class BlockingQueue<TItem> : Disposable
|
public sealed class BlockingQueue<TItem> : IDisposable
|
||||||
{
|
{
|
||||||
private readonly object _syncRoot = new object();
|
readonly object _syncRoot = new object();
|
||||||
private readonly LinkedList<TItem> _items = new LinkedList<TItem>();
|
readonly LinkedList<TItem> _items = new LinkedList<TItem>();
|
||||||
private readonly ManualResetEventSlim _gate = new ManualResetEventSlim(false);
|
|
||||||
|
ManualResetEventSlim _gate = new ManualResetEventSlim(false);
|
||||||
|
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
@@ -28,13 +29,13 @@ namespace MQTTnet.Internal
|
|||||||
lock (_syncRoot)
|
lock (_syncRoot)
|
||||||
{
|
{
|
||||||
_items.AddLast(item);
|
_items.AddLast(item);
|
||||||
_gate.Set();
|
_gate?.Set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TItem Dequeue(CancellationToken cancellationToken = default(CancellationToken))
|
public TItem Dequeue(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
while (true)
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
lock (_syncRoot)
|
lock (_syncRoot)
|
||||||
{
|
{
|
||||||
@@ -48,17 +49,19 @@ namespace MQTTnet.Internal
|
|||||||
|
|
||||||
if (_items.Count == 0)
|
if (_items.Count == 0)
|
||||||
{
|
{
|
||||||
_gate.Reset();
|
_gate?.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gate.Wait(cancellationToken);
|
_gate?.Wait(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new OperationCanceledException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TItem PeekAndWait(CancellationToken cancellationToken = default(CancellationToken))
|
public TItem PeekAndWait(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
while (true)
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
lock (_syncRoot)
|
lock (_syncRoot)
|
||||||
{
|
{
|
||||||
@@ -69,12 +72,14 @@ namespace MQTTnet.Internal
|
|||||||
|
|
||||||
if (_items.Count == 0)
|
if (_items.Count == 0)
|
||||||
{
|
{
|
||||||
_gate.Reset();
|
_gate?.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gate.Wait(cancellationToken);
|
_gate?.Wait(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new OperationCanceledException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveFirst(Predicate<TItem> match)
|
public void RemoveFirst(Predicate<TItem> match)
|
||||||
@@ -109,13 +114,10 @@ namespace MQTTnet.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (disposing)
|
_gate?.Dispose();
|
||||||
{
|
_gate = null;
|
||||||
_gate.Dispose();
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netstandard1.3;netstandard2.0</TargetFrameworks>
|
<TargetFrameworks>netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||||
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net452;net461</TargetFrameworks>
|
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net452;net461</TargetFrameworks>
|
||||||
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' AND '$(MSBuildRuntimeType)' != 'Core' AND '$(SolutionName)' != 'MQTTnet.noUWP' ">$(TargetFrameworks);uap10.0</TargetFrameworks>
|
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' AND '$(MSBuildRuntimeType)' != 'Core' AND '$(SolutionName)' != 'MQTTnet.noUWP' ">$(TargetFrameworks);uap10.0</TargetFrameworks>
|
||||||
<AssemblyName>MQTTnet</AssemblyName>
|
<AssemblyName>MQTTnet</AssemblyName>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using System.Threading;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using MQTTnet.Internal;
|
using MQTTnet.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MQTTnet.Tests
|
namespace MQTTnet.Tests
|
||||||
{
|
{
|
||||||
@@ -33,7 +34,7 @@ namespace MQTTnet.Tests
|
|||||||
|
|
||||||
Assert.AreEqual("a", queue.RemoveFirst());
|
Assert.AreEqual("a", queue.RemoveFirst());
|
||||||
Assert.AreEqual("b", queue.RemoveFirst());
|
Assert.AreEqual("b", queue.RemoveFirst());
|
||||||
|
|
||||||
Assert.AreEqual(1, queue.Count);
|
Assert.AreEqual(1, queue.Count);
|
||||||
|
|
||||||
Assert.AreEqual("c", queue.Dequeue());
|
Assert.AreEqual("c", queue.Dequeue());
|
||||||
@@ -81,7 +82,7 @@ namespace MQTTnet.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Wait_For_Times()
|
public void Wait_For_Items()
|
||||||
{
|
{
|
||||||
var number = 0;
|
var number = 0;
|
||||||
|
|
||||||
@@ -104,5 +105,21 @@ namespace MQTTnet.Tests
|
|||||||
Interlocked.Increment(ref number);
|
Interlocked.Increment(ref number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(OperationCanceledException))]
|
||||||
|
public void Use_Disposed_Queue()
|
||||||
|
{
|
||||||
|
var queue = new BlockingQueue<int>();
|
||||||
|
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
queue.Dispose();
|
||||||
|
});
|
||||||
|
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||||
|
|
||||||
|
queue.Dequeue(new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,18 @@ namespace MQTTnet.Tests
|
|||||||
{
|
{
|
||||||
public TestContext TestContext { get; set; }
|
public TestContext TestContext { get; set; }
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task Send_Manual_Ping()
|
||||||
|
{
|
||||||
|
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||||
|
{
|
||||||
|
await testEnvironment.StartServerAsync();
|
||||||
|
var client = await testEnvironment.ConnectClientAsync();
|
||||||
|
|
||||||
|
await client.PingAsync(CancellationToken.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task Send_Reply_In_Message_Handler_For_Same_Client()
|
public async Task Send_Reply_In_Message_Handler_For_Same_Client()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
using System;
|
using MQTTnet.Client.Options;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net.Security;
|
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MQTTnet.Client;
|
|
||||||
using MQTTnet.Client.Options;
|
|
||||||
using MQTTnet.Diagnostics;
|
using MQTTnet.Diagnostics;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MQTTnet.TestApp.NetCore
|
namespace MQTTnet.TestApp.NetCore
|
||||||
{
|
{
|
||||||
@@ -129,10 +127,15 @@ namespace MQTTnet.TestApp.NetCore
|
|||||||
var options = new MqttClientOptionsBuilder()
|
var options = new MqttClientOptionsBuilder()
|
||||||
.WithTls(new MqttClientOptionsBuilderTlsParameters
|
.WithTls(new MqttClientOptionsBuilderTlsParameters
|
||||||
{
|
{
|
||||||
CertificateValidationCallback = (X509Certificate x, X509Chain y, SslPolicyErrors z, IMqttClientOptions o) =>
|
CertificateValidationHandler = context =>
|
||||||
{
|
{
|
||||||
// TODO: Check conditions of certificate by using above parameters.
|
// TODO: Check conditions of certificate by using above context.
|
||||||
return true;
|
if (context.SslPolicyErrors == SslPolicyErrors.None)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
|||||||
Reference in New Issue
Block a user