You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2010/02/25 22:05:05 UTC
svn commit: r916457 - in
/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport:
Tcp/SslTransport.cs Tcp/SslTransportFactory.cs Tcp/TcpTransport.cs
Tcp/TcpTransportFactory.cs TransportFactory.cs
Author: tabish
Date: Thu Feb 25 21:05:04 2010
New Revision: 916457
URL: http://svn.apache.org/viewvc?rev=916457&view=rev
Log:
https://issues.apache.org/activemq/browse/AMQNET-239
Adds a basic SslTransport to NMS.ActiveMQ.
Doesn't force the broker Certificate to be valid currently.
Doesn't do anything with client certificates so if the broker is set to require a client certificate it might fail.
Added:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs (with props)
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs (with props)
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/TransportFactory.cs
Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs?rev=916457&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs Thu Feb 25 21:05:04 2010
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Net.Security;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Apache.NMS.ActiveMQ.Transport.Tcp
+{
+ public class SslTransport : TcpTransport
+ {
+ private string brokerCertLocation;
+ private string brokerCertPassword;
+ private string clientCertLocation;
+ private string clientCertPassword;
+ private SslStream sslStream;
+
+ public SslTransport(Uri location, Socket socket, IWireFormat wireFormat) :
+ base(location, socket, wireFormat)
+ {
+ }
+
+ ~SslTransport()
+ {
+ Dispose(false);
+ }
+
+ public string BrokerCertLocation
+ {
+ get { return this.brokerCertLocation; }
+ set { this.brokerCertLocation = value; }
+ }
+
+ public string BrokerCertPassword
+ {
+ get { return this.brokerCertPassword; }
+ set { this.brokerCertPassword = value; }
+ }
+
+ public string ClientCertLocation
+ {
+ get { return this.clientCertLocation; }
+ set { this.clientCertLocation = value; }
+ }
+
+ public string ClientCertPassword
+ {
+ get { return this.clientCertPassword; }
+ set { this.clientCertPassword = value; }
+ }
+
+ protected override Stream CreateSocketStream()
+ {
+ if(this.sslStream != null)
+ {
+ return this.sslStream;
+ }
+
+ this.sslStream = new SslStream(
+ new NetworkStream(this.socket),
+ false,
+ new RemoteCertificateValidationCallback(ValidateServerCertificate));
+
+ try
+ {
+ Tracer.Debug("Authorizing as Client for Server: " + this.RemoteAddress.Host);
+ sslStream.AuthenticateAsClient(this.RemoteAddress.Host);
+ Tracer.Debug("Server is Authenticated = " + sslStream.IsAuthenticated);
+ Tracer.Debug("Server is Encrypted = " + sslStream.IsEncrypted);
+ }
+ catch(Exception e)
+ {
+ Tracer.ErrorFormat("Exception: {0}", e.Message);
+ if(e.InnerException != null)
+ {
+ Tracer.ErrorFormat("Inner exception: {0}", e.InnerException.Message);
+ }
+ Tracer.Error("Authentication failed - closing the connection.");
+
+ throw e;
+ }
+
+ return sslStream;
+ }
+
+ private static bool ValidateServerCertificate(object sender,
+ X509Certificate certificate,
+ X509Chain chain,
+ SslPolicyErrors sslPolicyErrors)
+ {
+ Tracer.DebugFormat("ValidateServerCertificate: Issued By {0}", certificate.Issuer);
+ if(sslPolicyErrors == SslPolicyErrors.None)
+ {
+ return true;
+ }
+
+ Tracer.WarnFormat("Certificate error: {0}", sslPolicyErrors.ToString());
+ if(sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
+ {
+ Tracer.Error("Chain Status errors: ");
+ foreach( X509ChainStatus status in chain.ChainStatus )
+ {
+ Tracer.Error("*** Chain Status error: " + status.Status);
+ Tracer.Error("*** Chain Status information: " + status.StatusInformation);
+ }
+ }
+ else if(sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch)
+ {
+ Tracer.Error("Mismatch between Remote Cert Name.");
+ }
+
+ // Just ignore any cert errors for now.
+ return true;
+ }
+ }
+}
Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs
------------------------------------------------------------------------------
svn:eol-style = native
Added: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs?rev=916457&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs (added)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs Thu Feb 25 21:05:04 2010
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Apache.NMS.ActiveMQ.Transport.Tcp
+{
+ public class SslTransportFactory : TcpTransportFactory
+ {
+ private string brokerCertLocation;
+ private string brokerCertPassword;
+ private string clientCertLocation;
+ private string clientCertPassword;
+
+ public SslTransportFactory() : base()
+ {
+ }
+
+ public string BrokerCertLocation
+ {
+ get { return this.brokerCertLocation; }
+ set { this.brokerCertLocation = value; }
+ }
+
+ public string BrokerCertPassword
+ {
+ get { return this.brokerCertPassword; }
+ set { this.brokerCertPassword = value; }
+ }
+
+ public string ClientCertLocation
+ {
+ get { return this.clientCertLocation; }
+ set { this.clientCertLocation = value; }
+ }
+
+ public string ClientCertPassword
+ {
+ get { return this.clientCertPassword; }
+ set { this.clientCertPassword = value; }
+ }
+
+ protected override ITransport DoCreateTransport(Uri location, Socket socket, IWireFormat wireFormat )
+ {
+ Tracer.Debug("Creating new instance of the SSL Transport.");
+ SslTransport transport = new SslTransport(location, socket, wireFormat);
+
+ transport.BrokerCertLocation = BrokerCertLocation;
+ transport.BrokerCertPassword = BrokerCertPassword;
+ transport.ClientCertLocation = ClientCertLocation;
+ transport.ClientCertPassword = ClientCertPassword;
+
+ return transport;
+ }
+ }
+}
Propchange: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs
------------------------------------------------------------------------------
svn:eol-style = native
Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs?rev=916457&r1=916456&r2=916457&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs Thu Feb 25 21:05:04 2010
@@ -29,8 +29,8 @@
/// </summary>
public class TcpTransport : ITransport
{
- private readonly object myLock = new object();
- private readonly Socket socket;
+ protected readonly object myLock = new object();
+ protected readonly Socket socket;
private IWireFormat wireformat;
private BinaryReader socketReader;
private BinaryWriter socketWriter;
@@ -55,10 +55,15 @@
this.wireformat = wireformat;
}
- ~TcpTransport()
+ ~TcpTransport()
{
Dispose(false);
}
+
+ protected virtual Stream CreateSocketStream()
+ {
+ return new NetworkStream(socket);
+ }
/// <summary>
/// Method Start
@@ -83,10 +88,11 @@
started = true;
- // As reported in AMQ-988 it appears that NetworkStream is not thread safe
- // so lets use an instance for each of the 2 streams
- socketWriter = new EndianBinaryWriter(new NetworkStream(socket));
- socketReader = new EndianBinaryReader(new NetworkStream(socket));
+ // Initialize our Read and Writer instances. Its not actually necessary
+ // to have two distinct NetworkStream instances but for now the TcpTransport
+ // will continue to do so for legacy reasons.
+ socketWriter = new EndianBinaryWriter(CreateSocketStream());
+ socketReader = new EndianBinaryReader(CreateSocketStream());
// now lets create the background read thread
readThread = new Thread(new ThreadStart(ReadLoop));
Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs?rev=916457&r1=916456&r2=916457&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs Thu Feb 25 21:05:04 2010
@@ -129,7 +129,7 @@
OpenWireFormat wireformat = new OpenWireFormat();
// Set wireformat. properties on the wireformat owned by the tcpTransport
URISupport.SetProperties(wireformat.PreferredWireFormatInfo, map, "wireFormat.");
- ITransport transport = new TcpTransport(location, socket, wireformat);
+ ITransport transport = DoCreateTransport(location, socket, wireformat);
wireformat.Transport = transport;
@@ -166,6 +166,15 @@
#endregion
+ /// <summary>
+ /// Override in a subclass to create the specific type of transport that is
+ /// being implemented.
+ /// </summary>
+ protected virtual ITransport DoCreateTransport(Uri location, Socket socket, IWireFormat wireFormat )
+ {
+ return new TcpTransport(location, socket, wireFormat);
+ }
+
// DISCUSSION: Caching host entries may not be the best strategy when using the
// failover protocol. The failover protocol needs to be very dynamic when looking
// up hostnames at runtime. If old hostname->IP mappings are kept around, this may
Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/TransportFactory.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/TransportFactory.cs?rev=916457&r1=916456&r2=916457&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/TransportFactory.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/TransportFactory.cs Thu Feb 25 21:05:04 2010
@@ -82,7 +82,10 @@
case "tcp":
factory = new TcpTransportFactory();
break;
- case "discovery":
+ case "ssl":
+ factory = new SslTransportFactory();
+ break;
+ case "discovery":
factory = new DiscoveryTransportFactory();
break;
case "failover":