Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dotnet/Razorvine.Pyrolite/Pyrolite/Pyro/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ public static class Config {
public static int NS_PORT = 9090;
public static int NS_BCPORT = 9091;
public static bool SERPENT_INDENT = false;
public static bool SSL = false;
public static string SSL_CACERTS = "";
public static string SSL_CLIENTCERT = ""; // only clientcert option because it needs to be in pkcs12 format which integrates the key. PEM files are not supported!
public static string SSL_CLIENTCERTPASSWD = "";

public const int PROTOCOL_VERSION = 502; // Pyro5
public const string PYROLITE_VERSION="5.0";
Expand Down
53 changes: 50 additions & 3 deletions dotnet/Razorvine.Pyrolite/Pyrolite/Pyro/PyroProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Razorvine.Pyro.Serializer;

Expand Down Expand Up @@ -37,7 +39,7 @@ public class PyroProxy : DynamicObject, IDisposable {

private ushort sequenceNr;
private TcpClient sock;
private NetworkStream sock_stream;
private Stream sock_stream;

public ISet<string> pyroMethods = new HashSet<string>(); // remote methods
public ISet<string> pyroAttrs = new HashSet<string>(); // remote attributes
Expand Down Expand Up @@ -83,7 +85,23 @@ protected void connect() {
sock = new TcpClient();
sock.Connect(hostname,port);
sock.NoDelay=true;
sock_stream=sock.GetStream();

if (Config.SSL)
{
var sslStream = new SslStream(sock.GetStream(), true, ValidateServerCertificate);
if (File.Exists(Config.SSL_CLIENTCERT))
{
var clientCert = new X509CertificateCollection();
clientCert.Add(new X509Certificate(Config.SSL_CLIENTCERT, Config.SSL_CLIENTCERTPASSWD));
sslStream.AuthenticateAsClient(hostname, clientCert, System.Security.Authentication.SslProtocols.Default, false);
} else {
sslStream.AuthenticateAsClient(hostname);
}
sock_stream = sslStream;
} else {
sock_stream = sock.GetStream();
}

sequenceNr = 0;
_handshake();

Expand All @@ -97,6 +115,35 @@ protected void connect() {
}
}

/// <summary>
/// custom certificate validator to trust self signed CAs
/// </summary>
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
X509Certificate2Collection trustedCaCollection = new X509Certificate2Collection();

if (File.Exists(Config.SSL_CACERTS)) {
X509Certificate2 authority = new X509Certificate2(Config.SSL_CACERTS);
trustedCaCollection.Add(authority);
} else if (Directory.Exists(Config.SSL_CACERTS) && Directory.GetFiles(Config.SSL_CACERTS).Length > 0) {
foreach (var file in Directory.GetFiles(Config.SSL_CACERTS))
{
X509Certificate2 authority = new X509Certificate2(Config.SSL_CACERTS);
trustedCaCollection.Add(authority);
}
}

if (chain.ChainStatus.Any(status => status.Status != X509ChainStatusFlags.UntrustedRoot))
return false;

foreach (var element in chain.ChainElements)
{
if (element.ChainElementStatus.Any(status => status.Status == X509ChainStatusFlags.UntrustedRoot) && !trustedCaCollection.Contains(element.Certificate))
return false;
}

return true;
}

/// <summary>
/// get metadata from server (methods, attrs, oneway, ...) and remember them in some attributes of the proxy
/// </summary>
Expand Down Expand Up @@ -182,7 +229,7 @@ public override bool TrySetMember(SetMemberBinder binder, object value)
return true;
}


/// <summary>
/// Call a method on the remote Pyro object this proxy is for.
/// </summary>
Expand Down