Bug 848356

Summary: EXTERNAL SASL mechanism is not described properly.
Product: Red Hat Enterprise MRG Reporter: Leonid Zhaldybin <lzhaldyb>
Component: Messaging_Installation_and_Configuration_GuideAssignee: Jared MORGAN <jmorgan>
Status: CLOSED CURRENTRELEASE QA Contact: Eric Sammons <esammons>
Severity: medium Docs Contact:
Priority: medium    
Version: 2.1.2CC: esammons, freznice, gsim, iboverma, kgiusti, mmurray, rlandman
Target Milestone: 3.0   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-01-22 15:27:17 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Leonid Zhaldybin 2012-08-15 11:35:21 UTC
Description of problem:
The use and configuration of the EXTERNAL SASL authentication mechanism is not described in proper details. This is the only piece of information I was able to find (in MUG, chapter "11.3. Encryption using SSL"):

"If the client chooses the EXTERNAL mechanism, the client's identity is taken from the validated SSL certificate, using the CNliteral>, and appending any DCliteral>s to create the domain. For instance, if the certificate contains the properties CN=bob, DC=acme, DC=com, the client's identity is bob."

This is definitely not enough for a user to get an understanding of what EXTERNAL mechanism is, who it is supposed to work and how to configure it. This should be described in much more details, with configuration examples and so on.

Comment 1 Joshua Wulf 2013-04-29 14:03:28 UTC
From the doc it's clear that EXTERNAL can be enabled by starting the broker with the switch --ssl-require-client-authentication.


However, the table in http://documentation-devel.engineering.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/2/html-single/Messaging_Installation_and_Configuration_Guide/index.html#SASL_Mechanisms_and_Packages does not have EXTERNAL in it as a setting for /etc/sasl2/qpidd.conf.

Question 1. Should this table have an entry to enable EXTERNAL SASL via /etc/sasl2/qpidd.conf? Or is it that the command line switch is the only way to enable it? Or is there a third way to enable it? 

There is a note that the Python client does not support SASL EXTERNAL in MRG 2.3, and must send the client name in the connection request. This implies that the Java, C++, and C# clients support EXTERNAL SASL authentication using the client's SSL certificate.

The Qpid 0.20 docs have EXTERNAL SASL support only for the C# client: http://qpid.apache.org/books/0.20/AMQP-Messaging-Broker-CPP-Book/html/QpidInteroperabilityDocumentation-QpidInteroperabilityDocumentation.html#QpidInteroperabilityDocumentation-SASL

Question 2. Do all the clients except the Python client (that is to say: the C++ client, the Java client, and the C# client) support SASL EXTERNAL auth?

Comment 2 Gordon Sim 2013-04-29 14:36:39 UTC
1. The /etc/sasl2/qpidd.conf would need to have EXTERNAL in the mech_list for EXTERNAL to be a valid mechanism.

2. The c++ and java clients support EXTERNAL and SSL based client-authentication. The c# client does not as far as I am aware (it is windows only and does not use Cyrus SASL).

Comment 3 Joshua Wulf 2013-04-29 16:06:15 UTC
Thanks Gordon. There is currently a note that the Windows C++ client does not support SASL.

"The Windows Qpid C++ client supports only ANONYMOUS and PLAIN authentication mechanisms.
This is likely to change in a future release."

http://documentation-devel.engineering.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/2/html-single/Messaging_Installation_and_Configuration_Guide/index.html#SASL_Support_in_Windows_Clients

Should that be C# client?

Comment 4 Gordon Sim 2013-04-29 16:40:08 UTC
It's both. The c# client is a wrapper on top of the windows based c++ client.

Comment 5 Joshua Wulf 2013-04-30 03:50:41 UTC
OK, is this correct?

EXTERNAL SASL Authentication

EXTERNAL SASL Authentication allows a client to authenticate using the identity encoded in the SSL certificate that the client uses to establish an SSL-encrypted connection to the server.

The Windows C++ and C# client do not support EXTERNAL SASL. The Python client does support EXTERNAL SASL Authentication, but must pass the identity of the client along with the connection request, as it cannot be read from the SSL certificate when using the Python client.

The identity of the client is established from the SSL certificate used to encrypt the connection with the broker when making the connection (or passed by the Python client), and is not validated against the local sasldb.

To enable EXTERNAL SASL authentication, include EXTERNAL in the mech_list in /etc/sasl2/qpidd.conf. If you start the broker with --ssl-require-client-authentication then EXTERNAL SASL will be enabled.



Questions: 
1. What happens if you start the broker with --ssl-require-client-authentication but without EXTERNAL in the mech_list?

2. What packages (if any) need to be installed to get EXTERNAL SASL to work?

3. If the Python client must pass the identity to the server, and it cannot be read from the SSL certificate, where's the security in that?

Comment 6 Gordon Sim 2013-05-01 13:01:20 UTC
Rather than "EXTERNAL SASL Authentication allows a client to authenticate using the identity encoded in the SSL certificate that the client uses to establish an SSL-encrypted connection to the server." I would say something like "EXTERNAL SASL Authentication relies only on the underlying SSL authentication - i.e. the fact that the clients certificate is valid and trusted by the server."

1. If EXTERNAL is not allowed method that will not be advertised by the server and the client won't be able to authenticate using that mechanism. (It doesn't stop SSL authentication taking place, it just doesn't allow that to be used in lieu of an explicit SASL authentication.

2. None. (Other than those for SSL of course).

3. The identity the server uses if EXTERNAL is chosen is taken from the certificate by the server itself. I believe the issue is that if the application requires the authenticated username (e.g. for inclusion in messages it sends) that must be supplied through configuration of the connection as it can't be deduced from the certificate (this is not sent to the server for the purposes of authentication).

Ken, can you confirm point 3 above?

Comment 7 Ken Giusti 2013-05-01 20:05:48 UTC
I've spent some time trying this out on the python client.

It appears that the username is taken from the URL used to connect to the broker.  AND this username must match the CommonName entry in the client certificate.

For example, if I create a certificate for my client like this:

certutil -R -d ${SERVER_CERT_DIR} -s "CN=Test-Client,O=MyCo,ST=California,C=US" -o client.req -f ${CERT_PW_FILE} -z /bin/sh
certutil -C -d ${CA_CERT_DIR} -c "Test-CA" -i client.req -o client.crt -f ${CERT_PW_FILE} -m ${RANDOM}
certutil -A -d ${SERVER_CERT_DIR} -n "Test-Client" -i client.crt -t "Pu,,"

The CN is "Test-Client".  I must use "Test-Client" in the URL as the username. Example:

 qpid-config -b amqps://Test-Client:54012 --ssl-certificate ./client_cert_key.pem  --sasl-mechanism EXTERNAL

(this name is then available to the python application via the Connection object's 'auth_name' member)

Trying to use a different name will fail:

qpid-config -b amqps://fleabag:54012 --ssl-certificate ./client_cert_key.pem  --sasl-mechanism EXTERNAL

Enter PEM pass phrase:password

Failed: ConnectionError: connection-forced: Authentication failed(320)


Does this make sense?

Comment 8 Gordon Sim 2013-05-01 20:24:40 UTC
What if you don't specify a username at all? Does it still fail?

So to expand/clarify the answer to question 3, the server will enforce the identity as it reads it from the certificate. The python client expects that identity to be set as the username in order for the auth_name member to be correct and it also appears to send that to the broker who then ensures it matches what was in the certificate or else fails the connection.

Comment 9 Ken Giusti 2013-05-02 12:35:06 UTC
Ah, good question - it -will- fail if no username is supplied in the URL:

[kgiusti@t530 SSL]$ qpid-config -b amqps://t530.localdomain:54012 --ssl-certificate ./client_cert_key.pem  --sasl-mechanism EXTERNAL
qpid-config -b amqps://t530.localdomain:54012 --ssl-certificate ./client_cert_key.pem  --sasl-mechanism EXTERNAL
USING PLAINCLIENT
Enter PEM pass phrase:password

Failed: ConnectionError: connection-forced: Authentication failed(320)

And my previous comment had an error - the Connection's has two members that it sets:

        print "USERNAME=%s" % self.conn.username
        print "AUTH_USERNAME=%s" % self.conn.auth_username

Connection.username is set to the username as it appears in the URL string.

Connection.auth_username is returned by the SASL library after the SASL handshake occurs.

From the tests I've run - I see that these values are always the same.

And, just to be complete - this is how I'm running the broker:

/home/kgiusti/work/qpid/build/trunk/src/qpidd --port 0 --config /home/kgiusti/work/qpid/build/trunk/src/tests/../../../../qpid/qpid/cpp/src/tests/config.null --load-module /home/kgiusti/work/qpid/build/trunk/src/.libs/ssl.so --ssl-cert-db ./server_db --ssl-cert-password-file ./cert.password --ssl-cert-name t530.localdomain --log-to-file ./BROKER.LOG --transport ssl --ssl-port 0 --require-encryption --ssl-require-client-authentication  --auth yes --sasl-config=/home/kgiusti/work/qpid/build/trunk/src/tests/sasl_config
2013-05-01 15:54:57 [Network] notice Listening on TCP/TCP6 port 40575
2013-05-01 15:54:57 [Security] notice Listening for SSL connections on TCP/TCP6 port 54012

And its qpidd.conf file:

pwcheck_method: auxprop
auxprop_plugin: sasldb
sasldb_path: /home/kgiusti/work/qpid/build/trunk/src/tests/sasl_config/qpidd.sasldb
sql_select: dummy select
mech_list: EXTERNAL

Comment 10 Joshua Wulf 2013-05-08 09:36:12 UTC
Thanks for the information Ken and Gordon.

Leonid, I've added some information here: http://documentation-devel.engineering.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/2/html-single/Messaging_Installation_and_Configuration_Guide/index.html#SASL_Mechanisms

I've also added it to this table: http://documentation-devel.engineering.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/2/html-single/Messaging_Installation_and_Configuration_Guide/index.html#SASL_Mechanisms_and_Packages

It doesn't require any sasl packages, because it uses SSL, but I added it to the table to raise its visibility as a SASL auth mechanism.

Comment 11 Leonid Zhaldybin 2013-05-21 10:27:34 UTC
The changes in the documentation seem to be sufficient.