2010-05-25 02:33:24 +00:00
|
|
|
#!/usr/bin/python2.6
|
2009-06-03 22:56:51 +00:00
|
|
|
|
|
|
|
"""
|
|
|
|
SleekXMPP: The Sleek XMPP Library
|
2010-03-26 21:32:16 +00:00
|
|
|
Copyright (C) 2010 Nathanael C. Fritz
|
2009-06-03 22:56:51 +00:00
|
|
|
This file is part of SleekXMPP.
|
|
|
|
|
2010-07-20 15:19:49 +00:00
|
|
|
See the file LICENSE for copying permission.
|
2009-06-03 22:56:51 +00:00
|
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
from . basexmpp import basexmpp
|
|
|
|
from xml.etree import cElementTree as ET
|
2009-07-11 19:31:20 +00:00
|
|
|
|
2009-06-03 22:56:51 +00:00
|
|
|
from . xmlstream.xmlstream import XMLStream
|
|
|
|
from . xmlstream.xmlstream import RestartStream
|
|
|
|
from . xmlstream.matcher.xmlmask import MatchXMLMask
|
|
|
|
from . xmlstream.matcher.xpath import MatchXPath
|
|
|
|
from . xmlstream.matcher.many import MatchMany
|
|
|
|
from . xmlstream.handler.callback import Callback
|
|
|
|
from . xmlstream.stanzabase import StanzaBase
|
|
|
|
from . xmlstream import xmlstream as xmlstreammod
|
|
|
|
import time
|
|
|
|
import logging
|
|
|
|
import base64
|
|
|
|
import sys
|
|
|
|
import random
|
|
|
|
import copy
|
|
|
|
from . import plugins
|
|
|
|
from . import stanza
|
2009-08-31 23:02:19 +00:00
|
|
|
import hashlib
|
2009-06-03 22:56:51 +00:00
|
|
|
srvsupport = True
|
|
|
|
try:
|
|
|
|
import dns.resolver
|
|
|
|
except ImportError:
|
|
|
|
srvsupport = False
|
|
|
|
|
|
|
|
|
|
|
|
class ComponentXMPP(basexmpp, XMLStream):
|
|
|
|
"""SleekXMPP's client class. Use only for good, not evil."""
|
|
|
|
|
2009-10-29 03:22:50 +00:00
|
|
|
def __init__(self, jid, secret, host, port, plugin_config = {}, plugin_whitelist=[], use_jc_ns=False):
|
2009-06-03 22:56:51 +00:00
|
|
|
XMLStream.__init__(self)
|
2009-10-29 03:22:50 +00:00
|
|
|
if use_jc_ns:
|
|
|
|
self.default_ns = 'jabber:client'
|
|
|
|
else:
|
|
|
|
self.default_ns = 'jabber:component:accept'
|
2009-06-03 22:56:51 +00:00
|
|
|
basexmpp.__init__(self)
|
|
|
|
self.auto_authorize = None
|
|
|
|
self.stream_header = "<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' to='%s'>" % jid
|
|
|
|
self.stream_footer = "</stream:stream>"
|
|
|
|
self.server_host = host
|
|
|
|
self.server_port = port
|
|
|
|
self.set_jid(jid)
|
|
|
|
self.secret = secret
|
|
|
|
self.registerHandler(Callback('Handshake', MatchXPath('{jabber:component:accept}handshake'), self._handleHandshake))
|
2009-07-11 21:46:31 +00:00
|
|
|
|
2010-05-25 02:33:24 +00:00
|
|
|
def __getitem__(self, key):
|
2010-05-24 21:27:13 +00:00
|
|
|
if key in self.plugin:
|
|
|
|
return self.plugin[key]
|
|
|
|
else:
|
|
|
|
logging.warning("""Plugin "%s" is not loaded.""" % key)
|
|
|
|
return False
|
|
|
|
|
|
|
|
def get(self, key, default):
|
|
|
|
return self.plugin.get(key, default)
|
|
|
|
|
2009-07-11 21:46:31 +00:00
|
|
|
def incoming_filter(self, xmlobj):
|
|
|
|
if xmlobj.tag.startswith('{jabber:client}'):
|
2009-10-29 03:12:32 +00:00
|
|
|
xmlobj.tag = xmlobj.tag.replace('jabber:client', self.default_ns)
|
2009-09-15 18:42:47 +00:00
|
|
|
for sub in xmlobj:
|
|
|
|
self.incoming_filter(sub)
|
2009-07-11 21:46:31 +00:00
|
|
|
return xmlobj
|
|
|
|
|
2009-06-03 22:56:51 +00:00
|
|
|
def start_stream_handler(self, xml):
|
|
|
|
sid = xml.get('id', '')
|
|
|
|
handshake = ET.Element('{jabber:component:accept}handshake')
|
2010-01-27 23:09:23 +00:00
|
|
|
if sys.version_info < (3,0):
|
|
|
|
handshake.text = hashlib.sha1("%s%s" % (sid, self.secret)).hexdigest().lower()
|
|
|
|
else:
|
|
|
|
handshake.text = hashlib.sha1(bytes("%s%s" % (sid, self.secret), 'utf-8')).hexdigest().lower()
|
2009-12-15 04:31:46 +00:00
|
|
|
self.sendXML(handshake)
|
2009-06-03 22:56:51 +00:00
|
|
|
|
|
|
|
def _handleHandshake(self, xml):
|
|
|
|
self.event("session_start")
|
|
|
|
|
|
|
|
def connect(self):
|
|
|
|
logging.debug("Connecting to %s:%s" % (self.server_host, self.server_port))
|
|
|
|
return xmlstreammod.XMLStream.connect(self, self.server_host, self.server_port)
|