Just to update on this, I have included both sources (cyrus_sasl.c and 
cyrus_stub.c) and it works as expected.

Cheers


Andrew North
SOFTWARE ENGINEER
From: Andrew North
Sent: Monday, June 10, 2024 3:57 PM
To: users@qpid.apache.org
Subject: Is SASL_SSL enforced with qpid-proton when CyrusSASL dependency is used

Hi,

I've been using qpid-proton 0.39 C/C++, I have been testing with an extended 
version of the samples.
I'm sending secure messages and authenticating connections with SSL 
certificates I have generated manually connecting to a RabbitMQ broker.
I've validated the certificates and connections using openssl on the terminal 
and using qpid-proton samples.
I'm using both OpenSSL and CyrusSASL dependencies.

I have a "bug" perhaps in configuration of my client, where when I enable the 
dependency for cyrus-sasl.c over the cyrus-stub.c, I am no longer
able to authenticate using "PLAIN", and my default connection is forcing 
"EXTERNAL" SASL mechanism even if explicitly set it to false in connection 
options.

Below are some snippets from my tests:
This is my dummy_client
"""
class dummy_client : public proton::messaging_handler {
public:
    void on_container_start(proton::container& c) override {
       proton::connection_options client_opts;
       client_opts.handler(*this);

       if(this->_use_auth){
         client_opts.user(this->_user);
         client_opts.password(this->_password);
       }

       client_opts.sasl_enabled(false);

       if(this->_use_ssl) {
         std::string client_cert = this->_cert_dir + "client-cert.pem";
         std::string client_key = this->_cert_dir + "client-key.pem";
         std::string client_pw = "password";
         std::string client_ca  = this->_cert_dir + "ca-cert.pem";
         proton::ssl_certificate ssl_cert(client_cert, client_key, client_pw);
         proton::ssl_client_options ssl_client_opts(ssl_cert, client_ca, 
proton::ssl::VERIFY_PEER);
         if(this->_use_sasl){
           client_opts.sasl_enabled(true);
           
client_opts.ssl_client_options(ssl_client_opts).sasl_allowed_mechs(this->_sasl_mech);
         } else {
           client_opts.ssl_client_options(ssl_client_opts);
         }
       }

       if(this->_sasl_mech == "INSECURE") {
         client_opts.sasl_allow_insecure_mechs(true);
       }

       proton::sender s = c.open_sender(this->_url + "/" + this->_address, 
client_opts);
    }

    void on_sendable(proton::sender& s) override {
       proton::message m;
       m.body("Hello World!");
       s.send(m);
       s.close();
    }
  }
"""

Simplified test logic:
"""
{
  dummy_client client;
  proton::container container(client);
  local_thread = std::jthread([&](){ container.run(); });
  std::this_thread::sleep_for(std::chrono::microseconds(wait_sec*1000000));
  if (local_thread.joinable()) {
    container.stop();
    local_thread.join();
  }
}
"""

I have multiple tests with the following configurations:

  *   _url=target_ip:{5672,5671}
  *   _address=test_NN
  *   _use_auth={true,false}
  *   _user={guest,new_user}
  *   _password={guest,password}
  *   _use_ssl={true,false}
  *   _use_sasl={true,false}
  *   _sasl_mech={"INSECURE","PLAIN","EXTERNAL"}

I have run the tests in 4 different scenarios, below are the results:

  *   Using one of these two dependencies {cyrus_stub.c, cyrus_sasl.c}
  *   RabbitMQ - SASL_SSL authentication {on, off}

port
use_auth
user
password
use_ssl
use_sasl
sasl_mech
result w/plugin
w/cyrus_stub.c
result wo/plugin
w/cyrus_stub.c
result w/plugin
w/cyrus_sasl.c
result wo/plugin
w/cyrus_sasl.c
5672
-
-
-
-
-
-
PASS
PASS
PASS
PASS
5672
X
guest
guest
-
-
-
PASS
PASS
FAIL - SASL error (-4)
FAIL - SASL error (-4)
5672
X
new_user
password
-
-
-
PASS
PASS
FAIL - SASL error (-4)
FAIL - SASL error (-4)
5671
-
-
-
X
-
"INSECURE"
ERROR
PASS
PASS
FAIL - SASL error (-4)
5671
X
guest
guest
X
-
"INSECURE"
ERROR
PASS
PASS
FAIL - SASL error (-4)
5671
X
new_user
password
X
-
"INSECURE"
ERROR
PASS
PASS
FAIL - SASL error (-4)
5671
-
-
-
X
-
-
ERROR
PASS
PASS
FAIL - SASL error (-4)
5671
X
guest
guest
X
-
-
ERROR
PASS
PASS
FAIL - SASL error (-4)
5671
X
new_user
password
X
-
-
ERROR
PASS
PASS
FAIL - SASL error (-4)
5671
X
guest
guest
X
X
"PLAIN"
PASS
PASS
FAIL - SASL error (-4)
FAIL - SASL error (-4)
5671
-
-
-
X
X
"PLAIN"
FAIL - auth mech=none
FAIL - auth mech=none
FAIL - SASL error (-4)
FAIL - SASL error (-4)
5671
X
guest
guest
X
X
"EXTERNAL"
PASS
FAIL - auth mech=none
PASS
FAIL - auth
5671
-
-
-
X
X
"EXTERNAL"
PASS
FAIL - auth mech=none
PASS
FAIL - auth

Summary of results using cyrus_stub.c:

  *   Can always connect and send unsecure messages with no configuration set 
(assuming this means "ANONYMOUS")
  *   RabbitMQ NOT Using SASL_SSL:
     *   Can connect and send unsecure messages via port 5672, even with user 
credentials
     *   Can connect and send secure messages via port 5671, even with user 
credentials
     *   Can authenticate using "PLAIN" SASL
     *   Fails to authenticate using "EXTERNAL" assumed to be SASL_SSL 
authentication
  *   RabbitMQ Using SASL_SSL:
     *   Can connect and send unsecure messages via port 5672, even with user 
credentials
     *   Can't connect and send secure messages via port 5671
     *   Can authenticate using "PLAIN" SASL, and send secure messages via port 
5671
     *   Can authenticate using "EXTERNAL", assumed to be SASL_SSL 
authentication and send secure messages via port 5671

Summary of results using cyrus_sasl.c:

  *   Can always connect and send unsecure messages with no configuration set 
(assuming this means "ANONYMOUS")
  *   RabbitMQ NOT Using SASL_SSL:
     *   Can't connect or send unsecure/secure message via ports 5672/5671, 
with or without user credentials
     *   Can't authenticate using "PLAIN" SASL
     *   Fails to authenticate using "EXTERNAL" assumed to be SASL_SSL 
authentication
     *   Always assumes SASL is using "EXTERNAL" mech when sasl is explicitly 
disabled using "client_opts.sasl_enabled(false);"
  *   RabbitMQ Using SASL_SSL:
     *   Can't connect and send unsecure messages via port 5672, even with user 
credentials
     *   Can connect and send secure messages via port 5671 - but transport 
assumes use of "EXTERNAL" mech.
     *   Can't authenticate using "PLAIN" SASL
     *   Can authenticate using "EXTERNAL", assumed to be SASL_SSL 
authentication and send secure messages via port 5671

Let me know if you can see the formatted results as a table, I also have the 
following questions:

  *   Are we forced to use SASL authentication if we use dependency 
cyrus_sasl.c as opposed to cyrus_stub.c?
  *   Is there a configuration I am doing by mistake?
  *   Can a client be configured to open a container with "PLAIN" 
authentication, and a second container be opened with "EXTERNAL" or "NONE" 
depending on other log

If you have any suggestions or further clarity regarding above, that would be 
great thanks. I will continue to experiment with what I have.

Kind Regards,
Andrew

Reply via email to