Hi, I'm using version 0.37.0 of the C++ library (qpid-proton-cpp-0.37.0) and 
can't figure out how to authenticate with a username/password. My test setup:

For the broker, I run ActiveMQ Classic using this command: podman run -it --rm 
--net=host --env ACTIVEMQ_CONNECTION_USER=admin --env 
ACTIVEMQ_CONNECTION_PASSWORD=admin docker.io/apache/activemq-classic

For the C++ client, I run the code from the "simple_send.cpp" example at 
https://qpid.apache.org/releases/qpid-proton-0.37.0/proton/cpp/api/simple_send_8cpp-example.html,
 which I simplified to hardcode the username/password to admin/admin:

#include <proton/connection.hpp>
#include <proton/connection_options.hpp>
#include <proton/container.hpp>
#include <proton/message.hpp>
#include <proton/message_id.hpp>
#include <proton/messaging_handler.hpp>
#include <proton/reconnect_options.hpp>
#include <proton/tracker.hpp>
#include <proton/types.hpp>

#include <iostream>
#include <map>


class simple_send : public proton::messaging_handler {
  private:
    std::string url;
    std::string user;
    std::string password;
    bool reconnect;
    proton::sender sender;
    int sent;
    int confirmed;
    int total;

  public:
    simple_send(const std::string &s, const std::string &u, const std::string 
&p, bool r, int c) :
        url(s), user(u), password(p), reconnect(r), sent(0), confirmed(0), 
total(c) {}

    void on_container_start(proton::container &c) override {
        proton::connection_options co;
        if (!user.empty()) co.user(user);
        if (!password.empty()) co.password(password);
        if (reconnect) co.reconnect(proton::reconnect_options());
        sender = c.open_sender(url, co);
    }

    void on_connection_open(proton::connection& c) override {
        if (c.reconnected()) {
            sent = confirmed;   // Re-send unconfirmed messages after a 
reconnect
        }
    }

    void on_sendable(proton::sender &s) override {
        while (s.credit() && sent < total) {
            proton::message msg;
            std::map<std::string, int> m;
            m["sequence"] = sent + 1;

            msg.id(sent + 1);
            msg.body(m);

            s.send(msg);
            sent++;
        }
    }

    void on_tracker_accept(proton::tracker &t) override {
        confirmed++;

        if (confirmed == total) {
            std::cout << "all messages confirmed" << std::endl;
            t.connection().close();
        }
    }

    void on_transport_close(proton::transport &) override {
        sent = confirmed;
    }
};

int main(int argc, char **argv) {
    std::string address = "127.0.0.1:5672/examples";
    std::string user = "admin";
    std::string password = "admin";
    bool reconnect = false;
    int message_count = 100;

    try {
        simple_send send(address, user, password, reconnect, message_count);
        proton::container(send).run();

        return 0;
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
    }

    return 1;
}

When run, the C++ client crashes with this error:

amqp:unauthorized-access: Authentication failed [mech=ANONYMOUS]

The error message suggests (?) that the username/password I specify are not 
being used, since it says "mech=ANONYMOUS". Can anyone see an obvious mistake 
in my C++ code? Am I not setting the username/password correctly? Is this a 
known bug in version 0.37.0?

In contrast, I can successfully authenticate to the broker using the C# library 
example at 
https://docs.redhat.com/en/documentation/red_hat_build_of_apache_qpid_proton_dotnet/1.0/html-single/using_qpid_proton_dotnet/index.
 In the C# example, if I specify the username/password as admin/admin then 
message posting succeeds, and when I specify a wrong password it fails with an 
authentication error.

Reply via email to