summaryrefslogtreecommitdiff
path: root/sleekxmpp/componentxmpp.py
blob: 5534a457af6e64fac2b75f1f36f13495e98f9f4f (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
89
#!/usr/bin/env python

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

    See the file LICENSE 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.is_component = True
                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)