diff options
| author | Robert Greig <rgreig@apache.org> | 2007-01-29 10:46:27 +0000 |
|---|---|---|
| committer | Robert Greig <rgreig@apache.org> | 2007-01-29 10:46:27 +0000 |
| commit | 2bcc371558ce0659f53b86046cdf3d5de3b20910 (patch) | |
| tree | d0c987cfa076eb90edb80620661d69a6e7354d3a /dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs | |
| parent | fe736211136b60bec61c1a22d3765be9142c6b39 (diff) | |
| download | qpid-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.cs | 81 |
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; + } } } |
