Hey!

This is regarding the Qpid Proton C-API and version 0.24.0 and Cyrus SASL 2.1.26-21 running on CentOS7.

I am new to the AMQP world, hance also to Qpid Proton. I am looking into implementing a good single-sign-on solution using Kerberos GSSAPI between two very simple softwares as a proof of concept. I am on the other hand not new to MIT Kerberos and GSSAPI. So.. Here we go: There is a small qpid-dispatch-like software as server and a small client connecting to it and a heartbeat is received by the client. This works without SASL.

The server was previously written in an way that the transport was handled and set-up by a "proactor". I now have the transport initialization in the set-up/init of the "container" implementation, to be able to configure the SASL-related stuff on the transport before the sockets start opening and such. For this transport connection I use pn_proactor_connect2(). It seems this modification also works without SASL.

However... I am quite confused - Maybe it's just my understanding of the concepts of AMQP that fail, or Cyrus SASL - Maybe both.

In the IT-environment I am expermementing on I have written very simple similar client/server solutions using GSSAPI straight off and it works. The Cyrus SASL sample-server/sample-client also works. The Kerberos single-sign-on authentication works as expected. And I have set-up a keytab (and verified that it works with my pure GSSAPI-example) for the amqp/my_hostname@MY_REALM.COM principle. Happy times!!!!

I guess, rather than explaining everything in detail trying to debug my crappy implemenation - What I am really asking for is a working example client/server that use SASL and GSSAPI which would be quite helpful and meaningful for others too, i guess. Maybe more effective?

Can some clever person please enlighten me?

I've come so far that the server and the client agree to use SASL and I can see that the transport (at least on the server-side) is reused Suprisingly both server and client agree to go for SASL. Then everything breaks down in "no worthy mechs". And connection is broken/out-of sync.

I do try to allocate pn_transport() in both the client and the server at a very early stage.

The gssapi and client variables originate from environment variables just to be able to run the same code with different authentication models for now.

Client and server common code:

  /*
   * Allocation/initialization (constructor if you'd like) where I keep
   * track of allocated things for a container instance.
   */
  container->transport = pn_transport();
  if (gssapi) {
    if (client) {
      container->sasl = init_client_single_sign_on(container->transport);
    }
    else {
      container->sasl = init_server_single_sign_on(container->transport);
    }
  }

Connecting the container looks somewhat like this:

  char a[PN_MAX_ADDR];
  pn_proactor_addr(a, sizeof(a), "my_hostname", "amqp");
  pn_proactor_connect2(container->proactor,
                       connection->impl,
                       container->transport,
                       a);

Client init:

  pn_sasl_t* s = pn_sasl(t);
  pn_sasl_allowed_mechs(s, "GSSAPI");
  return s;

Server init:

  pn_transport_set_server(t);
  pn_sasl_t* s = pn_sasl(t);
  /*
   * Weird way to find my sasl-config file in current dir AND the
   * CyrusSASL mechanism plugins. (Verified with strace)
   */
  pn_sasl_config_path(s, ".:/usr/lib64/sasl2"); /* TODO: dont hardcode */
  pn_sasl_config_name(s, "my-server");
  /*
   * Regardless: Only allow GSSAPI and require authentication.
   */
  pn_sasl_allowed_mechs(s, "GSSAPI");
  pn_transport_require_auth(t, true);
  pn_sasl_set_allow_insecure_mechs(s, false);
  return s;

my-server.conf:

  keytab: /path/to/my/keytab/the/user/can/access/amqp.keytab
  mech: GSSAPI
  realm: MY_REALM.COM

I don't realy know which of these Cyrus SASL make use of, since I (from my point of view) overriede "mech" in the code and "realm" should be comming from /etc/krb5.conf in my humble oppinion.

And in the container-code most events are basically empty... I would suspect that SASL should do the negotiation and at some point end up in some part of the state-machine... Let's say: PN_TRANSPORT_AUTHENTICATED. But i get stuck in PN_CONNECTION_BOUND and all hell breaks loose.

Is there something additional i have to do in the state-machine?

And the weird part is that I _currently_ get:

@sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:"SCRAM-SHA-1", :GSSAPI, :"GSS-SPNEGO", :"DIGEST-MD5", :"CRAM-MD5", :ANONYMOUS]]

... Wich seem to be way too many.

Server debug-stuff:

DEBUG: START contructor transport: 0x15a34a0
DEBUG: Setting up server single-sign-on for transport 0x15a34a0 and SASL 
0x15a34a0
[0x15b16e0]:(PN_CONNECTION_INIT, pn_connection<0x15b0650>)
[0x15b16e0]:(PN_CONNECTION_BOUND, pn_connection<0x15b0650>)
DEBUG: check_condition() transport 0x15b16e0
DEBUG: PN_CONNECTION_BOUND transport 0x15b16e0
[0x15b16e0]:AMQP SASL layer detected
[0x15b16e0]:  <- SASL
[0x15b16e0]:  -> SASL
[0x15b16e0]:0 -> @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:"SCRAM-SHA-1", :GSSAPI, :"GSS-SPNEGO", :"DIGEST-MD5", :"CRAM-MD5", :ANONYMOUS]] [0x15b16e0]:RAW: "\x00\x00\x00l\x02\x01\x00\x00\x00S@\xd0\x00\x00\x00\\x00\x00\x00\x01\xf0\x00\x00\x00S\x00\x00\x00\x06\xb3\x00\x00\x00\x0bSCRAM-SHA-1\x00\x00\x00\x06GSSAPI\x00\x00\x00\x0aGSS-SPNEGO\x00\x00\x00\x0aDIGEST-MD5\x00\x00\x00\x08CRAM-MD5\x00\x00\x00\x09ANONYMOUS"
[0x15b16e0]:(PN_TRANSPORT, pn_transport<0x15b16e0>)
[0x15b16e0]:ERROR amqp:connection:framing-error connection aborted
[0x15b16e0]:  <- EOS
[0x15b16e0]:  -> EOS
[0x15b16e0]:(PN_TRANSPORT_TAIL_CLOSED, pn_transport<0x15b16e0>)
[0x15b16e0]:(PN_TRANSPORT_ERROR, pn_transport<0x15b16e0>)
[0x15b16e0]:(PN_TRANSPORT_HEAD_CLOSED, pn_transport<0x15b16e0>)
[0x15b16e0]:(PN_TRANSPORT_CLOSED, pn_transport<0x15b16e0>)

Client debug-stuff:

DEBUG: START contructor transport: 0x247b500
DEBUG: Setting up client single-sign-on for transport 0x247b500 and SASL 0x247b500
[0x247b500]:(PN_CONNECTION_INIT, pn_connection<0x2486af0>)
[0x247b500]:(PN_CONNECTION_LOCAL_OPEN, pn_connection<0x2486af0>)
DEBUG: check_condition() transport 0x247b500
[0x247b500]:(PN_SESSION_INIT, pn_session<0x248b290>)
[0x247b500]:(PN_LINK_INIT, pn_link<0x248c5f0>)
[0x247b500]:(PN_LINK_INIT, pn_link<0x248f160>)
[0x247b500]:(PN_SESSION_LOCAL_OPEN, pn_session<0x248b290>)
[0x247b500]:(PN_LINK_LOCAL_OPEN, pn_link<0x248c5f0>)
[0x247b500]:(PN_LINK_LOCAL_OPEN, pn_link<0x248f160>)
[0x247b500]:(PN_SESSION_INIT, pn_session<0x2491eb0>)
[0x247b500]:(PN_LINK_INIT, pn_link<0x2493210>)
[0x247b500]:(PN_SESSION_LOCAL_OPEN, pn_session<0x2491eb0>)
[0x247b500]:(PN_LINK_LOCAL_OPEN, pn_link<0x2493210>)
[0x247b500]:(PN_CONNECTION_BOUND, pn_connection<0x2486af0>)
DEBUG: check_condition() transport 0x247b500
[0x247b500]:  -> SASL
[0x247b500]:  <- SASL
[0x247b500]:0 <- @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:"SCRAM-SHA-1", :GSSAPI, :"GSS-SPNEGO", :"DIGEST-MD5", :"CRAM-MD5", :ANONYMOUS]] [0x247b500]:sasl error: SASL(-4): no mechanism available: No worthy mechs found
[0x247b500]:(PN_TRANSPORT, pn_transport<0x247b500>)
[0x247b500]:ERROR amqp:unauthorized-access Authentication failed [mech=none]
[0x247b500]:  -> EOS
[0x247b500]:(PN_TRANSPORT_ERROR, pn_transport<0x247b500>)
[0x247b500]:(PN_TRANSPORT_TAIL_CLOSED, pn_transport<0x247b500>)
[0x247b500]:(PN_TRANSPORT_HEAD_CLOSED, pn_transport<0x247b500>)
[0x247b500]:(PN_TRANSPORT_CLOSED, pn_transport<0x247b500>)
Segmentation fault

... Heh, nice ending there :) Probably not related.

I get this on both sides... At some point earlier I did only get GSSAPI in that list. But still "no worthy mechs" error.

I hope someone can spread some light on my plight to secure this implementation. Please let me know if more information is needed too.

Kind regards,
AiO

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org

Reply via email to