summaryrefslogtreecommitdiff
path: root/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs
diff options
context:
space:
mode:
authorRobert Greig <rgreig@apache.org>2007-01-29 10:46:27 +0000
committerRobert Greig <rgreig@apache.org>2007-01-29 10:46:27 +0000
commit2bcc371558ce0659f53b86046cdf3d5de3b20910 (patch)
treed0c987cfa076eb90edb80620661d69a6e7354d3a /dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs
parentfe736211136b60bec61c1a22d3765be9142c6b39 (diff)
downloadqpid-python-2bcc371558ce0659f53b86046cdf3d5de3b20910.tar.gz
(Patch supplied by Tomas Restrepo) QPID-291-2.diff applied. Adds SASL capability to the .Net client.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@501001 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs')
-rw-r--r--dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs81
1 files changed, 59 insertions, 22 deletions
diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs
index e88ff3ddbd..1815bea152 100644
--- a/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs
+++ b/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs
@@ -19,11 +19,15 @@
*
*/
using System;
+using System.Collections;
using System.Text;
using log4net;
using Qpid.Client.Protocol;
+using Qpid.Client.Security;
using Qpid.Client.State;
using Qpid.Framing;
+using Qpid.Sasl;
+
namespace Qpid.Client.Handler
{
@@ -35,36 +39,22 @@ namespace Qpid.Client.Handler
{
ConnectionStartBody body = (ConnectionStartBody) evt.Method;
AMQProtocolSession ps = evt.ProtocolSession;
- string username = ps.Username;
- string password = ps.Password;
try
{
- if (body.Mechanisms == null)
+ if ( body.Mechanisms == null )
{
throw new AMQException("mechanism not specified in ConnectionStart method frame");
}
- string allMechanisms = Encoding.ASCII.GetString(body.Mechanisms);
- string[] mechanisms = allMechanisms.Split(' ');
- string selectedMechanism = null;
- foreach (string mechanism in mechanisms)
- {
- if (mechanism.Equals("PLAIN"))
- {
- selectedMechanism = mechanism;
- break;
- }
- }
-
- if (selectedMechanism == null)
+ string mechanisms = Encoding.UTF8.GetString(body.Mechanisms);
+ string selectedMechanism = ChooseMechanism(mechanisms);
+ if ( selectedMechanism == null )
{
throw new AMQException("No supported security mechanism found, passed: " + mechanisms);
}
+
+ byte[] saslResponse = DoAuthentication(selectedMechanism, ps);
- // we always write out a null authzid which we don't currently use
- byte[] plainData = new byte[1 + ps.Username.Length + 1 + ps.Password.Length];
- Encoding.UTF8.GetBytes(username, 0, username.Length, plainData, 1);
- Encoding.UTF8.GetBytes(password, 0, password.Length, plainData, username.Length + 2);
if (body.Locales == null)
{
throw new AMQException("Locales is not defined in Connection Start method");
@@ -86,8 +76,9 @@ namespace Qpid.Client.Handler
clientProperties["product"] = "Qpid.NET";
clientProperties["version"] = "1.0";
clientProperties["platform"] = GetFullSystemInfo();
- AMQFrame frame = ConnectionStartOkBody.CreateAMQFrame(evt.ChannelId, clientProperties, selectedMechanism,
- plainData, selectedLocale);
+ AMQFrame frame = ConnectionStartOkBody.CreateAMQFrame(
+ evt.ChannelId, clientProperties, selectedMechanism,
+ saslResponse, selectedLocale);
ps.WriteFrame(frame);
}
catch (Exception e)
@@ -109,5 +100,51 @@ namespace Qpid.Client.Handler
// TODO: add in details here
return ".NET 1.1 Client";
}
+
+ private string ChooseMechanism(string mechanisms)
+ {
+ foreach ( string mech in mechanisms.Split(' ') )
+ {
+ if ( CallbackHandlerRegistry.Instance.IsSupportedMechanism(mech) )
+ {
+ return mech;
+ }
+ }
+ return null;
+ }
+
+ private byte[] DoAuthentication(string selectedMechanism, AMQProtocolSession ps)
+ {
+ ISaslClient saslClient = Sasl.Sasl.CreateClient(
+ new string[] { selectedMechanism }, null, "AMQP", "localhost",
+ new Hashtable(), CreateCallbackHandler(selectedMechanism, ps)
+ );
+ if ( saslClient == null )
+ {
+ throw new AMQException("Client SASL configuration error: no SaslClient could be created for mechanism " +
+ selectedMechanism);
+ }
+ ps.SaslClient = saslClient;
+ try
+ {
+ return saslClient.HasInitialResponse ?
+ saslClient.EvaluateChallenge(new byte[0]) : null;
+ } catch ( Exception ex )
+ {
+ ps.SaslClient = null;
+ throw new AMQException("Unable to create SASL client", ex);
+ }
+ }
+
+ private IAMQCallbackHandler CreateCallbackHandler(string mechanism, AMQProtocolSession session)
+ {
+ Type type = CallbackHandlerRegistry.Instance.GetCallbackHandler(mechanism);
+ IAMQCallbackHandler handler =
+ (IAMQCallbackHandler)Activator.CreateInstance(type);
+ if ( handler == null )
+ throw new AMQException("Unable to create callback handler: " + mechanism);
+ handler.Initialize(session);
+ return handler;
+ }
}
}