diff options
author | Ted Ross <tross@apache.org> | 2009-11-11 17:33:33 +0000 |
---|---|---|
committer | Ted Ross <tross@apache.org> | 2009-11-11 17:33:33 +0000 |
commit | ea3ed931fde51d95416c8f25520908f170ef716b (patch) | |
tree | 1736b3e06ef3391b243b905b883792a40b3eba2d /python/qpid/delegates.py | |
parent | fe2b5f5849574d7281c16b6ba066ced2d25184e2 (diff) | |
download | qpid-python-ea3ed931fde51d95416c8f25520908f170ef716b.tar.gz |
Added full SASL authentication and security layer for the Python client.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@834975 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'python/qpid/delegates.py')
-rw-r--r-- | python/qpid/delegates.py | 78 |
1 files changed, 70 insertions, 8 deletions
diff --git a/python/qpid/delegates.py b/python/qpid/delegates.py index 14111a88df..8ebaff4ba3 100644 --- a/python/qpid/delegates.py +++ b/python/qpid/delegates.py @@ -20,11 +20,20 @@ import os, connection, session from util import notify from datatypes import RangedSet -from exceptions import VersionError +from exceptions import VersionError, Closed from logging import getLogger from ops import Control import sys +_have_sasl = None +try: + import qpidsasl + _have_sasl = True +except: + pass +finally: + pass + log = getLogger("qpid.io.ctl") class Delegate: @@ -152,13 +161,36 @@ class Client(Delegate): "qpid.client_pid": os.getpid(), "qpid.client_ppid": ppid} - def __init__(self, connection, username="guest", password="guest", - mechanism="PLAIN", heartbeat=None): + def __init__(self, connection, username=None, password=None, + mechanism=None, heartbeat=None, **kwargs): Delegate.__init__(self, connection) - self.username = username - self.password = password - self.mechanism = mechanism + + ## + ## self.acceptableMechanisms is the list of SASL mechanisms that the client is willing to + ## use. If it's None, then any mechanism is acceptable. + ## + self.acceptableMechanisms = None + if mechanism: + self.acceptableMechanisms = mechanism.split(" ") self.heartbeat = heartbeat + self.username = username + self.password = password + + if _have_sasl: + self.sasl = qpidsasl.Client() + if username and len(username) > 0: + self.sasl.setAttr("username", str(username)) + if password and len(password) > 0: + self.sasl.setAttr("password", str(password)) + if "service" in kwargs: + self.sasl.setAttr("service", str(kwargs["service"])) + if "host" in kwargs: + self.sasl.setAttr("host", str(kwargs["host"])) + if "min_ssf" in kwargs: + self.sasl.setAttr("minssf", kwargs["min_ssf"]) + if "max_ssf" in kwargs: + self.sasl.setAttr("maxssf", kwargs["max_ssf"]) + self.sasl.init() def start(self): # XXX @@ -171,14 +203,44 @@ class Client(Delegate): (cli_major, cli_minor, major, minor)) def connection_start(self, ch, start): - r = "\0%s\0%s" % (self.username, self.password) - ch.connection_start_ok(client_properties=Client.PROPERTIES, mechanism=self.mechanism, response=r) + mech_list = "" + for mech in start.mechanisms: + if (not self.acceptableMechanisms) or mech in self.acceptableMechanisms: + mech_list += str(mech) + " " + mech = None + initial = None + if _have_sasl: + status, mech, initial = self.sasl.start(mech_list) + if status == False: + raise Closed("SASL error: %s" % self.sasl.getError()) + else: + if self.username and self.password and ("PLAIN" in mech_list): + mech = "PLAIN" + initial = "\0%s\0%s" % (self.username, self.password) + else: + mech = "ANONYMOUS" + if not mech in mech_list: + raise Closed("No acceptable SASL authentication mechanism available") + ch.connection_start_ok(client_properties=Client.PROPERTIES, mechanism=mech, response=initial) + + def connection_secure(self, ch, secure): + resp = None + if _have_sasl: + status, resp = self.sasl.step(secure.challenge) + if status == False: + raise Closed("SASL error: %s" % self.sasl.getError()) + ch.connection_secure_ok(response=resp) def connection_tune(self, ch, tune): ch.connection_tune_ok(heartbeat=self.heartbeat) ch.connection_open() + if _have_sasl: + self.connection.user_id = self.sasl.getUserId() + self.connection.security_layer_tx = self.sasl def connection_open_ok(self, ch, open_ok): + if _have_sasl: + self.connection.security_layer_rx = self.sasl self.connection.opened = True notify(self.connection.condition) |