diff --git a/src/common/xmpp/__init__.py b/src/common/xmpp/__init__.py index 705e4e133..ad03b2881 100644 --- a/src/common/xmpp/__init__.py +++ b/src/common/xmpp/__init__.py @@ -26,6 +26,6 @@ and use only methods for access all values you should not have any problems. """ -import simplexml,protocol,debug,auth,transports,roster,dispatcher,features,browser,filetransfer,commands +import simplexml,protocol,debug,auth,transports,roster,dispatcher,features,browser,filetransfer,commands from client import * from protocol import * diff --git a/src/common/xmpp/auth.py b/src/common/xmpp/auth.py index 52637b26e..3091f5542 100644 --- a/src/common/xmpp/auth.py +++ b/src/common/xmpp/auth.py @@ -12,7 +12,7 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. -# $Id: auth.py,v 1.35 2006/01/18 19:26:43 normanr Exp $ +# $Id: auth.py,v 1.35 2006/01/18 19:26:43 normanr Exp $ """ Provides library with all Non-SASL and SASL authentication mechanisms. @@ -174,7 +174,7 @@ class SASL(PlugIn): data=base64.decodestring(incoming_data) self.DEBUG('Got challenge:'+data,'ok') for pair in data.split(','): - key,value=pair.split('=', 1) + key,value=pair.split('=', 1) if value[:1]=='"' and value[-1:]=='"': value=value[1:-1] chal[key]=value if chal.has_key('qop') and chal['qop']=='auth': @@ -199,7 +199,7 @@ class SASL(PlugIn): if key in ['nc','qop','response','charset']: sasl_data+="%s=%s,"%(key,resp[key]) else: sasl_data+='%s="%s",'%(key,resp[key]) ########################################3333 - node=Node('response',attrs={'xmlns':NS_SASL},payload=[base64.encodestring(sasl_data[:-1]).replace('\r','').replace('\n','')]) + node=Node('response',attrs={'xmlns':NS_SASL},payload=[base64.encodestring(sasl_data[:-1]).replace('\r','').replace('\n','')]) self._owner.send(node.__str__()) elif chal.has_key('rspauth'): self._owner.send(Node('response',attrs={'xmlns':NS_SASL}).__str__()) else: @@ -259,48 +259,48 @@ class Bind(PlugIn): else: self.DEBUG('Binding failed: timeout expired.','error') return '' - -class ComponentBind(PlugIn): - """ ComponentBind some JID to the current connection to allow router know of our location.""" - def __init__(self): - PlugIn.__init__(self) - self.DBG_LINE='bind' - self.bound=None - self.needsUnregister=None - - def plugin(self,owner): - """ Start resource binding, if allowed at this time. Used internally. """ - if self._owner.Dispatcher.Stream.features: - try: self.FeaturesHandler(self._owner.Dispatcher,self._owner.Dispatcher.Stream.features) - except NodeProcessed: pass - else: - self._owner.RegisterHandler('features',self.FeaturesHandler,xmlns=NS_STREAMS) - self.needsUnregister=1 - - def plugout(self): - """ Remove ComponentBind handler from owner's dispatcher. Used internally. """ - if self.needsUnregister: - self._owner.UnregisterHandler('features',self.FeaturesHandler,xmlns=NS_STREAMS) - - def FeaturesHandler(self,conn,feats): - """ Determine if server supports resource binding and set some internal attributes accordingly. """ - if not feats.getTag('bind',namespace=NS_BIND): - self.bound='failure' - self.DEBUG('Server does not requested binding.','error') - return - if feats.getTag('session',namespace=NS_SESSION): self.session=1 - else: self.session=-1 - self.bound=[] - - def Bind(self,domain=None): - """ Perform binding. Use provided domain name (if not provided). """ - while self.bound is None and self._owner.Process(1): pass - resp=self._owner.SendAndWaitForResponse(Protocol('bind',attrs={'name':domain},xmlns=NS_COMPONENT_1)) - if resp and resp.getAttr('error'): - self.DEBUG('Binding failed: %s.'%resp.getAttr('error'),'error') - elif resp: - self.DEBUG('Successfully bound.','ok') - return 'ok' - else: - self.DEBUG('Binding failed: timeout expired.','error') - return '' + +class ComponentBind(PlugIn): + """ ComponentBind some JID to the current connection to allow router know of our location.""" + def __init__(self): + PlugIn.__init__(self) + self.DBG_LINE='bind' + self.bound=None + self.needsUnregister=None + + def plugin(self,owner): + """ Start resource binding, if allowed at this time. Used internally. """ + if self._owner.Dispatcher.Stream.features: + try: self.FeaturesHandler(self._owner.Dispatcher,self._owner.Dispatcher.Stream.features) + except NodeProcessed: pass + else: + self._owner.RegisterHandler('features',self.FeaturesHandler,xmlns=NS_STREAMS) + self.needsUnregister=1 + + def plugout(self): + """ Remove ComponentBind handler from owner's dispatcher. Used internally. """ + if self.needsUnregister: + self._owner.UnregisterHandler('features',self.FeaturesHandler,xmlns=NS_STREAMS) + + def FeaturesHandler(self,conn,feats): + """ Determine if server supports resource binding and set some internal attributes accordingly. """ + if not feats.getTag('bind',namespace=NS_BIND): + self.bound='failure' + self.DEBUG('Server does not requested binding.','error') + return + if feats.getTag('session',namespace=NS_SESSION): self.session=1 + else: self.session=-1 + self.bound=[] + + def Bind(self,domain=None): + """ Perform binding. Use provided domain name (if not provided). """ + while self.bound is None and self._owner.Process(1): pass + resp=self._owner.SendAndWaitForResponse(Protocol('bind',attrs={'name':domain},xmlns=NS_COMPONENT_1)) + if resp and resp.getAttr('error'): + self.DEBUG('Binding failed: %s.'%resp.getAttr('error'),'error') + elif resp: + self.DEBUG('Successfully bound.','ok') + return 'ok' + else: + self.DEBUG('Binding failed: timeout expired.','error') + return '' diff --git a/src/common/xmpp/client.py b/src/common/xmpp/client.py index 0c444a390..08417c8af 100644 --- a/src/common/xmpp/client.py +++ b/src/common/xmpp/client.py @@ -149,11 +149,11 @@ class CommonClient: """ Example of reconnection method. In fact, it can be used to batch connection and auth as well. """ handlerssave=self.Dispatcher.dumpHandlers() self.Dispatcher.PlugOut() - if self.__dict__.has_key('NonSASL'): self.NonSASL.PlugOut() - if self.__dict__.has_key('SASL'): self.SASL.PlugOut() - if self.__dict__.has_key('TLS'): self.TLS.PlugOut() - if self.__dict__.has_key('HTTPPROXYsocket'): self.HTTPPROXYsocket.PlugOut() - if self.__dict__.has_key('TCPsocket'): self.TCPsocket.PlugOut() + if self.__dict__.has_key('NonSASL'): self.NonSASL.PlugOut() + if self.__dict__.has_key('SASL'): self.SASL.PlugOut() + if self.__dict__.has_key('TLS'): self.TLS.PlugOut() + if self.__dict__.has_key('HTTPPROXYsocket'): self.HTTPPROXYsocket.PlugOut() + if self.__dict__.has_key('TCPsocket'): self.TCPsocket.PlugOut() if not self.connect(server=self._Server,proxy=self._Proxy): return if not self.auth(self._User,self._Password,self._Resource): return self.Dispatcher.restoreHandlers(handlerssave) diff --git a/src/common/xmpp/commands.py b/src/common/xmpp/commands.py index 4dcf0b588..6b23cbfe3 100644 --- a/src/common/xmpp/commands.py +++ b/src/common/xmpp/commands.py @@ -1,4 +1,4 @@ -## $Id: commands.py,v 1.11 2005/11/30 17:03:11 normanr Exp $ +## $Id: commands.py,v 1.11 2005/11/30 17:03:11 normanr Exp $ ## Ad-Hoc Command manager ## Mike Albon (c) 5th January 2005 @@ -125,7 +125,7 @@ class Commands(PlugIn): conn.send(Error(request,ERR_ITEM_NOT_FOUND)) raise NodeProcessed elif typ == 'info': - return {'ids':[{'category':'automation','type':'command-list'}],'features':[]} + return {'ids':[{'category':'automation','type':'command-list'}],'features':[]} def addCommand(self,name,cmddisco,cmdexecute,jid=''): """The method to call if adding a new command to the session, the requred parameters of cmddisco and cmdexecute are the methods to enable that command to be executed""" @@ -197,7 +197,7 @@ class Command_Handler_Prototype(PlugIn): self.sessioncount = 0 self.sessions = {} # Disco information for command list pre-formatted as a tuple - self.discoinfo = {'ids':[{'category':'automation','type':'command-node','name':self.description}],'features': self.discofeatures} + self.discoinfo = {'ids':[{'category':'automation','type':'command-node','name':self.description}],'features': self.discofeatures} self._jid = jid def plugin(self,owner): diff --git a/src/common/xmpp/debug.py b/src/common/xmpp/debug.py index 6c28eb62c..a3cfd513e 100644 --- a/src/common/xmpp/debug.py +++ b/src/common/xmpp/debug.py @@ -121,7 +121,7 @@ class Debug: # # active_flags are those that will trigger output # - active_flags = None, + active_flags = None, # # Log file should be file object or file namne # @@ -132,7 +132,7 @@ class Debug: # with prefix = chr(27) + '[34m' # sufix = chr(27) + '[37;1m\n' # - prefix = 'DEBUG: ', + prefix = 'DEBUG: ', sufix = '\n', # # If you want unix style timestamps, @@ -140,7 +140,7 @@ class Debug: # 1 before prefix, good when prefix is a string # 2 after prefix, good when prefix is a color # - time_stamp = 0, + time_stamp = 0, # # flag_show should normaly be of, but can be turned on to get a # good view of what flags are actually used for calls, diff --git a/src/common/xmpp/dispatcher.py b/src/common/xmpp/dispatcher.py index 4354a7031..556690964 100644 --- a/src/common/xmpp/dispatcher.py +++ b/src/common/xmpp/dispatcher.py @@ -124,7 +124,7 @@ class Dispatcher(PlugIn): _pendingException = self._pendingExceptions.pop() raise _pendingException[0], _pendingException[1], _pendingException[2] if self._owner.Connection.pending_data(timeout): - try: data=self._owner.Connection.receive() + try: data=self._owner.Connection.receive() except IOError: return self.Stream.Parse(data) if len(self._pendingExceptions) > 0: diff --git a/src/common/xmpp/features.py b/src/common/xmpp/features.py index 0cef16d99..724623166 100644 --- a/src/common/xmpp/features.py +++ b/src/common/xmpp/features.py @@ -12,7 +12,7 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. -# $Id: features.py,v 1.22 2005/09/30 20:13:04 mikealbon Exp $ +# $Id: features.py,v 1.22 2005/09/30 20:13:04 mikealbon Exp $ """ This module contains variable stuff that is not worth splitting into separate modules. @@ -60,7 +60,7 @@ def discoverInfo(disp,jid,node=None): """ Query remote object about info that it publishes. Returns identities and features lists.""" """ According to JEP-0030: query MAY have node attribute - identity: MUST HAVE category and name attributes and MAY HAVE type attribute. + identity: MUST HAVE category and name attributes and MAY HAVE type attribute. feature: MUST HAVE var attribute""" identities , features = [] , [] for i in _discover(disp,NS_DISCO_INFO,jid,node): diff --git a/src/common/xmpp/protocol.py b/src/common/xmpp/protocol.py index 449122c62..9b0224e44 100644 --- a/src/common/xmpp/protocol.py +++ b/src/common/xmpp/protocol.py @@ -12,7 +12,7 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. -# $Id: protocol.py,v 1.52 2006/01/09 22:08:57 normanr Exp $ +# $Id: protocol.py,v 1.52 2006/01/09 22:08:57 normanr Exp $ """ Protocol module contains tools that is needed for processing of @@ -21,64 +21,64 @@ xmpp-related data structures. from simplexml import Node,ustr import time -NS_ACTIVITY ='http://jabber.org/protocol/activity' # JEP-0108 -NS_ADDRESS ='http://jabber.org/protocol/address' # JEP-0033 +NS_ACTIVITY ='http://jabber.org/protocol/activity' # JEP-0108 +NS_ADDRESS ='http://jabber.org/protocol/address' # JEP-0033 NS_AGENTS ='jabber:iq:agents' NS_AMP ='http://jabber.org/protocol/amp' -NS_AMP_ERRORS =NS_AMP+'#errors' +NS_AMP_ERRORS =NS_AMP+'#errors' NS_AUTH ='jabber:iq:auth' NS_BIND ='urn:ietf:params:xml:ns:xmpp-bind' NS_BROWSE ='jabber:iq:browse' -NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # JEP-0065 -NS_CAPS ='http://jabber.org/protocol/caps' # JEP-0115 -NS_CHATSTATES ='http://jabber.org/protocol/chatstates' # JEP-0085 +NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # JEP-0065 +NS_CAPS ='http://jabber.org/protocol/caps' # JEP-0115 +NS_CHATSTATES ='http://jabber.org/protocol/chatstates' # JEP-0085 NS_CLIENT ='jabber:client' NS_COMMANDS ='http://jabber.org/protocol/commands' NS_COMPONENT_ACCEPT='jabber:component:accept' -NS_COMPONENT_1 ='http://jabberd.jabberstudio.org/ns/component/1.0' -NS_COMPRESS ='http://jabber.org/protocol/compress' # JEP-0138 +NS_COMPONENT_1 ='http://jabberd.jabberstudio.org/ns/component/1.0' +NS_COMPRESS ='http://jabber.org/protocol/compress' # JEP-0138 NS_CONFERENCE ='jabber:x:conference' NS_DATA ='jabber:x:data' # JEP-0004 NS_DELAY ='jabber:x:delay' NS_DIALBACK ='jabber:server:dialback' -NS_DISCO ='http://jabber.org/protocol/disco' -NS_DISCO_INFO =NS_DISCO+'#info' -NS_DISCO_ITEMS =NS_DISCO+'#items' -NS_ENCRYPTED ='jabber:x:encrypted' # JEP-0027 -NS_EVENT ='jabber:x:event' # JEP-0022 -NS_FEATURE ='http://jabber.org/protocol/feature-neg' -NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # JEP-0096 -NS_GEOLOC ='http://jabber.org/protocol/geoloc' # JEP-0080 +NS_DISCO ='http://jabber.org/protocol/disco' +NS_DISCO_INFO =NS_DISCO+'#info' +NS_DISCO_ITEMS =NS_DISCO+'#items' +NS_ENCRYPTED ='jabber:x:encrypted' # JEP-0027 +NS_EVENT ='jabber:x:event' # JEP-0022 +NS_FEATURE ='http://jabber.org/protocol/feature-neg' +NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # JEP-0096 +NS_GEOLOC ='http://jabber.org/protocol/geoloc' # JEP-0080 NS_GROUPCHAT ='gc-1.0' NS_HTTP_AUTH ='http://jabber.org/protocol/http-auth' # JEP-0070 -NS_HTTP_BIND ='http://jabber.org/protocol/httpbind' # JEP-0124 +NS_HTTP_BIND ='http://jabber.org/protocol/httpbind' # JEP-0124 NS_IBB ='http://jabber.org/protocol/ibb' -NS_INVISIBLE ='presence-invisible' # Jabberd2 -NS_IQ ='iq' # Jabberd2 +NS_INVISIBLE ='presence-invisible' # Jabberd2 +NS_IQ ='iq' # Jabberd2 NS_LAST ='jabber:iq:last' -NS_MESSAGE ='message' # Jabberd2 -NS_MOOD ='http://jabber.org/protocol/mood' # JEP-0107 +NS_MESSAGE ='message' # Jabberd2 +NS_MOOD ='http://jabber.org/protocol/mood' # JEP-0107 NS_MUC ='http://jabber.org/protocol/muc' -NS_MUC_USER =NS_MUC+'#user' -NS_MUC_ADMIN =NS_MUC+'#admin' -NS_MUC_OWNER =NS_MUC+'#owner' -NS_OFFLINE ='http://www.jabber.org/jeps/jep-0030.html' # JEP-0013 -NS_PHYSLOC ='http://jabber.org/protocol/physloc' # JEP-0112 -NS_PRESENCE ='presence' # Jabberd2 +NS_MUC_USER =NS_MUC+'#user' +NS_MUC_ADMIN =NS_MUC+'#admin' +NS_MUC_OWNER =NS_MUC+'#owner' +NS_OFFLINE ='http://www.jabber.org/jeps/jep-0030.html' # JEP-0013 +NS_PHYSLOC ='http://jabber.org/protocol/physloc' # JEP-0112 +NS_PRESENCE ='presence' # Jabberd2 NS_PRIVACY ='jabber:iq:privacy' NS_PRIVATE ='jabber:iq:private' -NS_PUBSUB ='http://jabber.org/protocol/pubsub' # JEP-0060 +NS_PUBSUB ='http://jabber.org/protocol/pubsub' # JEP-0060 NS_REGISTER ='jabber:iq:register' NS_ROSTER ='jabber:iq:roster' -NS_ROSTERX ='http://jabber.org/protocol/rosterx' # JEP-0144 -NS_RPC ='jabber:iq:rpc' # JEP-0009 +NS_ROSTERX ='http://jabber.org/protocol/rosterx' # JEP-0144 +NS_RPC ='jabber:iq:rpc' # JEP-0009 NS_SASL ='urn:ietf:params:xml:ns:xmpp-sasl' NS_SEARCH ='jabber:iq:search' NS_SERVER ='jabber:server' NS_SESSION ='urn:ietf:params:xml:ns:xmpp-session' -NS_SI ='http://jabber.org/protocol/si' # JEP-0096 -NS_SI_PUB ='http://jabber.org/protocol/sipub' # JEP-0137 -NS_SIGNED ='jabber:x:signed' # JEP-0027 +NS_SI ='http://jabber.org/protocol/si' # JEP-0096 +NS_SI_PUB ='http://jabber.org/protocol/sipub' # JEP-0137 +NS_SIGNED ='jabber:x:signed' # JEP-0027 NS_STANZAS ='urn:ietf:params:xml:ns:xmpp-stanzas' NS_STREAM ='http://affinix.com/jabber/stream' NS_STREAMS ='http://etherx.jabber.org/streams' @@ -90,10 +90,10 @@ NS_GMAILNOTIFY ='google:mail:notify' NS_GTALKSETTING ='google:setting' NS_VCARD_UPDATE =NS_VCARD+':x:update' NS_VERSION ='jabber:iq:version' -NS_WAITINGLIST ='http://jabber.org/protocol/waitinglist' # JEP-0130 -NS_XHTML_IM ='http://jabber.org/protocol/xhtml-im' # JEP-0071 -NS_DATA_LAYOUT ='http://jabber.org/protocol/xdata-layout' # JEP-0141 -NS_DATA_VALIDATE='http://jabber.org/protocol/xdata-validate' # JEP-0122 +NS_WAITINGLIST ='http://jabber.org/protocol/waitinglist' # JEP-0130 +NS_XHTML_IM ='http://jabber.org/protocol/xhtml-im' # JEP-0071 +NS_DATA_LAYOUT ='http://jabber.org/protocol/xdata-layout' # JEP-0141 +NS_DATA_VALIDATE='http://jabber.org/protocol/xdata-validate' # JEP-0122 NS_XMPP_STREAMS ='urn:ietf:params:xml:ns:xmpp-streams' xmpp_stream_error_conditions=""" @@ -695,7 +695,7 @@ class DataForm(Node): for field in self.getTags('field'): name=field.getAttr('var') typ=field.getType() - if type(typ) in [type(''),type(u'')] and typ[-6:]=='-multi': + if type(typ) in [type(''),type(u'')] and typ[-6:]=='-multi': val=[] for i in field.getTags('value'): val.append(i.getData()) else: val=field.getTagData('value') diff --git a/src/common/xmpp/transports.py b/src/common/xmpp/transports.py index 6af8d5082..d8781743f 100644 --- a/src/common/xmpp/transports.py +++ b/src/common/xmpp/transports.py @@ -66,7 +66,7 @@ class error: class TCPsocket(PlugIn): """ This class defines direct TCP connection method. """ - def __init__(self, server=None, use_srv=True): + def __init__(self, server=None, use_srv=True): """ Cache connection point 'server'. 'server' is the tuple of (host, port) absolutely the same as standard tcp socket uses. """ PlugIn.__init__(self) @@ -165,12 +165,12 @@ class HTTPPROXYsocket(TCPsocket): """ HTTP (CONNECT) proxy connection class. Uses TCPsocket as the base class redefines only connect method. Allows to use HTTP proxies like squid with (optionally) simple authentication (using login and password). """ - def __init__(self,proxy,server,use_srv=True): + def __init__(self,proxy,server,use_srv=True): """ Caches proxy and target addresses. 'proxy' argument is a dictionary with mandatory keys 'host' and 'port' (proxy address) and optional keys 'user' and 'password' to use for authentication. 'server' argument is a tuple of host and port - just like TCPsocket uses. """ - TCPsocket.__init__(self,server,use_srv) + TCPsocket.__init__(self,server,use_srv) self.DBG_LINE=DBG_CONNECT_PROXY self._proxy=proxy @@ -196,23 +196,23 @@ class HTTPPROXYsocket(TCPsocket): connector.append('Proxy-Authorization: Basic '+credentials) connector.append('\r\n') self.send('\r\n'.join(connector)) - try: reply = self.receive().replace('\r','') - except IOError: - self.DEBUG('Proxy suddenly disconnected','error') - self._owner.disconnected() - return + try: reply = self.receive().replace('\r','') + except IOError: + self.DEBUG('Proxy suddenly disconnected','error') + self._owner.disconnected() + return try: proto,code,desc=reply.split('\n')[0].split(' ',2) except: raise error('Invalid proxy reply') if code<>'200': self.DEBUG('Invalid proxy reply: %s %s %s'%(proto,code,desc),'error') self._owner.disconnected() return - while reply.find('\n\n') == -1: - try: reply += self.receive().replace('\r','') - except IOError: - self.DEBUG('Proxy suddenly disconnected','error') - self._owner.disconnected() - return + while reply.find('\n\n') == -1: + try: reply += self.receive().replace('\r','') + except IOError: + self.DEBUG('Proxy suddenly disconnected','error') + self._owner.disconnected() + return self.DEBUG("Authentification successfull. Jabber server contacted.",'ok') return 'ok' @@ -256,13 +256,13 @@ class TLS(PlugIn): self._owner.Connection.send(''%NS_TLS) raise NodeProcessed - def pending_data(self,timeout=0): - """ Returns true if there possible is a data ready to be read. """ - return self._tcpsock._seen_data or select.select([self._tcpsock._sock],[],[],timeout)[0] - + def pending_data(self,timeout=0): + """ Returns true if there possible is a data ready to be read. """ + return self._tcpsock._seen_data or select.select([self._tcpsock._sock],[],[],timeout)[0] + def _startSSL(self): """ Immidiatedly switch socket to TLS mode. Used internally.""" - """ Here we should switch pending_data to hint mode.""" + """ Here we should switch pending_data to hint mode.""" tcpsock=self._owner.Connection tcpsock._sslObj = socket.ssl(tcpsock._sock, None, None) tcpsock._sslIssuer = tcpsock._sslObj.issuer()