Hi Qpid Proton,

tl;dr: I'm working with Proton-C 0.10 and would like to have explicit override 
options to keep Proton-C from automatically picking up on EXTERNAL when being 
offered by the server - while using the messenger layer.

By what I can see, currently Proton-C's messenger automatically picks up 
EXTERNAL as the default mechanism whenever offered by the server, and when a 
username has been configured for the target URI. I believe Proton-C s only 
needs to pick up on EXTERNAL under two explicit circumstances:

a)       As Proton is immediately responsible for establishing the TLS 
connection, snapping to EXTERNAL with TLS only appears to makes sense when 
Proton has been configured with an explicit TLS credential and has used that 
credential successfully.  The EXTERNAL handshake subsequently binds the 
certificate identity used at the transport layer to the application layer, i.e. 
the two identities ought be deemed identical by the server for proceeding past 
the handshake.

b)      Alternatively, there might be some form of secure IPSec/VPN/etc tunnel 
that establishes the client identity with the server below the transport, in 
which case, by the way, the "allow insecure mechanisms" flag that has been 
introduced is making an incorrect implication as the tunnel provides security 
for a non-TLS PLAIN flow. In the case of such a tunnel, Proton should have to 
be configured with an explicit external identity before it picks up on 
EXTERNAL. Right now, EXTERNAL being offered and a configured sasl->username 
(which might have been intended to be part of a PLAIN credential set) seem 
sufficient to trigger snapping to EXTERNAL.

Thus, ideally, Proton's messenger would thus only snap to EXTERNAL if I have 
either set a transport credential (cert) or have explicitly set an external 
identity (distinct from the username used for PLAIN) for the second case.

Irrespective of whether that behavior ends up being automatic, it would be very 
useful to have an explicit override in Messenger to force either PLAIN or 
ANONYMOUS even if EXTERNAL has been offered up, so that the application 
protocol credential can differ from the transport credential, if so desired. 
The SASL layer allows me to do that with pn_sasl_allowed_mechs(). 
Unfortunately, Messenger doesn't give me a hook to set that from the outside, 
or at least it's not obvious if it were.

I've played with adding two PN_FLAGS_FORCE_SASL_PLAIN / 
PN_FLAGS_FORCE_SASL_ANONYMOUS extension flags for messenger; that works just 
fine, even though I don't like mutually exclusive options in flag fields. These 
flags beat introducing a new function, though.

The ANONYMOUS override is an escape hatch that allows opting for AMQP 
claims-based-security flow, ignoring any SASL mechanisms offered up by the 

Snippet (3 similar looking spots in messenger.c) :

   if (messenger->flags & (PN_FLAGS_ALLOW_INSECURE_MECHS |

         pn_sasl_t *s = pn_sasl(transport);
         if (messenger->flags & PN_FLAGS_ALLOW_INSECURE_MECHS &&
               user && pass)
               pn_sasl_set_allow_insecure_mechs(s, true);
         if (messenger->flags & PN_FLAGS_FORCE_SASL_PLAIN)
                pn_sasl_allowed_mechs(s, "PLAIN");
         if (messenger->flags & PN_FLAGS_FORCE_SASL_ANONYMOUS)
               pn_sasl_allowed_mechs(s, "ANONYMOUS");

The override flags addition doesn't get into the automated selection options 
mentioned above, but is absolutely sufficient to unblock my scenarios.

Best Regards

Clemens Vasters
Architect, Azure Service Bus
Microsoft Corporation
Twitter @clemensv

Reply via email to