activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject svn commit: r921061 - in /activemq/activemq-dotnet/Apache.NMS.Stomp/trunk: ./ src/main/csharp/Transport/ src/main/csharp/Transport/Tcp/
Date Tue, 09 Mar 2010 19:16:00 GMT
Author: tabish
Date: Tue Mar  9 19:16:00 2010
New Revision: 921061

URL: http://svn.apache.org/viewvc?rev=921061&view=rev
Log:
https://issues.apache.org/activemq/browse/AMQNET-239

Add an SslTransport to the Stomp Client and throw an exception when Ssl is specified on NETCF
platforms.

Added:
    activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs
  (with props)
    activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs
  (with props)
Modified:
    activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs
    activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
    activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/TransportFactory.cs
    activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/vs2008-stomp.csproj

Added: activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs?rev=921061&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs
(added)
+++ activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs
Tue Mar  9 19:16:00 2010
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+#if !NETCF
+
+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.Stomp.Transport.Tcp
+{
+    public class SslTransport : TcpTransport
+    {
+        private string clientCertLocation;
+        private string clientCertPassword;
+        
+        private bool acceptInvalidBrokerCert = false;
+        
+        private SslStream sslStream;
+
+        public SslTransport(Uri location, Socket socket, IWireFormat wireFormat) :
+            base(location, socket, wireFormat)
+        {
+        }
+
+        ~SslTransport()
+        {
+            Dispose(false);
+        }
+
+        /// <summary>
+        /// Indicates the location of the Client Certificate to use when the Broker
+        /// is configured for Client Auth (not common).  The SslTransport will supply
+        /// this certificate to the SslStream via the SelectLocalCertificate method.
+        /// </summary>
+        public string ClientCertLocation
+        {
+            get { return this.clientCertLocation; }
+            set { this.clientCertLocation = value; }
+        }
+
+        /// <summary>
+        /// Password for the Client Certificate specified via configuration.
+        /// </summary>
+        public string ClientCertPassword
+        {
+            get { return this.clientCertPassword; }
+            set { this.clientCertPassword = value; }
+        }
+       
+        /// <summary>
+        /// Indicates if the SslTransport should ignore any errors in the supplied Broker
+        /// certificate and connect anyway, this is useful in testing with a default AMQ
+        /// broker certificate that is self signed.
+        /// </summary>
+        public bool AcceptInvalidBrokerCert
+        {
+            get { return this.acceptInvalidBrokerCert; }
+            set { this.acceptInvalidBrokerCert = value; }
+        }
+        
+        protected override Stream CreateSocketStream()
+        {
+            if(this.sslStream != null)
+            {
+                return this.sslStream;
+            }
+            
+            LocalCertificateSelectionCallback clientCertSelect = null;
+            
+            if(this.clientCertLocation != null )
+            {
+                clientCertSelect = new LocalCertificateSelectionCallback(SelectLocalCertificate);
+            }
+
+            this.sslStream = new SslStream(
+                new NetworkStream(this.socket), 
+                false,
+                new RemoteCertificateValidationCallback(ValidateServerCertificate),
+                clientCertSelect );
+
+            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 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.");
+            }
+            else if(sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable)
+            {
+                Tracer.Error("The Remote Certificate was not Available.");
+            }
+
+            // Configuration may or may not allow us to connect with an invliad broker cert.
+            return AcceptInvalidBrokerCert;
+        }
+        
+        private X509Certificate SelectLocalCertificate(object sender,
+                                                       string targetHost, 
+                                                       X509CertificateCollection localCertificates,

+                                                       X509Certificate remoteCertificate,

+                                                       string[] acceptableIssuers)
+        {    
+            Tracer.Debug("Client is selecting a local certificate.");
+        
+            X509Certificate2 certificate = new X509Certificate2( clientCertLocation, clientCertPassword
);
+                        
+            return certificate;
+        }
+        
+    }
+}
+
+#endif

Propchange: activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransport.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs?rev=921061&view=auto
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs
(added)
+++ activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs
Tue Mar  9 19:16:00 2010
@@ -0,0 +1,68 @@
+/*
+ * 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.Stomp.Transport.Tcp
+{
+	public class SslTransportFactory : TcpTransportFactory
+	{
+        private string clientCertLocation;
+        private string clientCertPassword;
+        private bool acceptInvalidBrokerCert = false;
+        
+        public SslTransportFactory() : base()
+        {
+        }
+
+        public string ClientCertLocation
+        {
+            get { return this.clientCertLocation; }
+            set { this.clientCertLocation = value; }
+        }
+
+        public string ClientCertPassword
+        {
+            get { return this.clientCertPassword; }
+            set { this.clientCertPassword = value; }
+        }        
+
+        public bool AcceptInvalidBrokerCert
+        {
+            get { return this.acceptInvalidBrokerCert; }
+            set { this.acceptInvalidBrokerCert = value; }
+        }
+        
+		protected override ITransport DoCreateTransport(Uri location, Socket socket, IWireFormat
wireFormat )
+		{
+            Tracer.Debug("Creating new instance of the SSL Transport.");
+#if !NETCF
+            SslTransport transport = new SslTransport(location, socket, wireFormat);
+            
+            transport.ClientCertLocation = ClientCertLocation;
+            transport.ClientCertPassword = ClientCertPassword;
+            transport.AcceptInvalidBrokerCert = AcceptInvalidBrokerCert;
+            
+            return transport;
+#else
+            throw new NotSupportedException("SslTransport not implemented on the .NET Compact
Framework.");
+#endif
+		}		
+	}
+}

Propchange: activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/SslTransportFactory.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs?rev=921061&r1=921060&r2=921061&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs
(original)
+++ activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransport.cs
Tue Mar  9 19:16:00 2010
@@ -29,8 +29,8 @@ namespace Apache.NMS.Stomp.Transport.Tcp
     /// </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;
@@ -60,6 +60,11 @@ namespace Apache.NMS.Stomp.Transport.Tcp
             Dispose(false);
         }
 
+        protected virtual Stream CreateSocketStream()
+        {
+            return new NetworkStream(socket);
+        }
+
         /// <summary>
         /// Method Start
         /// </summary>
@@ -83,10 +88,11 @@ namespace Apache.NMS.Stomp.Transport.Tcp
 
                     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 BinaryWriter(new NetworkStream(socket));
-                    socketReader = new BinaryReader(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 BinaryWriter(CreateSocketStream());
+                    socketReader = new BinaryReader(CreateSocketStream());
 
                     // now lets create the background read thread
                     readThread = new Thread(new ThreadStart(ReadLoop));

Modified: activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs?rev=921061&r1=921060&r2=921061&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
(original)
+++ activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
Tue Mar  9 19:16:00 2010
@@ -119,7 +119,7 @@ namespace Apache.NMS.Stomp.Transport.Tcp
 			IWireFormat wireformat = new StompWireFormat();
 			// Set wireformat. properties on the wireformat owned by the tcpTransport
 			URISupport.SetProperties(wireformat, map, "wireFormat.");
-			ITransport transport = new TcpTransport(location, socket, wireformat);
+            ITransport transport = DoCreateTransport(location, socket, wireformat);
 
 			wireformat.Transport = transport;
 
@@ -151,6 +151,15 @@ namespace Apache.NMS.Stomp.Transport.Tcp
 
 		#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.Stomp/trunk/src/main/csharp/Transport/TransportFactory.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/TransportFactory.cs?rev=921061&r1=921060&r2=921061&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/TransportFactory.cs
(original)
+++ activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/src/main/csharp/Transport/TransportFactory.cs
Tue Mar  9 19:16:00 2010
@@ -80,6 +80,9 @@ namespace Apache.NMS.Stomp.Transport
                 case "tcp":
                     factory = new TcpTransportFactory();
                     break;
+                case "ssl":
+                    factory = new SslTransportFactory();
+                    break;
                 default:
                     throw new NMSConnectionException(String.Format("The transport {0} is
not supported.", scheme));
                 }

Modified: activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/vs2008-stomp.csproj
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/vs2008-stomp.csproj?rev=921061&r1=921060&r2=921061&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/vs2008-stomp.csproj (original)
+++ activemq/activemq-dotnet/Apache.NMS.Stomp/trunk/vs2008-stomp.csproj Tue Mar  9 19:16:00
2010
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="3.5">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -31,6 +31,7 @@
     <BootstrapperEnabled>true</BootstrapperEnabled>
     <SignAssembly>true</SignAssembly>
     <AssemblyOriginatorKeyFile>keyfile\NMSKey.snk</AssemblyOriginatorKeyFile>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -143,6 +144,8 @@
     <Compile Include="src\main\csharp\Protocol\StompFrame.cs" />
     <Compile Include="src\main\csharp\Protocol\IPrimitiveMapMarshaler.cs" />
     <Compile Include="src\main\csharp\Protocol\XmlPrimitiveMapMarshaler.cs" />
+    <Compile Include="src\main\csharp\Transport\Tcp\SslTransport.cs" />
+    <Compile Include="src\main\csharp\Transport\Tcp\SslTransportFactory.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="keyfile\NMSKey.snk" />



Mime
View raw message