Add 'x-force-sasl' to the Connection's property map. This allows

clients to use the system's SASL configuration without having to
specify any extra SASL configuration options.
This commit is contained in:
Kenneth Giusti 2016-08-04 13:07:58 -04:00
parent 11fd6b8fa7
commit a0e579a267
2 changed files with 63 additions and 1 deletions

View File

@ -106,7 +106,7 @@ class Connection(Endpoint):
# set of all SASL connection configuration properties
_SASL_PROPS = set(['x-username', 'x-password', 'x-require-auth',
'x-sasl-mechs', 'x-sasl-config-dir',
'x-sasl-config-name'])
'x-sasl-config-name', 'x-force-sasl'])
def _not_reentrant(func):
"""Decorator that prevents callbacks from calling into methods that are
@ -162,6 +162,13 @@ class Connection(Endpoint):
x-sasl-config-name: string, name of the Cyrus SASL configuration file
contained in the x-sasl-config-dir (without the '.conf' suffix)
x-force-sasl: by default SASL authentication is disabled. SASL will be
enabled if any of the above x-sasl-* options are set. For clients using
GSSAPI it is likely none of these options will be set. In order for
these clients to authenticate this flag must be set true. The value of
this property is ignored if any of the other SASL related properties
are set.
x-ssl-identity: tuple, contains identifying certificate information
which will be presented to the peer. The first item in the tuple is
the path to the certificate file (PEM format). The second item is the
@ -249,6 +256,11 @@ class Connection(Endpoint):
self._pn_sasl = None
self._sasl_done = False
# if x-force-sasl is false remove it so it does not trigger the SASL
# configuration logic below
if not self._properties.get('x-force-sasl', True):
del self._properties['x-force-sasl']
if self._SASL_PROPS.intersection(set(self._properties.keys())):
# SASL config specified, need to enable SASL
if (_PROTON_VERSION < (0, 10)):

View File

@ -903,3 +903,53 @@ mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS
#
# NOTE WELL: Update TEST_COUNT as new test methods are added!!
#
class SASLTest(common.Test):
"""A test class to check SASL configuration flags.
"""
def setup(self):
super(SASLTest, self).setup()
# logging.getLogger("pyngus").setLevel(logging.DEBUG)
self.container1 = pyngus.Container("test-container-1")
def teardown(self):
if self.container1:
self.container1.destroy()
def _header_protocol(self, conn):
# fetch the protocol # from the AMQP header
conn.open()
conn.process(time.time())
assert conn.has_output >= 5, "header expected"
p = conn.output_data()[4]
try:
return ord(p) if isinstance(p, str) else int(p)
except:
assert False, "could not convert protocol"
def test_sasl_disabled(self):
"""Verify SASL is disabled when it is NOT configured.
"""
c1 = self.container1.create_connection("c1")
p = self._header_protocol(c1)
assert p == 0, "Bad protocol - expect '0' got '%s'" % p
def test_sasl_force(self):
"""Verify SASL is enabled if forced
"""
props = {'x-force-sasl': True}
c1 = self.container1.create_connection("c1",
properties=props)
p = self._header_protocol(c1)
assert p == 3, "Bad protocol - expect '3' got '%s'" % p
def test_sasl_force_false(self):
"""Verify setting x-force-sasl to False does not enable SASL.
"""
props = {'x-force-sasl': False}
c1 = self.container1.create_connection("c1",
properties=props)
p = self._header_protocol(c1)
assert p == 0, "Bad protocol - expect '0' got '%s'" % p