summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Simon <arnaudsimon@apache.org>2008-10-23 14:38:56 +0000
committerArnaud Simon <arnaudsimon@apache.org>2008-10-23 14:38:56 +0000
commit0ff4ce941d519aaa9851ca0f9b45246fb72fc5fd (patch)
treef6aeef86394291f8bfe6ce46845b7bd4ac7d0920
parentcd9fd453bd479531ac3cec401fdc6e25a74209c8 (diff)
downloadqpid-python-0ff4ce941d519aaa9851ca0f9b45246fb72fc5fd.tar.gz
Qpid-1392: Add SSL support
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@707381 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/dotnet/client-010/client/client/Client.cs37
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs57
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs194
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IoSender.cs5
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs6
5 files changed, 292 insertions, 7 deletions
diff --git a/qpid/dotnet/client-010/client/client/Client.cs b/qpid/dotnet/client-010/client/client/Client.cs
index be279d5243..4871a1c3d9 100644
--- a/qpid/dotnet/client-010/client/client/Client.cs
+++ b/qpid/dotnet/client-010/client/client/Client.cs
@@ -52,7 +52,16 @@ namespace org.apache.qpid.client
}
#region Interface ClientInterface
-
+
+ /// <summary>
+ /// Establishes a connection with a broker using the provided user auths
+ ///
+ /// </summary>
+ /// <param name="host">Host name on which a broker is deployed</param>
+ /// <param name="port">Broker port </param>
+ /// <param name="virtualHost">virtual host name</param>
+ /// <param name="username">User Name</param>
+ /// <param name="password">Password</param>
public void connect(String host, int port, String virtualHost, String username, String password)
{
_log.debug(String.Format("Client Connecting to host {0}; port {1}; virtualHost {2}; username {3}", host,
@@ -67,6 +76,32 @@ namespace org.apache.qpid.client
negotiationComplete.WaitOne();
}
+ /// <summary>
+ /// Establishes a connection with a broker using SSL
+ ///
+ /// </summary>
+ /// <param name="host">Host name on which a broker is deployed</param>
+ /// <param name="port">Broker port </param>
+ /// <param name="virtualHost">virtual host name</param>
+ /// <param name="username">User Name</param>
+ /// <param name="password">Password</param>
+ /// <param name="serverName">Name of the SSL server</param>
+ /// <param name="certPath">Path to the X509 certificate to be used for client authentication</param>
+ /// <param name="rejectUntrusted">If true connection will not be established if the broker is not trusted</param>
+ public void connectSSL(String host, int port, String virtualHost, String username, String password, string serverName, string certPath, bool rejectUntrusted)
+ {
+ _log.debug(String.Format("Client Connecting to host {0}; port {1}; virtualHost {2}; username {3}", host,
+ port, virtualHost, username));
+ _log.debug(String.Format("SSL paramters: serverName: {0}; certPath: {1}; rejectUntrusted: {2}", serverName, certPath, rejectUntrusted));
+ ConnectionDelegate connectionDelegate = new ClientConnectionDelegate(this, username, password);
+ ManualResetEvent negotiationComplete = new ManualResetEvent(false);
+ connectionDelegate.setCondition(negotiationComplete);
+ connectionDelegate.VirtualHost = virtualHost;
+ _conn = IoSSLTransport.connect(host, port, serverName, certPath, rejectUntrusted, connectionDelegate);
+
+ _conn.send(new ProtocolHeader(1, 0, 10));
+ negotiationComplete.WaitOne();
+ }
public void close()
{
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs b/qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs
new file mode 100644
index 0000000000..aab017dad1
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs
@@ -0,0 +1,57 @@
+/*
+* 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.IO;
+using System.Net.Sockets;
+
+namespace org.apache.qpid.transport.network.io
+{
+ public interface IIoTransport
+ {
+ Connection Connection
+ {
+ get;
+ set;
+ }
+
+ Receiver<ReceivedPayload<MemoryStream>> Receiver
+ {
+ get;
+ set;
+ }
+
+ IoSender Sender
+ {
+ get;
+ set;
+ }
+
+
+ Stream Stream
+ {
+ get;
+ set;
+ }
+
+ TcpClient Socket
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs b/qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs
new file mode 100644
index 0000000000..8c5f161a35
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs
@@ -0,0 +1,194 @@
+/*
+* 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.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.network.io
+{
+ public sealed class IoSSLTransport : IIoTransport
+ {
+ // constants
+ private const int DEFAULT_READ_WRITE_BUFFER_SIZE = 64*1024;
+ private const int TIMEOUT = 60000;
+ private const int QUEUE_SIZE = 1000;
+ // props
+ private static readonly Logger log = Logger.get(typeof (IoSSLTransport));
+ private Stream m_stream;
+ private IoSender m_sender;
+ private Receiver<ReceivedPayload<MemoryStream>> m_receiver;
+ private TcpClient m_socket;
+ private Connection m_con;
+ private readonly bool _rejectUntrusted;
+
+ public static Connection connect(String host, int port, string serverName, string certPath, bool rejectUntrusted, ConnectionDelegate conndel)
+ {
+ IIoTransport transport = new IoSSLTransport(host, port, serverName, certPath, rejectUntrusted, conndel);
+ return transport.Connection;
+ }
+
+ public IoSSLTransport(String host, int port, string serverName, string certPath, bool rejectUntrusted, ConnectionDelegate conndel)
+ {
+ _rejectUntrusted = rejectUntrusted;
+ createSocket(host, port, serverName, certPath);
+ Sender = new IoSender(this, QUEUE_SIZE, TIMEOUT);
+ Receiver = new IoReceiver(Stream, Socket.ReceiveBufferSize*2, TIMEOUT);
+ Assembler assembler = new Assembler();
+ InputHandler inputHandler = new InputHandler(InputHandler.State.PROTO_HDR);
+ Connection = new Connection(assembler, new Disassembler(Sender, 64*1024 - 1), conndel);
+ // Input handler listen to Receiver events
+ Receiver.Received += inputHandler.On_ReceivedBuffer;
+ // Assembler listen to inputhandler events
+ inputHandler.ReceivedEvent += assembler.On_ReceivedEvent;
+ // Connection listen to asembler protocol event
+ Receiver.Closed += Connection.On_ReceivedClosed;
+ Receiver.Exception += Connection.On_ReceivedException;
+ inputHandler.HandlerClosed += Connection.On_ReceivedClosed;
+ inputHandler.ExceptionProcessing += Connection.On_ReceivedException;
+ assembler.HandlerClosed += Connection.On_ReceivedClosed;
+ assembler.ExceptionProcessing += Connection.On_ReceivedException;
+ assembler.ReceivedEvent += Connection.On_ReceivedEvent;
+ }
+
+ public Connection Connection
+ {
+ get { return m_con; }
+ set { m_con = value; }
+ }
+
+ public Receiver<ReceivedPayload<MemoryStream>> Receiver
+ {
+ get { return m_receiver; }
+ set { m_receiver = value; }
+ }
+
+ public IoSender Sender
+ {
+ get { return m_sender; }
+ set { m_sender = value; }
+ }
+
+
+ public Stream Stream
+ {
+ get { return m_stream; }
+ set { m_stream = value; }
+ }
+
+ public TcpClient Socket
+ {
+ get { return m_socket; }
+ set { m_socket = value; }
+ }
+
+ #region Private Support Functions
+
+ private void createSocket(String host, int port, string serverName, string certPath)
+ {
+ TcpClient socket;
+ try
+ {
+ socket = new TcpClient();
+ String noDelay = Environment.GetEnvironmentVariable("qpid.tcpNoDelay");
+ String writeBufferSize = Environment.GetEnvironmentVariable("qpid.writeBufferSize");
+ String readBufferSize = Environment.GetEnvironmentVariable("qpid.readBufferSize");
+ socket.NoDelay = noDelay != null && bool.Parse(noDelay);
+ socket.ReceiveBufferSize = readBufferSize == null
+ ? DEFAULT_READ_WRITE_BUFFER_SIZE
+ : int.Parse(readBufferSize);
+ socket.SendBufferSize = writeBufferSize == null
+ ? DEFAULT_READ_WRITE_BUFFER_SIZE
+ : int.Parse(writeBufferSize);
+
+ log.debug("NoDelay : {0}", socket.NoDelay);
+ log.debug("ReceiveBufferSize : {0}", socket.ReceiveBufferSize);
+ log.debug("SendBufferSize : {0}", socket.SendBufferSize);
+ log.debug("Openning connection with host : {0}; port: {1}", host, port);
+
+ socket.Connect(host, port);
+ Socket = socket;
+ }
+ catch (Exception e)
+ {
+ throw new TransportException("Error connecting to broker", e);
+ }
+ try
+ {
+ //Initializes a new instance of the SslStream class using the specified Stream, stream closure behavior, certificate validation delegate and certificate selection delegate
+ SslStream sslStream = new SslStream(socket.GetStream(), false, ValidateServerCertificate, LocalCertificateSelection);
+ if (certPath != null)
+ {
+ X509CertificateCollection col = new X509CertificateCollection();
+ X509Certificate cert = X509Certificate.CreateFromCertFile(certPath);
+ col.Add(cert);
+ sslStream.AuthenticateAsClient(serverName, col, SslProtocols.Default, true);
+ }
+ else
+ {
+ sslStream.AuthenticateAsClient(serverName);
+ }
+ Stream = sslStream;
+ }
+ catch (AuthenticationException e)
+ {
+ log.warn("Exception: {0}", e.Message);
+ if (e.InnerException != null)
+ {
+ log.warn("Inner exception: {0}", e.InnerException.Message);
+ }
+ socket.Close();
+ throw new TransportException("Authentication failed - closing the connection.");
+ }
+ }
+
+ // The following method is invoked by the RemoteCertificateValidationDelegate.
+ public bool ValidateServerCertificate(
+ object sender,
+ X509Certificate certificate,
+ X509Chain chain,
+ SslPolicyErrors sslPolicyErrors)
+ {
+ bool result = true;
+ if (sslPolicyErrors != SslPolicyErrors.None && _rejectUntrusted )
+ {
+ log.warn("Certificate error: {0}", sslPolicyErrors);
+ // Do not allow this client to communicate with unauthenticated servers.
+ result = false;
+ }
+ return result;
+ }
+
+ public X509Certificate LocalCertificateSelection(
+ Object sender,
+ string targetHost,
+ X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate,
+ string[] acceptableIssuers
+ )
+ {
+ return remoteCertificate;
+ }
+
+ #endregion
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IoSender.cs b/qpid/dotnet/client-010/client/transport/network/io/IoSender.cs
index 810e0b8cf4..924d871dd2 100644
--- a/qpid/dotnet/client-010/client/transport/network/io/IoSender.cs
+++ b/qpid/dotnet/client-010/client/transport/network/io/IoSender.cs
@@ -18,7 +18,6 @@
*/
using System;
using System.IO;
-using System.Net.Sockets;
using System.Threading;
using common.org.apache.qpid.transport.util;
using org.apache.qpid.transport.util;
@@ -28,14 +27,14 @@ namespace org.apache.qpid.transport.network.io
public sealed class IoSender : IIOSender<MemoryStream>
{
private static readonly Logger log = Logger.get(typeof (IoReceiver));
- private readonly NetworkStream bufStream;
+ private readonly Stream bufStream;
private bool closed;
private readonly Mutex mutClosed = new Mutex();
private readonly CircularBuffer<byte[]> queue;
private readonly Thread thread;
private readonly int timeout;
private readonly MemoryStream _tobeSent = new MemoryStream();
- public IoSender(IoTransport transport, int queueSize, int timeout)
+ public IoSender(IIoTransport transport, int queueSize, int timeout)
{
this.timeout = timeout;
bufStream = transport.Stream;
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs b/qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs
index f2ebab67c9..3a2397870d 100644
--- a/qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs
+++ b/qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs
@@ -31,7 +31,7 @@ namespace org.apache.qpid.transport.network.io
/// SO_RCVBUF - qpid.readBufferSize
/// SO_SNDBUF - qpid.writeBufferSize
/// </summary>
- public sealed class IoTransport
+ public sealed class IoTransport : IIoTransport
{
// constants
private const int DEFAULT_READ_WRITE_BUFFER_SIZE = 64*1024;
@@ -39,7 +39,7 @@ namespace org.apache.qpid.transport.network.io
private const int QUEUE_SIZE = 1000;
// props
private static readonly Logger log = Logger.get(typeof (IoTransport));
- private NetworkStream m_stream;
+ private Stream m_stream;
private IoSender m_sender;
private Receiver<ReceivedPayload<MemoryStream>> m_receiver;
private TcpClient m_socket;
@@ -92,7 +92,7 @@ namespace org.apache.qpid.transport.network.io
}
- public NetworkStream Stream
+ public Stream Stream
{
get { return m_stream; }
set { m_stream = value; }