diff options
author | Jacek Konieczny <jajcus@jajcus.net> | 2008-08-08 15:22:14 +0400 |
---|---|---|
committer | Jacek Konieczny <jajcus@jajcus.net> | 2008-08-08 15:22:14 +0400 |
commit | 0907fd17101211dae5859b6aa9c6deb9ecd08b9d (patch) | |
tree | 89eff210b3b7f6fb2d647bced38e2b4a1585f12c /pyxmpp | |
parent | b94a4bf738bd78217bdd44a05a8a1535aa2de9ad (diff) |
- GSSAPI SASL support by Jelmer Vernooij
Diffstat (limited to 'pyxmpp')
-rw-r--r-- | pyxmpp/client.py | 2 | ||||
-rw-r--r-- | pyxmpp/sasl/__init__.py | 10 | ||||
-rw-r--r-- | pyxmpp/sasl/gssapi.py | 69 | ||||
-rw-r--r-- | pyxmpp/stream.py | 2 | ||||
-rw-r--r-- | pyxmpp/streamsasl.py | 2 |
5 files changed, 79 insertions, 6 deletions
diff --git a/pyxmpp/client.py b/pyxmpp/client.py index cb510e3..230e487 100644 --- a/pyxmpp/client.py +++ b/pyxmpp/client.py @@ -128,8 +128,6 @@ class Client: succeeds.""" if not self.jid: raise ClientError, "Cannot connect: no or bad JID given" - if not register and not self.password: - raise ClientError, "Cannot connect: no password given" self.lock.acquire() try: stream = self.stream diff --git a/pyxmpp/sasl/__init__.py b/pyxmpp/sasl/__init__.py index e9a6be3..d26f79c 100644 --- a/pyxmpp/sasl/__init__.py +++ b/pyxmpp/sasl/__init__.py @@ -31,6 +31,12 @@ from pyxmpp.sasl.plain import PlainClientAuthenticator,PlainServerAuthenticator from pyxmpp.sasl.digest_md5 import DigestMD5ClientAuthenticator,DigestMD5ServerAuthenticator safe_mechanisms_dict={"DIGEST-MD5":(DigestMD5ClientAuthenticator,DigestMD5ServerAuthenticator)} +try: + from pyxmpp.sasl.gssapi import GSSAPIClientAuthenticator +except ImportError: + pass # Kerberos not available +else: + safe_mechanisms_dict["GSSAPI"] = (GSSAPIClientAuthenticator,None) unsafe_mechanisms_dict={"PLAIN":(PlainClientAuthenticator,PlainServerAuthenticator)} all_mechanisms_dict=safe_mechanisms_dict.copy() all_mechanisms_dict.update(unsafe_mechanisms_dict) @@ -44,7 +50,7 @@ def client_authenticator_factory(mechanism,password_manager): password manager. :Parameters: - - `mechanism`: name of the SASL mechanism ("PLAIN" or "DIGEST-MD5"). + - `mechanism`: name of the SASL mechanism ("PLAIN", "DIGEST-MD5" or "GSSAPI"). - `password_manager`: name of the password manager object providing authentication credentials. :Types: @@ -61,7 +67,7 @@ def server_authenticator_factory(mechanism,password_manager): password manager. :Parameters: - - `mechanism`: name of the SASL mechanism ("PLAIN" or "DIGEST-MD5"). + - `mechanism`: name of the SASL mechanism ("PLAIN", "DIGEST-MD5" or "GSSAPI"). - `password_manager`: name of the password manager object to be used for authentication credentials verification. :Types: diff --git a/pyxmpp/sasl/gssapi.py b/pyxmpp/sasl/gssapi.py new file mode 100644 index 0000000..913b162 --- /dev/null +++ b/pyxmpp/sasl/gssapi.py @@ -0,0 +1,69 @@ +# +# (C) Copyright 2008 Jelmer Vernooij <jelmer@samba.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License Version +# 2.1 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +"""GSSAPI authentication mechanism for PyXMPP SASL implementation. + +Normative reference: + - `RFC 4752 <http://www.ietf.org/rfc/rfc4752.txt>`__ +""" + +__revision__="$Id$" +__docformat__="restructuredtext en" + +import base64 +import kerberos + +import logging + +from pyxmpp.sasl.core import (ClientAuthenticator,Failure,Response,Challenge,Success) + +class GSSAPIClientAuthenticator(ClientAuthenticator): + """Provides client-side GSSAPI SASL (Kerberos 5) authentication.""" + + def __init__(self,password_manager): + ClientAuthenticator.__init__(self, password_manager) + self.password_manager = password_manager + self.__logger = logging.getLogger("pyxmpp.sasl.gssapi.GSSAPIClientAuthenticator") + + def start(self, username, authzid): + self.username = username + self.authzid = authzid + rc, self._gss = kerberos.authGSSClientInit(authzid or "%s@%s" % ("xmpp", self.password_manager.get_serv_host())) + self.step = 0 + return self.challenge("") + + def challenge(self, challenge): + if self.step == 0: + rc = kerberos.authGSSClientStep(self._gss, base64.b64encode(challenge)) + if rc != kerberos.AUTH_GSS_CONTINUE: + self.step = 1 + elif self.step == 1: + rc = kerberos.authGSSClientUnwrap(self._gss, base64.b64encode(challenge)) + response = kerberos.authGSSClientResponse(self._gss) + rc = kerberos.authGSSClientWrap(self._gss, response, self.username) + response = kerberos.authGSSClientResponse(self._gss) + if response is None: + return Response("") + else: + return Response(base64.b64decode(response)) + + def finish(self, data): + self.username = kerberos.authGSSClientUserName(self._gss) + self.__logger.debug("Authenticated as %s" % kerberos.authGSSClientUserName(self._gss)) + return Success(self.username,None,self.authzid) + + +# vi: sts=4 et sw=4 diff --git a/pyxmpp/stream.py b/pyxmpp/stream.py index 813a490..6941431 100644 --- a/pyxmpp/stream.py +++ b/pyxmpp/stream.py @@ -63,7 +63,7 @@ class Stream(StreamTLSMixIn,StreamSASLMixIn,StreamBase): - `extra_ns`: sequence of extra namespace URIs to be defined for the stream. - `sasl_mechanisms`: sequence of SASL mechanisms allowed for - authentication. Currently "PLAIN" and "DIGEST-MD5" are supported. + authentication. Currently "PLAIN", "DIGEST-MD5" and "GSSAPI" are supported. - `tls_settings`: settings for StartTLS -- `TLSSettings` instance. - `keepalive`: keepalive output interval. 0 to disable. - `owner`: `Client`, `Component` or similar object "owning" this stream. diff --git a/pyxmpp/streamsasl.py b/pyxmpp/streamsasl.py index ff7e9ba..1997500 100644 --- a/pyxmpp/streamsasl.py +++ b/pyxmpp/streamsasl.py @@ -41,7 +41,7 @@ class StreamSASLMixIn(sasl.PasswordManager): :Parameters: - `sasl_mechanisms`: sequence of SASL mechanisms allowed for - authentication. Currently "PLAIN" and "DIGEST-MD5" are supported. + authentication. Currently "PLAIN", "DIGEST-MD5" and "GSSAPI" are supported. """ sasl.PasswordManager.__init__(self) if sasl_mechanisms: |