Bug 1038586 - Python client SSL authentication passes when "ssl_skip_hostname_check" is "false" and "ssl_trustfile" is not given
Summary: Python client SSL authentication passes when "ssl_skip_hostname_check" is "fa...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: python-qpid
Version: Development
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: 3.1
: ---
Assignee: Ernie
QA Contact: Petra Svobodová
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2013-12-05 12:26 UTC by Petra Svobodová
Modified: 2015-04-14 13:47 UTC (History)
5 users (show)

Fixed In Version: python-qpid-0.30-2
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-04-14 13:47:13 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
bz reproducer (7.04 KB, text/x-python)
2013-12-05 12:32 UTC, Petra Svobodová
no flags Details
Assume if skip_hostname_check is set to false, user wants ssl (521 bytes, patch)
2014-07-14 16:15 UTC, Ernie
no flags Details | Diff
Distinguish between the default value of ssl_skip_hostname_check and manually setting the value to false (1.42 KB, patch)
2014-07-16 16:54 UTC, Ernie
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Apache JIRA QPID-5894 0 None None None Never
Red Hat Product Errata RHEA-2015:0805 0 normal SHIPPED_LIVE Red Hat Enterprise MRG Messaging 3.1 Release 2015-04-14 17:45:54 UTC

Description Petra Svobodová 2013-12-05 12:26:16 UTC
Description of problem:
Qpid python client should verify broker hostname against the server certificate before connecting the broker, if "ssl_skip_hostname_check" was set to "false" value.
In case "ssl_trustfile" is set correctly, verification succeeds; if the "ssl_trustfile" is an invalid file, verification fails (this behavior seems to be right).
However if "ssl_trustfile" is not given (and "ssl_skip_hostname_check" has still value "false"), the hostname verification against the server certificate is successful too, although there is no given certificate to authenticate the remote server.

Version-Release number of selected component (if applicable):
# rpm -qa | grep qpid
qpid-java-common-0.23-4.el6.noarch
qpid-cpp-client-devel-0.22-29.el6.i686
rh-qpid-cpp-tests-0.22-29.el6.i686
qpid-java-amqp-0-10-client-jms-0.23-4.el6.noarch
qpid-qmf-0.22-24.el6.i686
qpid-cpp-server-rdma-0.22-29.el6.i686
qpid-java-example-0.23-4.el6.noarch
qpid-snmpd-1.0.0-14.el6.i686
qpid-cpp-client-0.22-29.el6.i686
python-qpid-qmf-0.22-24.el6.i686
qpid-cpp-server-devel-0.22-29.el6.i686
ruby-qpid-qmf-0.22-24.el6.i686
qpid-cpp-server-xml-0.22-29.el6.i686
qpid-java-client-0.23-4.el6.noarch
qpid-jca-0.22-1.el6.noarch
qpid-proton-c-devel-0.5-9.el6.i686
qpid-cpp-client-devel-docs-0.22-29.el6.noarch
qpid-cpp-client-rdma-0.22-29.el6.i686
qpid-cpp-debuginfo-0.22-16.el6.i686
qpid-tools-0.22-7.el6.noarch
qpid-cpp-server-store-0.22-29.el6.i686
perl-qpid-0.22-7.el6.i686
qpid-jca-xarecovery-0.22-1.el6.noarch
qpid-proton-c-0.5-9.el6.i686
qpid-cpp-server-0.22-29.el6.i686
qpid-cpp-server-ssl-0.22-29.el6.i686
python-qpid-0.22-8.el6.noarch
qpid-cpp-client-ssl-0.22-29.el6.i686
qpid-cpp-server-ha-0.22-29.el6.i686

How reproducible:
100%

Steps to Reproduce:
1. Generate "client.pem" certificate.
2. Run a broker over SSL.
3. Try to send a message; you can use the attached reproducer:
./qc2_spout.py  --broker <hostname>:5671 --connection-options "{  username : 'guest', ssl_certfile : <path_to_client.pem>, protocol : 'amqp0-10', sasl_mechanisms : 'DIGEST-MD5', ssl_skip_hostname_check : 'false', password : 'guest', transport : 'ssl' }" --count 1 --sync-mode None "amq.topic;{}"

Actual results:
The client connects the broker.

Expected results:
The client should fail due to unsuccessful server hostname verification.

Additional info:
Broker configuration:

ssl-require-client-authentication=yes
data-dir=/var/lib/qpidd
log-to-file=/var/lib/qpidd/qpidd.log
ssl-cert-name=server
auth=yes
acl-file=/etc/qpid/qpidd.acl
log-enable=info+
ssl-cert-password-file=<path_to_the_password_file>
port=5672
ssl-port=5671
ssl-cert-db=<path_to_the_certdb>

Comment 1 Petra Svobodová 2013-12-05 12:32:35 UTC
Created attachment 833118 [details]
bz reproducer

Try to send a message: 
./spout.py  --broker <hostname>:5671 --connection-options "{  username : 'guest', ssl_certfile : <path_to_client.pem>, protocol : 'amqp0-10', sasl_mechanisms : 'DIGEST-MD5', ssl_skip_hostname_check : 'false', password : 'guest', transport : 'ssl' }" --count 1 "amq.topic;{}"

Comment 2 Justin Ross 2013-12-10 20:05:48 UTC
Ken, please assess.

Comment 3 Ken Giusti 2013-12-10 21:09:48 UTC
According to the python docs: 


"The parameter cert_reqs specifies whether a certificate is required from the other side of the connection, and whether it will be validated if provided. It must be one of the three values CERT_NONE (certificates ignored), CERT_OPTIONAL (not required, but validated if provided), or CERT_REQUIRED (required and validated). If the value of this parameter is not CERT_NONE, then the ca_certs parameter [our ssl_trustfile parameter] must point to a file of CA certificates."

We support only CERT_NONE (if no ssl_trustfile given) or CERT_REQUIRED (ssl_trustfile given).  CERT_OPTIONAL is a security risk, and is not used.

So our python client only receives the cert containing a hostname if ssl_trustfile is given.  In other words, if ssl_trustfile is not given, then there will not be a hostname available to validate.

But the behavior as described above can be confusing.  Perhaps a warning should be logged if a user does not supply an ssl_trustfile and explicitly states "skip_hostname_check" == False (as opposed to not providing the parameter - as the default is _False_ anyways)

As far a security is concerned: if no ssl_trustfile is given, checking the hostname would provide a false sense of security.  Without a valid ssl_trustfile, nothing can be securely verified.

Comment 6 Ernie 2014-07-14 16:15:01 UTC
Created attachment 917919 [details]
Assume if skip_hostname_check is set to false, user wants ssl

Proposed patch. If the user has explicitly set the skip_hostname_check flag to false, assume they want a secure connection. 

If the trustfile is not also given, then a "qpid.messaging.exceptions.ConnectError: [Errno 111] Connection refused" is raised.

Comment 7 Ernie 2014-07-14 16:17:57 UTC
Ken, can you review the attached patch. If you concur that we should raise an exception when skip_hostname_check is explicitly set to false and no trustfile is given, then can you commit the patch upstream per Justin's request?

Comment 9 Ernie 2014-07-16 16:54:42 UTC
Created attachment 918475 [details]
Distinguish between the default value of ssl_skip_hostname_check and manually setting the value to false

New patch that only raises an exception if the user explicitly sets the flag, as opposed to the flag getting the default value.

Comment 13 Petra Svobodová 2015-01-20 12:10:36 UTC
Qpid python client requires to have a path to the certification authority's certificate and tries to verify the server certificate before connecting the broker, if "ssl_skip_hostname_check" was set to "false" value.

Verified on Rhel6.6-i686 and x86_64 on package python-qpid-0.30-3.

--> VERIFIED

Comment 15 errata-xmlrpc 2015-04-14 13:47:13 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHEA-2015-0805.html


Note You need to log in before you can comment on or make changes to this bug.