diff --git a/ReactiveXComponent/Configuration/BusDetails.cs b/ReactiveXComponent/Configuration/BusDetails.cs
index a4c5ca4..6613c37 100644
--- a/ReactiveXComponent/Configuration/BusDetails.cs
+++ b/ReactiveXComponent/Configuration/BusDetails.cs
@@ -1,4 +1,6 @@
+using System.Security.Authentication;
+
namespace ReactiveXComponent.Configuration
{
public class BusDetails
@@ -8,26 +10,87 @@ public BusDetails()
}
- public BusDetails(string username, string password, string host, string virtualHost, int port)
+ public BusDetails(
+ string username,
+ string password,
+ string host,
+ string virtualHost,
+ int port,
+ bool sslEnabled = false,
+ string sslServerName = "",
+ string sslCertificatePath = "",
+ string sslCertificatePassphrase = "",
+ SslProtocols sslProtocol = SslProtocols.Default,
+ bool sslAllowUntrustedServerCertificate = false)
{
Username = username;
Password = password;
Host = host;
VirtualHost = virtualHost;
Port = port;
-
+ SslEnabled = sslEnabled;
+ SslServerName = sslServerName;
+ SslCertificatePath = sslCertificatePath;
+ SslCertificatePassphrase = sslCertificatePassphrase;
+ SslProtocol = sslProtocol;
+ SslAllowUntrustedServerCertificate = sslAllowUntrustedServerCertificate;
}
+ ///
+ /// Rabbit Mq user.
+ ///
public string Username { get; set; }
+ ///
+ /// Rabbit Mq password for user.
+ ///
public string Password { get; set; }
+ ///
+ /// Rabbit Mq server's address.
+ ///
public string Host { get; set; }
+ ///
+ /// Rabbit Mq virtual host to connect to.
+ ///
public string VirtualHost { get; set; }
+ ///
+ /// Rabbit Mq server's port.
+ ///
public int Port { get; set; }
+ ///
+ /// To enable SSL.
+ ///
+ public bool SslEnabled { get; set; }
+
+ ///
+ /// Server's Common Name. It's indicated in the CN field of the server's certificate.
+ ///
+ public string SslServerName { get; set; }
+
+ ///
+ /// Path to the client's certificate.
+ ///
+ public string SslCertificatePath { get; set; }
+
+ ///
+ /// Passphrase for the client's certificate if it has one.
+ ///
+ public string SslCertificatePassphrase { get; set; }
+
+ ///
+ /// SSL protocol to use.
+ ///
+ public SslProtocols SslProtocol { get; set; }
+
+ ///
+ /// To accept untrusted (e.g self-signed) server certificates. Only use this in Dev environment.
+ ///
+ public bool SslAllowUntrustedServerCertificate { get; set; }
+
public BusDetails Clone()
{
return new BusDetails(
@@ -35,7 +98,13 @@ public BusDetails Clone()
Password,
Host,
VirtualHost,
- Port);
+ Port,
+ SslEnabled,
+ SslServerName,
+ SslCertificatePath,
+ SslCertificatePassphrase,
+ SslProtocol,
+ SslAllowUntrustedServerCertificate);
}
}
}
diff --git a/ReactiveXComponent/Configuration/ConfigurationOverrides.cs b/ReactiveXComponent/Configuration/ConfigurationOverrides.cs
index 33782ab..490449e 100644
--- a/ReactiveXComponent/Configuration/ConfigurationOverrides.cs
+++ b/ReactiveXComponent/Configuration/ConfigurationOverrides.cs
@@ -1,4 +1,5 @@
-using ReactiveXComponent.Common;
+using System.Security.Authentication;
+using ReactiveXComponent.Common;
namespace ReactiveXComponent.Configuration
{
@@ -15,5 +16,17 @@ public class ConfigurationOverrides
public string Password { get; set; }
public WebSocketType? WebSocketType { get; set; }
+
+ public bool? SslEnabled { get; set; }
+
+ public string SslServerName { get; set; }
+
+ public string SslCertificatePath { get; set; }
+
+ public string SslCertificatePassphrase { get; set; }
+
+ public SslProtocols? SslProtocol { get; set; }
+
+ public bool? SslAllowUntrustedServerCertificate { get; set; }
}
}
diff --git a/ReactiveXComponent/Configuration/XCApiTags.cs b/ReactiveXComponent/Configuration/XCApiTags.cs
index de89362..6732682 100644
--- a/ReactiveXComponent/Configuration/XCApiTags.cs
+++ b/ReactiveXComponent/Configuration/XCApiTags.cs
@@ -29,5 +29,13 @@ public static class XCApiTags
public const string Json = "Json";
public const string Bson = "Bson";
public const string GzipJson = "GzipJson";
+ public const string WebsocketType = "type";
+ public const string VirtualHost = "virtualHost";
+ public const string BusSslEnabled = "sslEnabled";
+ public const string BusSslServerName = "sslServerName";
+ public const string BusSslCertificatePath = "sslCertPath";
+ public const string BusSslCertificatePassphrase = "sslCertPassphrase";
+ public const string BusSslProtocol = "sslProtocol";
+ public const string BusSslAllowUntrustedServerCertificate = "sslAllowUntrustedServerCertificate";
}
}
diff --git a/ReactiveXComponent/Parser/XCApiConfigParser.cs b/ReactiveXComponent/Parser/XCApiConfigParser.cs
index 2059f76..fb53d3f 100644
--- a/ReactiveXComponent/Parser/XCApiConfigParser.cs
+++ b/ReactiveXComponent/Parser/XCApiConfigParser.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Security.Authentication;
using System.Xml;
using System.Xml.Linq;
using ReactiveXComponent.Common;
@@ -182,12 +183,44 @@ public string GetSerializationType()
public BusDetails GetBusDetails()
{
XElement busInfos = _xcApiDescription.GetBusNode()?.FirstOrDefault();
+
+ var sslEnabledString = busInfos?.Attribute(XCApiTags.BusSslEnabled)?.Value;
+ var sslEnabled = false;
+ if (!string.IsNullOrEmpty(sslEnabledString))
+ {
+ bool.TryParse(sslEnabledString, out sslEnabled);
+ }
+
+ var sslServerName = busInfos?.Attribute(XCApiTags.BusSslServerName)?.Value;
+ var sslCertificatePath = busInfos?.Attribute(XCApiTags.BusSslCertificatePath)?.Value;
+ var sslCertificatePassphrase = busInfos?.Attribute(XCApiTags.BusSslCertificatePassphrase)?.Value;
+
+ var sslProtocolString = busInfos?.Attribute(XCApiTags.BusSslProtocol)?.Value;
+ SslProtocols sslProtocol = SslProtocols.Default;
+ if (!string.IsNullOrEmpty(sslProtocolString))
+ {
+ Enum.TryParse(sslProtocolString, out sslProtocol);
+ }
+
+ var sslAllowUntrustedServerCertificateString = busInfos?.Attribute(XCApiTags.BusSslAllowUntrustedServerCertificate)?.Value;
+ var sslAllowUntrustedServerCertificate = false;
+ if (!string.IsNullOrEmpty(sslAllowUntrustedServerCertificateString))
+ {
+ bool.TryParse(sslAllowUntrustedServerCertificateString, out sslAllowUntrustedServerCertificate);
+ }
+
var busDetails = new BusDetails(
- busInfos?.Attribute("user")?.Value,
- busInfos?.Attribute("password")?.Value,
- busInfos?.Attribute("host")?.Value,
- busInfos?.Attribute("virtualHost")?.Value,
- Convert.ToInt32(busInfos?.Attribute("port")?.Value));
+ busInfos?.Attribute(XCApiTags.User)?.Value,
+ busInfos?.Attribute(XCApiTags.Password)?.Value,
+ busInfos?.Attribute(XCApiTags.Host)?.Value,
+ busInfos?.Attribute(XCApiTags.VirtualHost)?.Value,
+ Convert.ToInt32(busInfos?.Attribute(XCApiTags.Port)?.Value),
+ sslEnabled,
+ sslServerName,
+ sslCertificatePath,
+ sslCertificatePassphrase,
+ sslProtocol,
+ sslAllowUntrustedServerCertificate);
return busDetails;
}
@@ -197,16 +230,16 @@ public WebSocketEndpoint GetWebSocketEndpoint()
XElement websocketInfos = _xcApiDescription.GetWebSocketNode()?.FirstOrDefault();
WebSocketType webSocketType;
- var webSocketTypeString = websocketInfos?.Attribute("type")?.Value;
+ var webSocketTypeString = websocketInfos?.Attribute(XCApiTags.WebsocketType)?.Value;
if (!Enum.TryParse(webSocketTypeString, out webSocketType))
{
throw new ReactiveXComponentException($"Could not parse communication type: {webSocketTypeString}");
}
var webSocketEndpoint = new WebSocketEndpoint(
- websocketInfos?.Attribute("name")?.Value,
- websocketInfos?.Attribute("host")?.Value,
- websocketInfos?.Attribute("port")?.Value,
+ websocketInfos?.Attribute(XCApiTags.Name)?.Value,
+ websocketInfos?.Attribute(XCApiTags.Host)?.Value,
+ websocketInfos?.Attribute(XCApiTags.Port)?.Value,
webSocketType);
return webSocketEndpoint;
diff --git a/ReactiveXComponent/RabbitMq/RabbitMqConnection.cs b/ReactiveXComponent/RabbitMq/RabbitMqConnection.cs
index a3db190..b6ba99a 100644
--- a/ReactiveXComponent/RabbitMq/RabbitMqConnection.cs
+++ b/ReactiveXComponent/RabbitMq/RabbitMqConnection.cs
@@ -50,6 +50,36 @@ public IXCSession CreateSession(ConfigurationOverrides configurationOverrides =
busDetails.Password = configurationOverrides.Password;
}
+ if (configurationOverrides.SslEnabled != null)
+ {
+ busDetails.SslEnabled = configurationOverrides.SslEnabled.Value;
+ }
+
+ if (configurationOverrides.SslServerName != null)
+ {
+ busDetails.SslServerName = configurationOverrides.SslServerName;
+ }
+
+ if (configurationOverrides.SslCertificatePath != null)
+ {
+ busDetails.SslCertificatePath = configurationOverrides.SslCertificatePath;
+ }
+
+ if (configurationOverrides.SslCertificatePassphrase != null)
+ {
+ busDetails.SslCertificatePassphrase = configurationOverrides.SslCertificatePassphrase;
+ }
+
+ if (configurationOverrides.SslProtocol != null)
+ {
+ busDetails.SslProtocol = configurationOverrides.SslProtocol.Value;
+ }
+
+ if (configurationOverrides.SslAllowUntrustedServerCertificate != null)
+ {
+ busDetails.SslAllowUntrustedServerCertificate = configurationOverrides.SslAllowUntrustedServerCertificate.Value;
+ }
+
return new RabbitMqSession(_xcConfiguration, busDetails, _privateCommunicationIdentifier);
}
}
diff --git a/ReactiveXComponent/RabbitMq/RabbitMqSession.cs b/ReactiveXComponent/RabbitMq/RabbitMqSession.cs
index 7805ead..e8dce11 100644
--- a/ReactiveXComponent/RabbitMq/RabbitMqSession.cs
+++ b/ReactiveXComponent/RabbitMq/RabbitMqSession.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Net.Security;
using RabbitMQ.Client;
using RabbitMQ.Client.Exceptions;
using ReactiveXComponent.Common;
@@ -39,6 +40,39 @@ private void InitConnection(BusDetails busDetails)
Protocol = Protocols.DefaultProtocol
};
+ if (busDetails.SslEnabled)
+ {
+ _factory.Ssl.Enabled = true;
+
+ _factory.Ssl.ServerName = busDetails.SslServerName;
+
+ if (!string.IsNullOrEmpty(busDetails.SslCertificatePath))
+ {
+ _factory.Ssl.CertPath = busDetails.SslCertificatePath;
+ }
+
+ if (!string.IsNullOrEmpty(busDetails.SslCertificatePassphrase))
+ {
+ _factory.Ssl.CertPassphrase = busDetails.SslCertificatePassphrase;
+ }
+
+ _factory.Ssl.Version = busDetails.SslProtocol;
+
+ if (busDetails.SslAllowUntrustedServerCertificate)
+ {
+ _factory.Ssl.CertificateValidationCallback += (sender, certificate, chain, errors) =>
+ {
+ if ((errors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch ||
+ (errors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
+ {
+ return false;
+ }
+
+ return true;
+ };
+ }
+ }
+
_connection = _factory?.CreateConnection();
_connection.ConnectionShutdown += ConnectionOnConnectionShutdown;
diff --git a/ReactiveXComponentTest/Configuration/ConfigurationTests.cs b/ReactiveXComponentTest/Configuration/ConfigurationTests.cs
index 1ce9830..7f10ad4 100644
--- a/ReactiveXComponentTest/Configuration/ConfigurationTests.cs
+++ b/ReactiveXComponentTest/Configuration/ConfigurationTests.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Security.Authentication;
using NFluent;
using NUnit.Framework;
using ReactiveXComponent.Common;
@@ -77,7 +78,13 @@ public void GetBusDetailsTest()
Check.That(busDetails.VirtualHost).IsEqualTo("myVirtualHost");
Check.That(busDetails.Username).IsEqualTo("guest");
Check.That(busDetails.Password).IsEqualTo("guest");
- Check.That(busDetails.Port).IsEqualTo(5672);
+ Check.That(busDetails.Port).IsEqualTo(5671);
+ Check.That(busDetails.SslEnabled).IsTrue();
+ Check.That(busDetails.SslServerName).IsEqualTo("XComponent RMq");
+ Check.That(busDetails.SslCertificatePath).IsEqualTo("some_cert_path");
+ Check.That(busDetails.SslCertificatePassphrase).IsEqualTo("some_cert_pass");
+ Check.That(busDetails.SslProtocol).IsEqualTo(SslProtocols.Default);
+ Check.That(busDetails.SslAllowUntrustedServerCertificate).IsTrue();
}
[Test]
diff --git a/ReactiveXComponentTest/RabbitMqTestApi.xcApi b/ReactiveXComponentTest/RabbitMqTestApi.xcApi
index c95c6d9..cf273da 100644
--- a/ReactiveXComponentTest/RabbitMqTestApi.xcApi
+++ b/ReactiveXComponentTest/RabbitMqTestApi.xcApi
@@ -3,7 +3,7 @@
Binary
-
+