Author: js Date: 2009-01-10 22:56:21 +0100 (Sat, 10 Jan 2009) New Revision: 10960
Added: branches/osx_newbuildsys/src/common/xmpp/plugin.py Removed: branches/osx_newbuildsys/src/common/xmpp/client.py Modified: branches/osx_newbuildsys/src/common/connection_handlers.py branches/osx_newbuildsys/src/common/helpers.py branches/osx_newbuildsys/src/common/socks5.py branches/osx_newbuildsys/src/common/xmpp/Makefile branches/osx_newbuildsys/src/common/xmpp/__init__.py branches/osx_newbuildsys/src/common/xmpp/auth_nb.py branches/osx_newbuildsys/src/common/xmpp/bosh.py branches/osx_newbuildsys/src/common/xmpp/c14n.py branches/osx_newbuildsys/src/common/xmpp/client_nb.py branches/osx_newbuildsys/src/common/xmpp/dispatcher_nb.py branches/osx_newbuildsys/src/common/xmpp/proxy_connectors.py branches/osx_newbuildsys/src/common/xmpp/roster_nb.py branches/osx_newbuildsys/src/common/xmpp/tls_nb.py branches/osx_newbuildsys/src/common/xmpp/transports_nb.py branches/osx_newbuildsys/src/common/zeroconf/client_zeroconf.py branches/osx_newbuildsys/src/conversation_textview.py branches/osx_newbuildsys/src/roster_window.py Log: Merge trunk r10945. Rest follows later.
Modified: branches/osx_newbuildsys/src/common/connection_handlers.py =================================================================== --- branches/osx_newbuildsys/src/common/connection_handlers.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/connection_handlers.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -30,10 +30,10 @@
import os import base64 -import sha import socket import sys import operator +import hashlib
from time import (altzone, daylight, gmtime, localtime, mktime, strftime, time as time_time, timezone, tzname) @@ -1049,7 +1049,7 @@ photo = vcard['PHOTO']['BINVAL'] photo_decoded = base64.decodestring(photo) gajim.interface.save_avatar_files(our_jid, photo_decoded) - avatar_sha = sha.sha(photo_decoded).hexdigest() + avatar_sha = hashlib.sha1(photo_decoded).hexdigest() iq2.getTag('PHOTO').setTagData('SHA', avatar_sha) else: gajim.interface.remove_avatar_files(our_jid) @@ -1205,7 +1205,7 @@ photo = vcard['PHOTO']['BINVAL'] try: photo_decoded = base64.decodestring(photo) - avatar_sha = sha.sha(photo_decoded).hexdigest() + avatar_sha = hashlib.sha1(photo_decoded).hexdigest() except Exception: avatar_sha = '' else:
Modified: branches/osx_newbuildsys/src/common/helpers.py =================================================================== --- branches/osx_newbuildsys/src/common/helpers.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/helpers.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -38,6 +38,8 @@ import select import base64 import sys +import hashlib + from encodings.punycode import punycode_encode
import gajim @@ -46,18 +48,6 @@ import xmpp
try: - # Python 2.5 - import hashlib - hash_md5 = hashlib.md5 - hash_sha1 = hashlib.sha1 -except ImportError: - # Python 2.4 - import md5 - import sha - hash_md5 = md5.new - hash_sha1 = sha.new - -try: from osx import nsapp except ImportError: pass @@ -731,7 +721,7 @@
def get_auth_sha(sid, initiator, target): ''' return sha of sid + initiator + target used for proxy auth''' - return hash_sha1("%s%s%s" % (sid, initiator, target)).hexdigest() + return hashlib.sha1("%s%s%s" % (sid, initiator, target)).hexdigest()
distro_info = { @@ -847,7 +837,7 @@ latin characters, and is not too long (in that case hash it)''' # 48 is the limit if len(filename) > 48: - hash = hash_md5(filename) + hash = hashlib.md5(filename) filename = base64.b64encode(hash.digest())
filename = punycode_encode(filename) # make it latin chars only @@ -1250,9 +1240,9 @@ S += '%s<' % value
if hash_method == 'sha-1': - hash_ = hash_sha1(S) + hash_ = hashlib.sha1(S) elif hash_method == 'md5': - hash_ = hash_md5(S) + hash_ = hashlib.md5(S) else: return '' return base64.b64encode(hash_.digest())
Modified: branches/osx_newbuildsys/src/common/socks5.py =================================================================== --- branches/osx_newbuildsys/src/common/socks5.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/socks5.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -25,7 +25,7 @@ import os import socket import struct -import sha +import hashlib import os
from errno import EWOULDBLOCK @@ -645,9 +645,10 @@ ''' get sha of sid + Initiator jid + Target jid ''' if 'is_a_proxy' in self.file_props: del(self.file_props['is_a_proxy']) - return sha.new('%s%s%s' % (self.sid, self.file_props['proxy_sender'], + return hashlib.sha1('%s%s%s' % (self.sid, + self.file_props['proxy_sender'], self.file_props['proxy_receiver'])).hexdigest() - return sha.new('%s%s%s' % (self.sid, self.initiator, self.target)).\ + return hashlib.sha1('%s%s%s' % (self.sid, self.initiator, self.target)).\ hexdigest()
class Socks5Sender(Socks5, IdleObject):
Modified: branches/osx_newbuildsys/src/common/xmpp/Makefile =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/Makefile 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/Makefile 2009-01-10 21:56:21 UTC (rev 10960) @@ -2,11 +2,11 @@ auth_nb.py \ bosh.py \ c14n.py \ - client.py \ client_nb.py \ dispatcher_nb.py \ features_nb.py \ idlequeue.py \ + plugin.py \ protocol.py \ proxy_connectors.py \ roster_nb.py \
Modified: branches/osx_newbuildsys/src/common/xmpp/__init__.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/__init__.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/__init__.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -13,7 +13,7 @@ import simplexml, protocol, auth_nb, transports_nb, roster_nb import dispatcher_nb, features_nb, idlequeue, bosh, tls_nb, proxy_connectors from client_nb import NonBlockingClient -from client import PlugIn +from plugin import PlugIn from protocol import *
# vim: se ts=3:
Modified: branches/osx_newbuildsys/src/common/xmpp/auth_nb.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/auth_nb.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/auth_nb.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -21,19 +21,18 @@ ''' from protocol import NS_SASL, NS_SESSION, NS_STREAMS, NS_BIND, NS_AUTH from protocol import Node, NodeProcessed, isResultNode, Iq, Protocol, JID -from client import PlugIn -import sha +from plugin import PlugIn import base64 import random import itertools import dispatcher_nb -import md5 +import hashlib
import logging log = logging.getLogger('gajim.c.x.auth_nb')
-def HH(some): return md5.new(some).hexdigest() -def H(some): return md5.new(some).digest() +def HH(some): return hashlib.md5(some).hexdigest() +def H(some): return hashlib.md5(some).digest() def C(some): return ':'.join(some)
try: @@ -128,7 +127,7 @@ self.password = password self.on_sasl = on_sasl self.realm = None - + def plugin(self, owner): if 'version' not in self._owner.Dispatcher.Stream._document_attrs: self.startsasl = SASL_UNSUPPORTED @@ -256,8 +255,8 @@ # Openfire) old_features = self._owner.Dispatcher.Stream.features self._owner.Dispatcher.PlugOut() - dispatcher_nb.Dispatcher().PlugIn(self._owner, after_SASL=True, - old_features=old_features) + dispatcher_nb.Dispatcher.get_instance().PlugIn(self._owner, + after_SASL=True, old_features=old_features) self._owner.Dispatcher.restoreHandlers(handlers) self._owner.User = self.username
@@ -372,8 +371,8 @@ if query.getTag('digest'): log.info("Performing digest authentication") query.setTagData('digest', - sha.new(self.owner.Dispatcher.Stream._document_attrs['id'] + - self.password).hexdigest()) + hashlib.sha1(self.owner.Dispatcher.Stream._document_attrs['id'] + + self.password).hexdigest()) if query.getTag('password'): query.delChild('password') self._method = 'digest' @@ -383,7 +382,7 @@ log.info("Performing zero-k authentication")
def hasher(s): - return sha.new(s).hexdigest() + return hashlib.sha1(s).hexdigest()
def hash_n_times(s, count): return count and hasher(hash_n_times(s, count-1)) or s
Modified: branches/osx_newbuildsys/src/common/xmpp/bosh.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/bosh.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/bosh.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -18,7 +18,8 @@ ## along with Gajim. If not, see http://www.gnu.org/licenses/.
-import locale, random, sha +import locale, random +from hashlib import sha1 from transports_nb import NonBlockingTransport, NonBlockingHTTPBOSH,\ CONNECTED, CONNECTING, DISCONNECTED, DISCONNECTING,\ urisplit, DISCONNECT_TIMEOUT_SECONDS @@ -527,10 +528,10 @@
def reset(self): seed = str(get_rand_number()) - self.keys = [sha.new(seed).hexdigest()] + self.keys = [sha1(seed).hexdigest()] for i in range(self.count-1): curr_seed = self.keys[i] - self.keys.append(sha.new(curr_seed).hexdigest()) + self.keys.append(sha1(curr_seed).hexdigest())
def get(self): if self.first_call:
Modified: branches/osx_newbuildsys/src/common/xmpp/c14n.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/c14n.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/c14n.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -1,6 +1,5 @@ -''' XML canonicalisation methods (for XEP-0116) ''' # -*- coding:utf-8 -*- -## src/common/stanza_session.py +## c14n.py ## ## Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com> ## @@ -18,6 +17,8 @@ ## You should have received a copy of the GNU General Public License ## along with Gajim. If not, see http://www.gnu.org/licenses/. ## + +''' XML canonicalisation methods (for XEP-0116) ''' from simplexml import ustr
def c14n(node):
Deleted: branches/osx_newbuildsys/src/common/xmpp/client.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/client.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/client.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -1,86 +0,0 @@ -## client.py -## -## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2, or (at your option) -## any later version. -## -## 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 General Public License for more details. - -# $Id: client.py,v 1.52 2006/01/02 19:40:55 normanr Exp $ - -''' -Provides PlugIn class functionality to develop extentions for xmpppy. -''' - -import logging -log = logging.getLogger('gajim.c.x.plugin') - -class PlugIn: - ''' - Abstract xmpppy plugin infrastructure code, providing plugging in/out and - debugging functionality. - - Inherit to develop pluggable objects. No code change on the owner class - required (the object where we plug into) - - For every instance of PlugIn class the 'owner' is the class in what the plug - was plugged. - ''' - def __init__(self): - self._exported_methods=[] - - def PlugIn(self, owner): - ''' - Attach to owner and register ourself and our _exported_methods in it. - If defined by a subclass, call self.plugin(owner) to execute hook - code after plugging. - ''' - self._owner=owner - log.info('Plugging %s __INTO__ %s' % (self, self._owner)) - if self.__class__.__name__ in owner.__dict__: - log.debug('Plugging ignored: another instance already plugged.') - return - self._old_owners_methods=[] - for method in self._exported_methods: - if method.__name__ in owner.__dict__: - self._old_owners_methods.append(owner.__dict__[method.__name__]) - owner.__dict__[method.__name__]=method - if self.__class__.__name__.endswith('Dispatcher'): - # FIXME: I need BOSHDispatcher or XMPPDispatcher on .Dispatcher - # there must be a better way.. - owner.__dict__['Dispatcher']=self - else: - owner.__dict__[self.__class__.__name__]=self - - # Execute hook - if hasattr(self,'plugin'): - return self.plugin(owner) - - def PlugOut(self): - ''' - Unregister our _exported_methods from owner and detach from it. - If defined by a subclass, call self.plugout() after unplugging to execute - hook code. - ''' - log.info('Plugging %s __OUT__ of %s.' % (self, self._owner)) - for method in self._exported_methods: - del self._owner.__dict__[method.__name__] - for method in self._old_owners_methods: - self._owner.__dict__[method.__name__]=method - # FIXME: Dispatcher workaround - if self.__class__.__name__.endswith('Dispatcher'): - del self._owner.__dict__['Dispatcher'] - else: - del self._owner.__dict__[self.__class__.__name__] - # Execute hook - if hasattr(self,'plugout'): - return self.plugout() - del self._owner - -# vim: se ts=3:
Modified: branches/osx_newbuildsys/src/common/xmpp/client_nb.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/client_nb.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/client_nb.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -1,6 +1,5 @@ ## client_nb.py ## based on client.py, changes backported up to revision 1.60 - ## ## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov ## modified by Dimitur Kirov dkirov@gmail.com @@ -21,9 +20,7 @@ Client class establishs connection to XMPP Server and handles authentication ''' import socket - import transports_nb, dispatcher_nb, auth_nb, roster_nb, protocol, bosh - from protocol import NS_TLS
import logging @@ -120,7 +117,7 @@ if not stream_started: # if error occur before XML stream was opened, e.g. no response on # init request, we call the on_connect_failure callback because - # proper connection is not estabilished yet and it's not a proxy + # proper connection is not established yet and it's not a proxy # issue log.debug('calling on_connect_failure cb') self.on_connect_failure() @@ -146,15 +143,15 @@ values for keys 'host' and 'port' - connection details for proxy serve and optionally keys 'user' and 'pass' as proxy credentials :param secure_tuple: tuple of (desired connection type, cacerts, mycerts) - connection type can be 'ssl' - TLS estabilished after TCP connection, - 'tls' - TLS estabilished after negotiation with starttls, or 'plain'. + connection type can be 'ssl' - TLS established after TCP connection, + 'tls' - TLS established after negotiation with starttls, or 'plain'. cacerts, mycerts - see tls_nb.NonBlockingTLS constructor for more details ''' self.on_connect = on_connect self.on_connect_failure=on_connect_failure self.on_proxy_failure = on_proxy_failure - self.secure, self.cacerts, self.mycerts = secure_tuple + self.desired_security, self.cacerts, self.mycerts = secure_tuple self.Connection = None self.Port = port self.proxy = proxy @@ -163,8 +160,12 @@ self.xmpp_hostname = hostname else: self.xmpp_hostname = self.Server - - estabilish_tls = self.secure == 'ssl' + + # We only check for SSL here as for TLS we will first have to start a + # PLAIN connection and negotiate TLS afterwards. + # establish_tls will instruct transport to start secure connection + # directly + establish_tls = self.desired_security == 'ssl' certs = (self.cacerts, self.mycerts)
proxy_dict = {} @@ -181,16 +182,16 @@ if proxy['type'] == 'bosh': # Setup BOSH transport - self.socket = bosh.NonBlockingBOSH( - on_disconnect = self.disconnect, - raise_event = self.raise_event, - idlequeue = self.idlequeue, - estabilish_tls = estabilish_tls, - certs = certs, - proxy_creds = (proxy_user, proxy_pass), - xmpp_server = (self.xmpp_hostname, self.Port), - domain = self.Server, - bosh_dict = proxy) + self.socket = bosh.NonBlockingBOSH.get_instance( + on_disconnect=self.disconnect, + raise_event=self.raise_event, + idlequeue=self.idlequeue, + estabilish_tls=establish_tls, + certs=certs, + proxy_creds=(proxy_user, proxy_pass), + xmpp_server=(self.xmpp_hostname, self.Port), + domain=self.Server, + bosh_dict=proxy) self.protocol_type = 'BOSH' self.wait_for_restart_response = \ proxy['bosh_wait_for_restart_response'] @@ -202,13 +203,13 @@
if not proxy or proxy['type'] != 'bosh': # Setup ordinary TCP transport - self.socket = transports_nb.NonBlockingTCP( - on_disconnect = self.disconnect, - raise_event = self.raise_event, - idlequeue = self.idlequeue, - estabilish_tls = estabilish_tls, - certs = certs, - proxy_dict = proxy_dict) + self.socket = transports_nb.NonBlockingTCP.get_instance( + on_disconnect=self.disconnect, + raise_event=self.raise_event, + idlequeue=self.idlequeue, + estabilish_tls=establish_tls, + certs=certs, + proxy_dict=proxy_dict)
# plug transport into client as self.Connection self.socket.PlugIn(self) @@ -221,8 +222,8 @@ def _resolve_hostname(self, hostname, port, on_success): ''' wrapper for getaddinfo call. FIXME: getaddinfo blocks''' try: - self.ip_addresses = socket.getaddrinfo(hostname,port, - socket.AF_UNSPEC,socket.SOCK_STREAM) + self.ip_addresses = socket.getaddrinfo(hostname, port, + socket.AF_UNSPEC, socket.SOCK_STREAM) except socket.gaierror, (errnum, errstr): self.disconnect(message='Lookup failure for %s:%s, hostname: %s - %s' % (self.Server, self.Port, hostname, errstr)) @@ -241,7 +242,7 @@ self.current_ip = self.ip_addresses.pop(0) self.socket.connect( conn_5tuple=self.current_ip, - on_connect=lambda: self._xmpp_connect(socket_type='plain'), + on_connect=lambda: self._xmpp_connect(), on_connect_failure=self._try_next_ip)
def incoming_stream_version(self): @@ -251,14 +252,20 @@ else: return None
- def _xmpp_connect(self, socket_type): + def _xmpp_connect(self, socket_type=None): ''' Starts XMPP connecting process - opens the XML stream. Is called after TCP - connection is estabilished or after switch to TLS when successfully + connection is established or after switch to TLS when successfully negotiated with <starttls>. ''' - if socket_type == 'plain' and self.Connection.ssl_lib: - socket_type = 'ssl' + # socket_type contains info which transport connection was established + if not socket_type: + if self.Connection.ssl_lib: + # When ssl_lib is set we connected via SSL + socket_type = 'ssl' + else: + # PLAIN is default + socket_type = 'plain' self.connected = socket_type self._xmpp_connect_machine()
@@ -287,7 +294,7 @@ if self.__dict__.has_key('Dispatcher'): self.Dispatcher.PlugOut() self.got_features = False - d = dispatcher_nb.Dispatcher().PlugIn(self) + dispatcher_nb.Dispatcher.get_instance().PlugIn(self) on_next_receive('RECEIVE_DOCUMENT_ATTRIBUTES')
elif mode == 'FAILURE': @@ -307,7 +314,6 @@ else: log.info('got STREAM FEATURES in first recv') self._xmpp_connect_machine(mode='STREAM_STARTED') - else: log.info('incoming stream version less than 1.0') self._xmpp_connect_machine(mode='STREAM_STARTED') @@ -330,32 +336,35 @@
def _on_stream_start(self): ''' - Called after XMPP stream is opened. - TLS negotiation may follow when stream is established. + Called after XMPP stream is opened. TLS negotiation may follow if + supported and desired. ''' self.stream_started = True self.onreceive(None) + if self.connected == 'plain': - if self.secure == 'plain': - # if we want plain connection, we're done now + if self.desired_security == 'plain': + # if we want and have plain connection, we're done now self._on_connect() - return - if self.incoming_stream_version() != '1.0': - # if stream version is less than 1.0, we can't do more - log.warn('While connecting with type = "tls": stream version is less than 1.0') - self._on_connect() - return - if not self.Dispatcher.Stream.features.getTag('starttls'): - # if server doesn't advertise TLS in init response, we can't do more - log.warn('While connecting with type = "tls": TLS unsupported by remote server') - self._on_connect() - return - # otherwise start TLS negotioation - self.stream_started = False - log.info("TLS supported by remote server. Requesting TLS start.") - self._tls_negotiation_handler() + else: + # try to negotiate TLS + if self.incoming_stream_version() != '1.0': + # if stream version is less than 1.0, we can't do more + log.warn('While connecting with type = "tls": stream version is less than 1.0') + self._on_connect() + return + if self.Dispatcher.Stream.features.getTag('starttls'): + # Server advertises TLS support, start negotiation + self.stream_started = False + log.info('TLS supported by remote server. Requesting TLS start.') + self._tls_negotiation_handler() + else: + log.warn('While connecting with type = "tls": TLS unsupported by remote server') + self._on_connect() + elif self.connected in ['ssl', 'tls']: self._on_connect() + assert False # should never be reached
def _tls_negotiation_handler(self, con=None, tag=None): ''' takes care of TLS negotioation with <starttls> ''' @@ -374,7 +383,7 @@ return tagname = tag.getName() if tagname == 'failure': - self.disconnect('TLS <failure> received: %s' % tag) + self.disconnect('TLS <failure> received: %s' % tag) return log.info('Got starttls proceed response. Switching to TLS/SSL...') # following call wouldn't work for BOSH transport but it doesn't matter @@ -439,13 +448,13 @@ def _on_doc_attrs(self): ''' Plug authentication objects and start auth. ''' if self._sasl: - auth_nb.SASL(self._User, self._Password, + auth_nb.SASL.get_instance(self._User, self._Password, self._on_start_sasl).PlugIn(self) if not self._sasl or self.SASL.startsasl == 'not-supported': if not self._Resource: self._Resource = 'xmpppy' - auth_nb.NonBlockingNonSASL(self._User, self._Password, self._Resource, - self._on_old_auth).PlugIn(self) + auth_nb.NonBlockingNonSASL.get_instance(self._User, self._Password, + self._Resource, self._on_old_auth).PlugIn(self) return self.SASL.auth() return True @@ -464,10 +473,10 @@ # wrong user/pass, stop auth if 'SASL' in self.__dict__: self.SASL.PlugOut() - self.connected = None + self.connected = None # FIXME: is this intended? self._on_sasl_auth(None) elif self.SASL.startsasl == 'success': - auth_nb.NonBlockingBind().PlugIn(self) + auth_nb.NonBlockingBind.get_instance().PlugIn(self) self.onreceive(self._on_auth_bind) return True @@ -483,7 +492,7 @@ def initRoster(self): ''' Plug in the roster. ''' if not self.__dict__.has_key('NonBlockingRoster'): - roster_nb.NonBlockingRoster().PlugIn(self) + roster_nb.NonBlockingRoster.get_instance().PlugIn(self)
def getRoster(self, on_ready=None): ''' Return the Roster instance, previously plugging it in and @@ -497,7 +506,7 @@ Can also request roster from server if according agrument is set.''' if requestRoster: # FIXME: used somewhere? - roster_nb.NonBlockingRoster().PlugIn(self) + roster_nb.NonBlockingRoster.get_instance().PlugIn(self) self.send(dispatcher_nb.Presence(to=jid, typ=typ))
###############################################################################
Modified: branches/osx_newbuildsys/src/common/xmpp/dispatcher_nb.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/dispatcher_nb.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/dispatcher_nb.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -22,9 +22,9 @@
import simplexml, sys, locale from xml.parsers.expat import ExpatError -from client import PlugIn -from protocol import NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, Iq, Presence, \ - Message, Protocol, Node, Error, ERR_FEATURE_NOT_IMPLEMENTED, StreamError +from plugin import PlugIn +from protocol import (NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, Iq, Presence, + Message, Protocol, Node, Error, ERR_FEATURE_NOT_IMPLEMENTED, StreamError) import logging log = logging.getLogger('gajim.c.x.dispatcher_nb')
@@ -52,6 +52,16 @@ XMPPDispatcher().PlugIn(client_obj) elif client_obj.protocol_type == 'BOSH': BOSHDispatcher().PlugIn(client_obj, after_SASL, old_features) + + @classmethod + def get_instance(cls, *args, **kwargs): + ''' + Factory Method for object creation. + + Use this instead of directly initializing the class in order to make + unit testing much easier. + ''' + return cls(*args, **kwargs)
class XMPPDispatcher(PlugIn):
Copied: branches/osx_newbuildsys/src/common/xmpp/plugin.py (from rev 10945, trunk/src/common/xmpp/plugin.py) =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/plugin.py (rev 0) +++ branches/osx_newbuildsys/src/common/xmpp/plugin.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -0,0 +1,97 @@ +## plugin.py +## +## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## 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 General Public License for more details. + +# $Id: client.py,v 1.52 2006/01/02 19:40:55 normanr Exp $ + +''' +Provides PlugIn class functionality to develop extentions for xmpppy. +''' + +import logging +log = logging.getLogger('gajim.c.x.plugin') + +class PlugIn: + ''' + Abstract xmpppy plugin infrastructure code, providing plugging in/out and + debugging functionality. + + Inherit to develop pluggable objects. No code change on the owner class + required (the object where we plug into) + + For every instance of PlugIn class the 'owner' is the class in what the plug + was plugged. + ''' + def __init__(self): + self._exported_methods=[] + + def PlugIn(self, owner): + ''' + Attach to owner and register ourself and our _exported_methods in it. + If defined by a subclass, call self.plugin(owner) to execute hook + code after plugging. + ''' + self._owner=owner + log.info('Plugging %s __INTO__ %s' % (self, self._owner)) + if self.__class__.__name__ in owner.__dict__: + log.debug('Plugging ignored: another instance already plugged.') + return + self._old_owners_methods=[] + for method in self._exported_methods: + if method.__name__ in owner.__dict__: + self._old_owners_methods.append(owner.__dict__[method.__name__]) + owner.__dict__[method.__name__]=method + if self.__class__.__name__.endswith('Dispatcher'): + # FIXME: I need BOSHDispatcher or XMPPDispatcher on .Dispatcher + # there must be a better way.. + owner.__dict__['Dispatcher']=self + else: + owner.__dict__[self.__class__.__name__]=self + + # Execute hook + if hasattr(self,'plugin'): + return self.plugin(owner) + + def PlugOut(self): + ''' + Unregister our _exported_methods from owner and detach from it. + If defined by a subclass, call self.plugout() after unplugging to execute + hook code. + ''' + log.info('Plugging %s __OUT__ of %s.' % (self, self._owner)) + for method in self._exported_methods: + del self._owner.__dict__[method.__name__] + for method in self._old_owners_methods: + self._owner.__dict__[method.__name__]=method + # FIXME: Dispatcher workaround + if self.__class__.__name__.endswith('Dispatcher'): + del self._owner.__dict__['Dispatcher'] + else: + del self._owner.__dict__[self.__class__.__name__] + # Execute hook + if hasattr(self,'plugout'): + return self.plugout() + del self._owner + + @classmethod + def get_instance(cls, *args, **kwargs): + ''' + Factory Method for object creation. + + Use this instead of directly initializing the class in order to make + unit testing easier. For testing, this method can be patched to inject + mock objects. + ''' + return cls(*args, **kwargs) + +# vim: se ts=3:
Modified: branches/osx_newbuildsys/src/common/xmpp/proxy_connectors.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/proxy_connectors.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/proxy_connectors.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -55,6 +55,16 @@ self.old_on_receive = old_on_receive
self.start_connecting() + + @classmethod + def get_instance(cls, *args, **kwargs): + ''' + Factory Method for object creation. + + Use this instead of directly initializing the class in order to make + unit testing much easier. + ''' + return cls(*args, **kwargs)
def start_connecting(self): raise NotImplementedError
Modified: branches/osx_newbuildsys/src/common/xmpp/roster_nb.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/roster_nb.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/roster_nb.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -22,7 +22,7 @@ '''
from protocol import JID, Iq, Presence, Node, NodeProcessed, NS_ROSTER -from client import PlugIn +from plugin import PlugIn
import logging log = logging.getLogger('gajim.c.x.roster_nb')
Modified: branches/osx_newbuildsys/src/common/xmpp/tls_nb.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/tls_nb.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/tls_nb.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -16,7 +16,7 @@ ## GNU General Public License for more details.
import socket -from client import PlugIn +from plugin import PlugIn
import sys import os @@ -249,13 +249,12 @@ "SSL_CB_ALERT": 0x4000, "SSL_CB_HANDSHAKE_START": 0x10, "SSL_CB_HANDSHAKE_DONE": 0x20}
- def PlugIn(self, owner): + def plugin(self, owner): ''' Use to PlugIn TLS into transport and start establishing immediately Returns True if TLS/SSL was established correctly, otherwise False. ''' log.info('Starting TLS estabilishing') - PlugIn.PlugIn(self, owner) try: res = self._startSSL() except Exception, e: @@ -328,9 +327,8 @@ def _startSSL_pyOpenSSL(self): log.debug("_startSSL_pyOpenSSL called") tcpsock = self._owner - # FIXME: should method be configurable? - #tcpsock._sslContext = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD) - tcpsock._sslContext = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) + # See http://docs.python.org/dev/library/ssl.html + tcpsock._sslContext = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv3_METHOD) tcpsock.ssl_errnum = 0 tcpsock._sslContext.set_verify(OpenSSL.SSL.VERIFY_PEER, self._ssl_verify_callback)
Modified: branches/osx_newbuildsys/src/common/xmpp/transports_nb.py =================================================================== --- branches/osx_newbuildsys/src/common/xmpp/transports_nb.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/xmpp/transports_nb.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -25,7 +25,7 @@ '''
from simplexml import ustr -from client import PlugIn +from plugin import PlugIn from idlequeue import IdleObject import proxy_connectors import tls_nb @@ -74,22 +74,27 @@ #: size of the buffer which reads data from server # if lower, more stanzas will be fragmented and processed twice RECV_BUFSIZE = 32768 # 2x maximum size of ssl packet, should be plenty -#RECV_BUFSIZE = 16 # FIXME: (#2634) gajim breaks with this setting: it's inefficient but should work. +# FIXME: (#2634) gajim breaks with #RECV_BUFSIZE = 16 +# it's inefficient but should work. Problem is that connect machine makes wrong +# assumptions and that we only check for pending data in sockets but not in SSL +# buffer...
-DATA_RECEIVED='DATA RECEIVED' -DATA_SENT='DATA SENT' +DATA_RECEIVED = 'DATA RECEIVED' +DATA_SENT = 'DATA SENT'
DISCONNECTED = 'DISCONNECTED' DISCONNECTING = 'DISCONNECTING' CONNECTING = 'CONNECTING' PROXY_CONNECTING = 'PROXY_CONNECTING' CONNECTED = 'CONNECTED' -STATES = [DISCONNECTED, CONNECTING, PROXY_CONNECTING, CONNECTED, DISCONNECTING] -# Transports have different arguments in constructor and same connect() method. +STATES = (DISCONNECTED, CONNECTING, PROXY_CONNECTING, CONNECTED, DISCONNECTING)
class NonBlockingTransport(PlugIn): ''' Abstract class representing a transport. + + Subclasses CAN have different constructor signature but connect method SHOULD + be the same. ''' def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, certs): @@ -198,6 +203,7 @@ if hasattr(self._owner, 'Dispatcher'): self.on_receive = self._owner.Dispatcher.ProcessNonBlocking else: + log.warning('No Dispatcher plugged. Received data will not be processed') self.on_receive = None return self.on_receive = recv_handler @@ -321,15 +327,14 @@ proxyclass = proxy_connectors.SOCKS5Connector elif self.proxy_dict['type'] == 'http' : proxyclass = proxy_connectors.HTTPCONNECTConnector - proxyclass( - send_method = self.send, - onreceive = self.onreceive, - old_on_receive = self.on_receive, - on_success = self._on_connect, - on_failure = self._on_connect_failure, - xmpp_server = self.proxy_dict['xmpp_server'], - proxy_creds = self.proxy_dict['credentials'] - ) + proxyclass.get_instance( + send_method=self.send, + onreceive=self.onreceive, + old_on_receive=self.on_receive, + on_success=self._on_connect, + on_failure=self._on_connect_failure, + xmpp_server=self.proxy_dict['xmpp_server'], + proxy_creds=self.proxy_dict['credentials'])
def _on_connect(self): ''' @@ -344,14 +349,13 @@ else: NonBlockingTransport._on_connect(self)
- def tls_init(self, on_succ, on_fail): ''' Estabilishes TLS/SSL using this TCP connection by plugging a NonBlockingTLS module ''' cacerts, mycerts = self.certs - result = tls_nb.NonBlockingTLS(cacerts, mycerts).PlugIn(self) + result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts).PlugIn(self) if result: on_succ() else:
Modified: branches/osx_newbuildsys/src/common/zeroconf/client_zeroconf.py =================================================================== --- branches/osx_newbuildsys/src/common/zeroconf/client_zeroconf.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/common/zeroconf/client_zeroconf.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -21,7 +21,7 @@ import common.xmpp from common.xmpp.idlequeue import IdleObject from common.xmpp import dispatcher_nb, simplexml -from common.xmpp.client import * +from common.xmpp.plugin import * from common.xmpp.simplexml import ustr from common.xmpp.transports_nb import DATA_RECEIVED, DATA_SENT from common.zeroconf import zeroconf
Modified: branches/osx_newbuildsys/src/conversation_textview.py =================================================================== --- branches/osx_newbuildsys/src/conversation_textview.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/conversation_textview.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -1150,8 +1150,8 @@ '', None) imagepath = None end_iter = buffer_.get_end_iter() - anchor = buffer_.create_child_anchor(end_iter) if imagepath is not None: + anchor = buffer_.create_child_anchor(end_iter) img = gtk.Image() img.set_from_file(imagepath) img.show()
Modified: branches/osx_newbuildsys/src/roster_window.py =================================================================== --- branches/osx_newbuildsys/src/roster_window.py 2009-01-10 21:54:30 UTC (rev 10959) +++ branches/osx_newbuildsys/src/roster_window.py 2009-01-10 21:56:21 UTC (rev 10960) @@ -3519,7 +3519,6 @@ self.collapsed_rows.remove(account + group) for contact in gajim.contacts.iter_contacts(account): jid = contact.jid - print contact.jid, group, gajim.contacts.is_big_brother(account, contact.jid, accounts), self.collapsed_rows if group in contact.groups and gajim.contacts.is_big_brother( account, jid, accounts) and account + group + jid \ not in self.collapsed_rows: