Skip to content

Commit

Permalink
update(M2MQTT): update to the current version of M2MQTT on GitHub
Browse files Browse the repository at this point in the history
Manually merged the current version of M2MQTT on GitHub.

Some reformatting in M2MqttUnityClient.

Tested on Windows Standalone, Android (also GearVR), Unity Editor,
UWP (desktop and HoloLens).

While no problem was found using a not encrypted connection,
I tested the example also with SLL, using Unity 2017.1.4 and
SSL does not work on Windows Standalone, Android, Unity Editor, but
SSL works on UWP (desktop and HoloLens).
  • Loading branch information
gpvigano committed Jul 26, 2018
1 parent 0d02645 commit cc4e432
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 78 deletions.
102 changes: 55 additions & 47 deletions Assets/M2Mqtt/MqttClient.cs

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions Assets/M2Mqtt/MqttSecurity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Copyright (c) 2013, 2014 Paolo Patierno
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/

namespace uPLibrary.Networking.M2Mqtt
{
/// <summary>
/// Supported SSL/TLS protocol versions
/// </summary>
public enum MqttSslProtocols
{
None,
SSLv3,
TLSv1_0,
TLSv1_1,
TLSv1_2
}
}
12 changes: 12 additions & 0 deletions Assets/M2Mqtt/MqttSecurity.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Assets/M2Mqtt/Net/Fx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Giovanni Paolo Vigano' - preprocessor directives for platform dependent compilation in Unity
*/

#if !((!UNITY_EDITOR&&UNITY_WSA_10_0&&!ENABLE_IL2CPP))
#if !(!UNITY_EDITOR&&UNITY_WSA_10_0&&!ENABLE_IL2CPP)
using System.Threading;

namespace uPLibrary.Networking.M2Mqtt
Expand Down
4 changes: 2 additions & 2 deletions Assets/M2Mqtt/Net/Fx.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

163 changes: 149 additions & 14 deletions Assets/M2Mqtt/Net/MqttNetworkChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
----------------------------------------------------------------------------
Giovanni Paolo Vigano' - preprocessor directives for platform dependent compilation in Unity
*/
#if !(!UNITY_EDITOR&&UNITY_WSA_10_0&&!ENABLE_IL2CPP)

#if !((!UNITY_EDITOR&&UNITY_WSA_10_0&&!ENABLE_IL2CPP))
#if SSL
#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
using Microsoft.SPOT.Net.Security;
Expand All @@ -27,7 +30,6 @@
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System;
using System.Net.Security;

namespace uPLibrary.Networking.M2Mqtt
{
Expand All @@ -50,8 +52,15 @@ public class MqttNetworkChannel : IMqttNetworkChannel
// using SSL
private bool secure;

// CA certificate
// CA certificate (on client)
private X509Certificate caCert;
// Server certificate (on broker)
private X509Certificate serverCert;
// client certificate (on client)
private X509Certificate clientCert;

// SSL/TLS protocol version
private MqttSslProtocols sslProtocol;

/// <summary>
/// Remote host name
Expand Down Expand Up @@ -106,8 +115,40 @@ public bool DataAvailable
/// </summary>
/// <param name="socket">Socket opened with the client</param>
public MqttNetworkChannel(Socket socket)
#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
: this(socket, false, null, MqttSslProtocols.None, null, null)
#else
: this(socket, false, null, MqttSslProtocols.None)
#endif
{

}

/// <summary>
/// Constructor
/// </summary>
/// <param name="socket">Socket opened with the client</param>
/// <param name="secure">Secure connection (SSL/TLS)</param>
/// <param name="serverCert">Server X509 certificate for secure connection</param>
/// <param name="sslProtocol">SSL/TLS protocol version</param>
#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
/// <param name="userCertificateSelectionCallback">A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party</param>
/// <param name="userCertificateValidationCallback">A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication</param>
public MqttNetworkChannel(Socket socket, bool secure, X509Certificate serverCert, MqttSslProtocols sslProtocol,
RemoteCertificateValidationCallback userCertificateValidationCallback,
LocalCertificateSelectionCallback userCertificateSelectionCallback)
#else
public MqttNetworkChannel(Socket socket, bool secure, X509Certificate serverCert, MqttSslProtocols sslProtocol)
#endif
{
this.socket = socket;
this.secure = secure;
this.serverCert = serverCert;
this.sslProtocol = sslProtocol;
#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
this.userCertificateValidationCallback = userCertificateValidationCallback;
this.userCertificateSelectionCallback = userCertificateSelectionCallback;
#endif
}

/// <summary>
Expand All @@ -117,9 +158,9 @@ public MqttNetworkChannel(Socket socket)
/// <param name="remotePort">Remote port</param>
public MqttNetworkChannel(string remoteHostName, int remotePort)
#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
: this(remoteHostName, remotePort, false, null, null, null)
: this(remoteHostName, remotePort, false, null, null, MqttSslProtocols.None, null, null)
#else
: this(remoteHostName, remotePort, false, null)
: this(remoteHostName, remotePort, false, null, null, MqttSslProtocols.None)
#endif
{
}
Expand All @@ -131,14 +172,16 @@ public MqttNetworkChannel(string remoteHostName, int remotePort)
/// <param name="remotePort">Remote port</param>
/// <param name="secure">Using SSL</param>
/// <param name="caCert">CA certificate</param>
/// <param name="clientCert">Client certificate</param>
/// <param name="sslProtocol">SSL/TLS protocol version</param>
#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
/// <param name="userCertificateSelectionCallback">A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party</param>
/// <param name="userCertificateValidationCallback">A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication</param>
public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert,
public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol,
RemoteCertificateValidationCallback userCertificateValidationCallback,
LocalCertificateSelectionCallback userCertificateSelectionCallback)
#else
public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert)
public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol)
#endif
{
IPAddress remoteIpAddress = null;
Expand Down Expand Up @@ -174,6 +217,8 @@ public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X5
this.remotePort = remotePort;
this.secure = secure;
this.caCert = caCert;
this.clientCert = clientCert;
this.sslProtocol = sslProtocol;
#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
this.userCertificateValidationCallback = userCertificateValidationCallback;
this.userCertificateSelectionCallback = userCertificateSelectionCallback;
Expand Down Expand Up @@ -204,16 +249,20 @@ public void Connect()
// server authentication (SSL/TLS handshake)
#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
this.sslStream.AuthenticateAsClient(this.remoteHostName,
null,
this.clientCert,
new X509Certificate[] { this.caCert },
SslVerification.CertificateRequired,
SslProtocols.TLSv1);
MqttSslUtility.ToSslPlatformEnum(this.sslProtocol));
#else
this.sslStream.AuthenticateAsClient(
this.remoteHostName,
null,
SslProtocols.Tls,
false);
X509CertificateCollection clientCertificates = null;
// check if there is a client certificate to add to the collection, otherwise it's null (as empty)
if (this.clientCert != null)
clientCertificates = new X509CertificateCollection(new X509Certificate[] { this.clientCert });

this.sslStream.AuthenticateAsClient(this.remoteHostName,
clientCertificates,
MqttSslUtility.ToSslPlatformEnum(this.sslProtocol),
false);

#endif
}
Expand Down Expand Up @@ -330,6 +379,30 @@ public void Close()
this.socket.Close();
#else
this.socket.Close();
#endif
}

/// <summary>
/// Accept connection from a remote client
/// </summary>
public void Accept()
{
#if SSL
// secure channel requested
if (secure)
{
#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)

this.netStream = new NetworkStream(this.socket);
this.sslStream = new SslStream(this.netStream, false, this.userCertificateValidationCallback, this.userCertificateSelectionCallback);

this.sslStream.AuthenticateAsServer(this.serverCert, false, MqttSslUtility.ToSslPlatformEnum(this.sslProtocol), false);
#endif
}

return;
#else
return;
#endif
}
}
Expand All @@ -354,5 +427,67 @@ public static AddressFamily GetAddressFamily(this IPAddress ipAddress)
#endif
}
}

/// <summary>
/// MQTT SSL utility class
/// </summary>
public static class MqttSslUtility
{
#if (UNITY_EDITOR || !NET_4_6)
public static SslProtocols ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol)
{
switch (mqttSslProtocol)
{
case MqttSslProtocols.None:
return SslProtocols.None;
case MqttSslProtocols.SSLv3:
return SslProtocols.Ssl3;
case MqttSslProtocols.TLSv1_0:
return SslProtocols.Tls;
case MqttSslProtocols.TLSv1_1:
case MqttSslProtocols.TLSv1_2:
default:
throw new ArgumentException("SSL/TLS protocol version not supported");
}
}
#elif (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3 && !COMPACT_FRAMEWORK)
public static SslProtocols ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol)
{
switch (mqttSslProtocol)
{
case MqttSslProtocols.None:
return SslProtocols.None;
case MqttSslProtocols.SSLv3:
return SslProtocols.Ssl3;
case MqttSslProtocols.TLSv1_0:
return SslProtocols.Tls;
case MqttSslProtocols.TLSv1_1:
return SslProtocols.Tls11;
case MqttSslProtocols.TLSv1_2:
return SslProtocols.Tls12;
default:
throw new ArgumentException("SSL/TLS protocol version not supported");
}
}
#elif (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
public static SslProtocols ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol)
{
switch (mqttSslProtocol)
{
case MqttSslProtocols.None:
return SslProtocols.None;
case MqttSslProtocols.SSLv3:
return SslProtocols.SSLv3;
case MqttSslProtocols.TLSv1_0:
return SslProtocols.TLSv1;
case MqttSslProtocols.TLSv1_1:
case MqttSslProtocols.TLSv1_2:
default:
throw new ArgumentException("SSL/TLS protocol version not supported");
}
}
#endif
}
}

#endif
4 changes: 2 additions & 2 deletions Assets/M2Mqtt/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("4.1.0.0")]
[assembly: AssemblyVersion("4.3.0.0")]
// to avoid compilation error (AssemblyFileVersionAttribute doesn't exist) under .Net CF 3.5
#if !WindowsCE
[assembly: AssemblyFileVersion("4.1.0.0")]
[assembly: AssemblyFileVersion("4.3.0.0")]
#endif
45 changes: 42 additions & 3 deletions Assets/M2Mqtt/WinRT/MqttNetworkChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,17 @@ public class MqttNetworkChannel : IMqttNetworkChannel
// using SSL
private bool secure;

// SSL/TLS protocol version
private MqttSslProtocols sslProtocol;

/// <summary>
/// Constructor
/// </summary>
/// <param name="socket">Socket opened with the client</param>
public MqttNetworkChannel(StreamSocket socket)
{
this.socket = socket;
this.sslProtocol = MqttSslProtocols.None;
}

/// <summary>
Expand All @@ -58,11 +62,16 @@ public MqttNetworkChannel(StreamSocket socket)
/// <param name="remoteHostName">Remote Host name</param>
/// <param name="remotePort">Remote port</param>
/// <param name="secure">Using SSL</param>
public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure)
/// <param name="sslProtocol">SSL/TLS protocol version</param>
public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, MqttSslProtocols sslProtocol)
{
this.remoteHostName = new HostName(remoteHostName);
this.remotePort = remotePort;
this.secure = secure;
this.sslProtocol = sslProtocol;

if (secure && (sslProtocol == MqttSslProtocols.None))
throw new ArgumentException("For secure connection, an SSL/TLS protocol version is needed");
}

public bool DataAvailable
Expand Down Expand Up @@ -137,10 +146,40 @@ public void Connect()
// connection is executed synchronously
this.socket.ConnectAsync(this.remoteHostName,
this.remotePort.ToString(),
this.secure ? SocketProtectionLevel.Tls12 : SocketProtectionLevel.PlainSocket).AsTask().Wait();
MqttSslUtility.ToSslPlatformEnum(this.sslProtocol)).AsTask().Wait();
}

public void Accept()
{
// TODO : SSL support with StreamSocket / StreamSocketListener seems to be NOT supported
return;
}
}


/// <summary>
/// MQTT SSL utility class
/// </summary>
public static class MqttSslUtility
{
public static SocketProtectionLevel ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol)
{
switch (mqttSslProtocol)
{
case MqttSslProtocols.None:
return SocketProtectionLevel.PlainSocket;
case MqttSslProtocols.SSLv3:
return SocketProtectionLevel.SslAllowNullEncryption;
case MqttSslProtocols.TLSv1_0:
return SocketProtectionLevel.Tls10;
case MqttSslProtocols.TLSv1_1:
return SocketProtectionLevel.Tls11;
case MqttSslProtocols.TLSv1_2:
return SocketProtectionLevel.Tls12;
default:
throw new ArgumentException("SSL/TLS protocol version not supported");
}
}
}
}

#endif
Loading

0 comments on commit cc4e432

Please sign in to comment.