alanxz / SimpleAmqpClient

Simple C++ Interface to rabbitmq-c
MIT License
397 stars 213 forks source link

SimpleAmqClient external auth #95

Open dnj12345 opened 9 years ago

dnj12345 commented 9 years ago

Hi, Has support for external auth in SimpleAmqpClient come to fruition. This topic was discussed in the following thread?

http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2014-March/034866.html

Thanks, Bhasker.

alanxz commented 9 years ago

It has not. Tests would need to be added to the rabbitmq-c PR linked, then merged into master. SimpleAmqpClient would then need to be extended to support this feature of rabbitmq-c.

dnj12345 commented 9 years ago

Thanks. I pulled down your change for external auth and built it. Then I modified the example amqp_listen.c as shown below. When I start the listener, it fails.

./examples/amqp_listen localhost 5672 amq.direct test sasl_mechanism_in_list fail Unknown SASL method Logging in: (unknown error)

What am I doing wrong? Thanks.

+++ rabbitmq-c/examples/amqp_listen.c
@@ -80,7 +80,9 @@ int main(int argc, char const *const *argv)
     die("opening TCP socket");
   }

-  die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
+  //die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
+  //                  "Logging in");
+  die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_EXTERNAL, "guest", "guest"),
                     "Logging in");
   amqp_channel_open(conn, 1);
   die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
alanxz commented 9 years ago
  1. You're calling amqp_login twice.
  2. Make sure the broker is advertising that it will do the EXTERNAL SASL mechanism.
  3. There's a good possibility that the PR contains a bug (which is why it needs tests ;-)).
dnj12345 commented 9 years ago

I don't believe I am calling login twice. The diff shows '-' for the modified line. This is the example listener which I am trying to validate. Where is the broker involved?

alanxz commented 9 years ago

Since this isn't a SimpleAmqpClient thing (yet), lets continue this discussion over on alanxz/rabbitmq-c#179

dnj12345 commented 9 years ago

ok. I've also made changes to SimpleAmqpClient to incorporate the external auth stuff. I am getting undefined errors in my app.

I am linking my app to the new new library using '-L -lSimpleAmqpClient' Still I keep getting these undefined errors. Any suggestions?

Please see this on the web since it could be a long one...

In function `boost::detail::sp_if_not_array<AmqpClient::Channel>::type boost::make_shared<AmqpClient::Channel, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, amqp_sasl_method_enum_>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int const&, amqp_sasl_method_enum_ const&)':
/usr/local/include/boost/smart_ptr/make_shared_object.hpp:927: undefined reference to `AmqpClient::Channel::Channel(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, amqp_sasl_method_enum_)'
diff --git SimpleAmqpClient/src/Channel.cpp SimpleAmqpClient/src/Channel.cpp
index 01a5df0..4ce55c9 100644
--- SimpleAmqpClient/src/Channel.cpp
+++ SimpleAmqpClient/src/Channel.cpp
@@ -82,6 +82,7 @@ Channel::ptr_t Channel::CreateFromUri(const std::string &uri, int frame_max)
         throw BadUriException();
     }

+    // use PLAIN auth since amqp_connection_info doesn't have an option to specify auth param.
     return Create(std::string(info.host),
                   info.port,
                   std::string(info.user),
@@ -95,7 +96,8 @@ Channel::Channel(const std::string &host,
                  const std::string &username,
                  const std::string &password,
                  const std::string &vhost,
-                 int frame_max) :
+                 int frame_max,
+                 const amqp_sasl_method_enum sasl_method) :
     m_impl(new Detail::ChannelImpl)
 {
     m_impl->m_connection = amqp_new_connection();
@@ -111,7 +113,7 @@ Channel::Channel(const std::string &host,
         int sock = amqp_socket_open(socket, host.c_str(), port);
         m_impl->CheckForError(sock);

-        m_impl->DoLogin(username, password, vhost, frame_max);
+        m_impl->DoLogin(username, password, vhost, frame_max, sasl_method);
     }
     catch (...)
     {
@@ -129,7 +131,8 @@ Channel::Channel(const std::string &host,
                  const std::string &password,
                  const std::string &vhost,
                  int frame_max,
-                 const SSLConnectionParams &ssl_params)
+                 const SSLConnectionParams &ssl_params,
+                 const amqp_sasl_method_enum sasl_method)
     : m_impl(new Detail::ChannelImpl)
 {
     m_impl->m_connection = amqp_new_connection();
@@ -171,7 +174,7 @@ Channel::Channel(const std::string &host,
             throw std::runtime_error("Error in opening SSL/TLS connection for socket");
         }

-        m_impl->DoLogin(username, password, vhost, frame_max);
+        m_impl->DoLogin(username, password, vhost, frame_max, sasl_method);
     }
     catch (...)
     {
diff --git SimpleAmqpClient/src/ChannelImpl.cpp SimpleAmqpClient/src/ChannelImpl.cpp
index 9749556..7705e1d 100644
--- SimpleAmqpClient/src/ChannelImpl.cpp
+++ SimpleAmqpClient/src/ChannelImpl.cpp
@@ -67,7 +67,8 @@ ChannelImpl::~ChannelImpl()
 }

 void ChannelImpl::DoLogin(const std::string &username,
-        const std::string &password, const std::string &vhost, int frame_max)
+        const std::string &password, const std::string &vhost, int frame_max,
+        amqp_sasl_method_enum sasl_method)
 {
     amqp_table_entry_t capabilties[1];
     amqp_table_entry_t capability_entry;
@@ -87,8 +88,8 @@ void ChannelImpl::DoLogin(const std::string &username,
     client_properties.entries = &capability_entry;

     CheckRpcReply(0, amqp_login_with_properties(m_connection, vhost.c_str(), 0,
-                frame_max, BROKER_HEARTBEAT, &client_properties,
-                AMQP_SASL_METHOD_PLAIN, username.c_str(), password.c_str()));
+                        frame_max, BROKER_HEARTBEAT, &client_properties,
+                        sasl_method, username.c_str(), password.c_str()));
 }

 amqp_channel_t ChannelImpl::GetNextChannelId()
diff --git SimpleAmqpClient/src/SimpleAmqpClient/Channel.h SimpleAmqpClient/src/SimpleAmqpClient/Channel.h
index d930108..ad9dd9a 100644
--- SimpleAmqpClient/src/SimpleAmqpClient/Channel.h
+++ SimpleAmqpClient/src/SimpleAmqpClient/Channel.h
@@ -29,6 +29,7 @@
  * ***** END LICENSE BLOCK *****
  */

+#include <amqp.h>

 #include "SimpleAmqpClient/BasicMessage.h"
 #include "SimpleAmqpClient/Envelope.h"
@@ -89,9 +90,11 @@ public:
                         const std::string &username = "guest",
                         const std::string &password = "guest",
                         const std::string &vhost = "/",
-                        int frame_max = 131072)
+                        int frame_max = 131072,
+                        amqp_sasl_method_enum sasl_method=AMQP_SASL_METHOD_PLAIN)
     {
-        return boost::make_shared<Channel>(host, port, username, password, vhost, frame_max);
+        return boost::make_shared<Channel>(host, port, username, password, vhost,
+                                           frame_max, sasl_method);
     }

 protected:
@@ -133,7 +136,8 @@ public:
                               const std::string &password = "guest",
                               const std::string &vhost = "/",
                               int frame_max = 131072,
-                              bool verify_hostname = true)
+                              bool verify_hostname = true,
+                              amqp_sasl_method_enum sasl_method=AMQP_SASL_METHOD_PLAIN)
     {
         SSLConnectionParams ssl_params;
         ssl_params.path_to_ca_cert = path_to_ca_cert;
@@ -147,7 +151,8 @@ public:
                                            password,
                                            vhost,
                                            frame_max,
-                                           ssl_params);
+                                           ssl_params,
+                                           sasl_method);
     }

@@ -165,7 +170,8 @@ public:
                      const std::string &username,
                      const std::string &password,
                      const std::string &vhost,
-                     int frame_max);
+                     int frame_max,
+                     const amqp_sasl_method_enum sasl_method);

     explicit Channel(const std::string &host,
                      int port,
@@ -173,7 +179,8 @@ public:
                      const std::string &password,
                      const std::string &vhost,
                      int frame_max,
-                     const SSLConnectionParams &ssl_params);
+                     const SSLConnectionParams &ssl_params,
+                     const amqp_sasl_method_enum sasl_method);

 public:
diff --git SimpleAmqpClient/src/SimpleAmqpClient/ChannelImpl.h SimpleAmqpClient/src/SimpleAmqpClient/ChannelIm
index d30b6c2..e7b5e6a 100644
--- SimpleAmqpClient/src/SimpleAmqpClient/ChannelImpl.h
+++ SimpleAmqpClient/src/SimpleAmqpClient/ChannelImpl.h
@@ -64,7 +64,8 @@ public:
     typedef channel_map_t::iterator channel_map_iterator_t;

     void DoLogin(const std::string &username, const std::string &password,
-            const std::string &vhost, int frame_max);
+            const std::string &vhost, int frame_max,
+            amqp_sasl_method_enum sasl_method=AMQP_SASL_METHOD_PLAIN);
     amqp_channel_t GetChannel();
     void ReturnChannel(amqp_channel_t channel);
     bool IsChannelOpen(amqp_channel_t channel);
alanxz commented 9 years ago

Look very carefully at the function signature that the compiler is complaining about. The boost::make_shared<>() template is rather picky about function signatures.