summaryrefslogtreecommitdiff
path: root/sleekxmpp/componentxmpp.py
blob: de125814b3161d7e44ba045554dbfabe933cc76e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/python2.6

"""
    SleekXMPP: The Sleek XMPP Library
    Copyright (C) 2010  Nathanael C. Fritz
    This file is part of SleekXMPP.

    See the file license.txt for copying permission.
"""
from __future__ import absolute_import
from . basexmpp import basexmpp
from xml.etree import cElementTree as ET

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
import hashlib
srvsupport = True
try:
	import dns.resolver
except ImportError:
	srvsupport = False


class ComponentXMPP(basexmpp, XMLStream):
	"""SleekXMPP's client class.  Use only for good, not evil."""

	def __init__(self, jid, secret, host, port, plugin_config = {}, plugin_whitelist=[], use_jc_ns=False):
		XMLStream.__init__(self)
		if use_jc_ns:
			self.default_ns = 'jabber:client'
		else:
			self.default_ns = 'jabber:component:accept'
		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))
	
	def __getitem__(self, key):
		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)
	
	def incoming_filter(self, xmlobj):
		if xmlobj.tag.startswith('{jabber:client}'):
			xmlobj.tag = xmlobj.tag.replace('jabber:client', self.default_ns)
		for sub in xmlobj:
			self.incoming_filter(sub)
		return xmlobj

	def start_stream_handler(self, xml):
		sid = xml.get('id', '')
		handshake = ET.Element('{jabber:component:accept}handshake')
		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()
		self.sendXML(handshake)
	
	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)