Beispiel #1
0
    def plugin_init(self):
        register_stanza_plugin(Iq, RPCQuery)
        register_stanza_plugin(RPCQuery, MethodCall)
        register_stanza_plugin(RPCQuery, MethodResponse)

        self.xmpp.registerHandler(
            Callback('RPC Call', MatchXPath('{%s}iq/{%s}query/{%s}methodCall' % (self.xmpp.default_ns, RPCQuery.namespace, RPCQuery.namespace)),
            self._handle_method_call)
        )
        self.xmpp.registerHandler(
            Callback('RPC Call', MatchXPath('{%s}iq/{%s}query/{%s}methodResponse' % (self.xmpp.default_ns, RPCQuery.namespace, RPCQuery.namespace)),
            self._handle_method_response)
        )
        self.xmpp.registerHandler(
            Callback('RPC Call', MatchXPath('{%s}iq/{%s}error' % (self.xmpp.default_ns, self.xmpp.default_ns)),
            self._handle_error)
        )
        self.xmpp.add_event_handler('jabber_rpc_method_call', self._on_jabber_rpc_method_call)
        self.xmpp.add_event_handler('jabber_rpc_method_response', self._on_jabber_rpc_method_response)
        self.xmpp.add_event_handler('jabber_rpc_method_fault', self._on_jabber_rpc_method_fault)
        self.xmpp.add_event_handler('jabber_rpc_error', self._on_jabber_rpc_error)
        self.xmpp.add_event_handler('error', self._handle_error)
        #self.activeCalls = []

        self.xmpp['xep_0030'].add_feature('jabber:iq:rpc')
        self.xmpp['xep_0030'].add_identity('automation','rpc')
Beispiel #2
0
    def __init__(self, jid, password, ssl=False, plugin_config={},
                 plugin_whitelist=[], escape_quotes=True, sasl_mech=None):
        BaseXMPP.__init__(self, jid, 'jabber:client')

        self.set_jid(jid)
        self.escape_quotes = escape_quotes
        self.plugin_config = plugin_config
        self.plugin_whitelist = plugin_whitelist
        self.default_port = 5222

        self.credentials = {}

        self.password = password

        self.stream_header = "<stream:stream to='%s' %s %s version='1.0'>" % (
                self.boundjid.host,
                "xmlns:stream='%s'" % self.stream_ns,
                "xmlns='%s'" % self.default_ns)
        self.stream_footer = "</stream:stream>"

        self.features = set()
        self._stream_feature_handlers = {}
        self._stream_feature_order = []

        #TODO: Use stream state here
        self.authenticated = False
        self.sessionstarted = False
        self.bound = False
        self.bindfail = False

        self.add_event_handler('connected', self._handle_connected)
        self.add_event_handler('session_bind', self._handle_session_bind)

        self.register_stanza(StreamFeatures)

        self.register_handler(
                Callback('Stream Features',
                         MatchXPath('{%s}features' % self.stream_ns),
                         self._handle_stream_features))
        self.register_handler(
                Callback('Roster Update',
                         MatchXPath('{%s}iq/{%s}query' % (
                             self.default_ns,
                             'jabber:iq:roster')),
                         self._handle_roster))

        # Setup default stream features
        self.register_plugin('feature_starttls')
        self.register_plugin('feature_bind')
        self.register_plugin('feature_session')
        self.register_plugin('feature_mechanisms',
                pconfig={'use_mech': sasl_mech} if sasl_mech else None)
        self.register_plugin('feature_rosterver')
Beispiel #3
0
    def __init__(self,
                 jid,
                 secret,
                 host=None,
                 port=None,
                 plugin_config={},
                 plugin_whitelist=[],
                 use_jc_ns=False):
        if use_jc_ns:
            default_ns = 'jabber:client'
        else:
            default_ns = 'jabber:component:accept'
        BaseXMPP.__init__(self, jid, default_ns)

        self.auto_authorize = None
        self.stream_header = "<stream:stream %s %s to='%s'>" % (
            'xmlns="jabber:component:accept"',
            'xmlns:stream="%s"' % self.stream_ns, jid)
        self.stream_footer = "</stream:stream>"
        self.server_host = host
        self.server_port = port
        self.secret = secret

        self.plugin_config = plugin_config
        self.plugin_whitelist = plugin_whitelist
        self.is_component = True

        self.register_handler(
            Callback('Handshake',
                     MatchXPath('{jabber:component:accept}handshake'),
                     self._handle_handshake))
        self.add_event_handler('presence_probe', self._handle_probe)
Beispiel #4
0
    def testIqErrorException(self):
        """Test using error exceptions with Iq stanzas."""
        def handle_iq(iq):
            raise XMPPError(condition='feature-not-implemented',
                            text="We don't do things that way here.",
                            etype='cancel',
                            clear=False)

        self.stream_start()
        self.xmpp.register_handler(
            Callback('Test Iq',
                     MatchXPath('{%s}iq/{test}query' % self.xmpp.default_ns),
                     handle_iq))

        self.recv("""
          <iq type="get" id="0">
            <query xmlns="test" />
          </iq>
        """)

        self.send("""
          <iq type="error" id="0">
            <query xmlns="test" />
            <error type="cancel" code="501">
              <feature-not-implemented
                  xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
              <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
                We don&apos;t do things that way here.
              </text>
            </error>
          </iq>
        """,
                  use_values=False)
Beispiel #5
0
    def start(self):
        """
        Démarre le service
        """
        xmppDomain = self.configService.value("XMPP_DOMAIN_NAME")
        xmppUser = self.configService.value("XMPP_USERNAME")
        self.xmpp = ClientXMPP(xmppUser,
                               self.configService.value("XMPP_PASSWORD"))

        # ajout des listeners et plugins
        self.xmpp.add_event_handler("session_start", self.session_start)
        self.xmpp.register_plugin('XmppMessagePlugin', module=xmpp)
        self.xmpp.register_handler(
            Callback(
                'SEN1 Message',
                MatchXPath('{%s}message/{http://xmpp.rocks}Sen1Message' %
                           self.xmpp.default_ns), self.receiveMessage))
        register_stanza_plugin(Message, XmppMessageStanza)

        if (not self.xmpp.connect(address=(xmppDomain, 5222))):
            raise Exception("Cannot bind XMPP session to {}".format(xmppUser))

        self.logger.info(
            "Start XMPP protocol : bind session {}...".format(xmppUser))

        self.xmpp.process()
Beispiel #6
0
    def __init__(self, jid, password, plugin_config={}, plugin_whitelist=[],
                 escape_quotes=True, sasl_mech=None, lang='en'):
        BaseXMPP.__init__(self, jid, 'jabber:client')

        self.escape_quotes = escape_quotes
        self.plugin_config = plugin_config
        self.plugin_whitelist = plugin_whitelist
        self.default_port = 5222
        self.default_lang = lang

        self.credentials = {}

        self.password = password

        self.stream_header = "<stream:stream to='%s' %s %s %s %s>" % (
                self.boundjid.host,
                "xmlns:stream='%s'" % self.stream_ns,
                "xmlns='%s'" % self.default_ns,
                "xml:lang='%s'" % self.default_lang,
                "version='1.0'")
        self.stream_footer = "</stream:stream>"

        self.features = set()
        self._stream_feature_handlers = {}
        self._stream_feature_order = []

        self.dns_service = 'xmpp-client'

        #TODO: Use stream state here
        self.authenticated = False
        self.sessionstarted = False
        self.bound = False
        self.bindfail = False

        self.add_event_handler('connected', self._reset_connection_state)
        self.add_event_handler('session_bind', self._handle_session_bind)
        self.add_event_handler('roster_update', self._handle_roster)

        self.register_stanza(StreamFeatures)

        self.register_handler(
                Callback('Stream Features',
                         MatchXPath('{%s}features' % self.stream_ns),
                         self._handle_stream_features))
        self.register_handler(
                Callback('Roster Update',
                         StanzaPath('iq@type=set/roster'),
                         lambda iq: self.event('roster_update', iq)))

        # Setup default stream features
        self.register_plugin('feature_starttls')
        self.register_plugin('feature_bind')
        self.register_plugin('feature_session')
        self.register_plugin('feature_rosterver')
        self.register_plugin('feature_preapproval')
        self.register_plugin('feature_mechanisms')

        if sasl_mech:
            self['feature_mechanisms'].use_mech = sasl_mech
Beispiel #7
0
    def plugin_init(self):
        if self.sasl_callback is None:
            self.sasl_callback = self._default_credentials

        if self.security_callback is None:
            self.security_callback = self._default_security

        creds = self.sasl_callback(set(['username']), set())
        if not self.use_mech and not creds['username']:
            self.use_mech = 'ANONYMOUS'

        self.mech = None
        self.mech_list = set()
        self.attempted_mechs = set()

        register_stanza_plugin(StreamFeatures, stanza.Mechanisms)

        self.xmpp.register_stanza(stanza.Success)
        self.xmpp.register_stanza(stanza.Failure)
        self.xmpp.register_stanza(stanza.Auth)
        self.xmpp.register_stanza(stanza.Challenge)
        self.xmpp.register_stanza(stanza.Response)
        self.xmpp.register_stanza(stanza.Abort)

        self.xmpp.register_handler(
                Callback('SASL Success',
                         MatchXPath(stanza.Success.tag_name()),
                         self._handle_success,
                         instream=True))
        self.xmpp.register_handler(
                Callback('SASL Failure',
                         MatchXPath(stanza.Failure.tag_name()),
                         self._handle_fail,
                         instream=True))
        self.xmpp.register_handler(
                Callback('SASL Challenge',
                         MatchXPath(stanza.Challenge.tag_name()),
                         self._handle_challenge))

        self.xmpp.register_feature('mechanisms',
                self._handle_sasl_auth,
                restart=True,
                order=self.order)
Beispiel #8
0
    def _handle_sm_feature(self, features):
        """
        Enable or resume stream management.

        If no SM-ID is stored, and resource binding has taken place,
        stream management will be enabled.

        If an SM-ID is known, and the server allows resumption, the
        previous stream will be resumed.
        """
        if 'stream_management' in self.xmpp.features:
            # We've already negotiated stream management,
            # so no need to do it again.
            return False
        if not self.sm_id:
            if 'bind' in self.xmpp.features:
                self.enabled.set()
                enable = stanza.Enable(self.xmpp)
                enable['resume'] = self.allow_resume
                enable.send(now=True)
                self.handled = 0
        elif self.sm_id and self.allow_resume:
            self.enabled.set()
            resume = stanza.Resume(self.xmpp)
            resume['h'] = self.handled
            resume['previd'] = self.sm_id
            resume.send(now=True)

            # Wait for a response before allowing stream feature processing
            # to continue. The actual result processing will be done in the
            # _handle_resumed() or _handle_failed() methods.
            waiter = Waiter(
                'resumed_or_failed',
                MatchMany([
                    MatchXPath(stanza.Resumed.tag_name()),
                    MatchXPath(stanza.Failed.tag_name())
                ]))
            self.xmpp.register_handler(waiter)
            result = waiter.wait()
            if result is not None and result.name == 'resumed':
                return True
        return False
    def __init__(self,
                 server,
                 callback,
                 lang='en',
                 ns='jabber:client',
                 get_ca=False):
        super(StreamFeatureClient, self).__init__(server.domain, default_ns=ns)
        self._listed_server = server

        self.use_ipv6 = settings.USE_IP6
        self.auto_reconnect = False
        self.callback = callback
        self.ca_certs = '/etc/ssl/certs/ca-certificates.crt'

        # copied from ClientXMPP
        self.default_lang = lang
        self.stream_header = "<stream:stream to='%s' %s %s %s %s>" % (
            self.boundjid.host, "xmlns:stream='%s'" % self.stream_ns,
            "xmlns='%s'" % self.default_ns,
            "xml:lang='%s'" % self.default_lang, "version='1.0'")
        self.stream_footer = "</stream:stream>"
        self.features = set()
        self._stream_feature_handlers = {}
        self._stream_feature_order = []

        # register known features:
        self.register_plugin('feature_amp', module=amp)
        self.register_plugin('feature_auth', module=auth)
        self.register_plugin('feature_bind', module=bind)
        self.register_plugin('feature_caps', module=caps)
        self.register_plugin('feature_compression', module=compression)
        self.register_plugin('feature_mechanisms',
                             pconfig={'sasl_callback': self.sasl_callback})
        self.register_plugin('feature_register', module=register)
        self.register_plugin('feature_session', module=session)
        self.register_plugin('feature_sm', module=sm)
        self.register_plugin('feature_starttls')
        self.register_plugin('feature_rosterver', module=rosterver)
        self.register_plugin('feature_dialback', module=dialback)

        self.register_stanza(StreamFeatures)
        self.register_handler(
            Callback('Stream Features',
                     MatchXPath('{%s}features' % self.stream_ns),
                     self.get_features))

        self.add_event_handler('ssl_invalid_chain', self._invalid_chain)
        self.add_event_handler('ssl_invalid_cert', self._invalid_cert)
        self.add_event_handler('socket_error', self._socket_error)
        if get_ca:
            self.add_event_handler('ssl_cert', self._handle_cert)

        # do not reparse features:
        self._features = None
Beispiel #10
0
    def plugin_init(self):
        register_stanza_plugin(Iq, stanza.GmailQuery)
        register_stanza_plugin(Iq, stanza.MailBox)
        register_stanza_plugin(Iq, stanza.NewMail)

        self.xmpp.register_handler(
            Callback(
                'Gmail New Mail',
                MatchXPath('{%s}iq/{%s}%s' %
                           (self.xmpp.default_ns, stanza.NewMail.namespace,
                            stanza.NewMail.name)), self._handle_new_mail))

        self._last_result_time = None
        self._last_result_tid = None
Beispiel #11
0
    def plugin_init(self):
        self.xmpp.register_handler(
            Callback('STARTTLS Proceed',
                     MatchXPath(stanza.Proceed.tag_name()),
                     self._handle_starttls_proceed,
                     instream=True))
        self.xmpp.register_feature('starttls',
                                   self._handle_starttls,
                                   restart=True,
                                   order=self.config.get('order', 0))

        self.xmpp.register_stanza(stanza.Proceed)
        self.xmpp.register_stanza(stanza.Failure)
        register_stanza_plugin(StreamFeatures, stanza.STARTTLS)
Beispiel #12
0
    def plugin_init(self):
        self.xep = '0004'
        self.description = 'Data Forms'

        self.xmpp.register_handler(
            Callback(
                'Data Form',
                MatchXPath('{%s}message/{%s}x' %
                           (self.xmpp.default_ns, Form.namespace)),
                self.handle_form))

        register_stanza_plugin(FormField, FieldOption)
        register_stanza_plugin(Form, FormField)
        register_stanza_plugin(Message, Form)
Beispiel #13
0
    def __init__(self, jid, password):
        sleekxmpp.ClientXMPP.__init__(self, jid, password)

        # The session_start event will be triggered when
        # the bot establishes its connection with the server
        # and the XML streams are ready for use. We want to
        # listen for this event so that we we can initialize
        # our roster.
        self.register_handler(
            Callback(
                'GcmMessage',
                MatchXPath('{%s}message/{%s}gcm' %
                           (self.default_ns, 'google:mobile:data')),
                self.message_callback))
        self.add_event_handler("session_start", self.start)
Beispiel #14
0
    def plugin_init(self):
        register_stanza_plugin(RPCQuery, stanza.MethodTimeout)

        self.xmpp.register_handler(
            Callback(
                "RPC Call",
                MatchXPath(
                    "{%s}iq/{%s}query/{%s}methodTimeout"
                    % (self.xmpp.default_ns, RPCQuery.namespace, RPCQuery.namespace)
                ),
                self._handle_method_timeout,
            )
        )

        self.xmpp.add_event_handler("jabber_rpc_method_timeout", self._on_jabber_rpc_method_timeout, threaded=True)
Beispiel #15
0
	def changed_status(self, pres):
		# Here we keep track of the status changes.

		# If it's a MUC presence, we're going to ignore it. MUC presence stanzas are handled elswhere.
		if MatchXPath("{%s}presence/{%s}x" % (self.xmpp.default_ns, 'http://jabber.org/protocol/muc#user')).match(pres):
			return;

		if pres['from'].user == self.xmpp.boundjid.user:
			return;
		
		if pres['type'] == 'available':
			status = "Online";

		elif pres['type'] == 'xa' or pres['type'] == 'away' or pres['type'] == 'dnd':
			status = "Away";

		else: #elif pres['type'] == 'unavailable' or pres['type'] == 'error' or pres['type'] == 'probe':
			status = "Offline";

		if "savage" in self.xmpp.client_roster.presence( pres['from'].bare):
			status = "Ingame";
			
		self.chatEvent("chat_contact_update", pres['from'].user, status);
Beispiel #16
0
    def __init__(self, test, jid, lang='en'):
        super(StreamFeatureServer, self).__init__(jid,
                                                  default_ns='jabber:server')

        self.test = test
        self.use_ipv6 = settings.USE_IP6
        self.auto_reconnect = False
        self.test = test
        self._stream_features = {}

        # adapted from ClientXMPP
        self.default_port = 5269
        self.default_lang = lang
        self.stream_header = "<stream:stream to='%s' %s %s %s %s>" % (
            self.boundjid.host, "xmlns:stream='%s'" % self.stream_ns,
            "xmlns='%s'" % self.default_ns,
            "xml:lang='%s'" % self.default_lang, "version='1.0'")
        self.stream_footer = "</stream:stream>"

        self.features = set()
        self._stream_feature_handlers = {}
        self._stream_feature_order = []

        self.dns_service = 'xmpp-server'

        self.register_stanza(StreamFeatures)
        self.register_handler(
            Callback('Stream Features',
                     MatchXPath('{%s}features' % self.stream_ns),
                     self._handle_stream_features))

        self.register_plugin('feature_starttls')
        self.register_plugin('feature_dialback', module=dialback)
        self.register_plugin('feature_sm', module=sm)

        self.add_event_handler('stream_negotiated', self._stream_negotiated)
Beispiel #17
0
    def plugin_init(self):
        self.use_mech = self.config.get('use_mech', None)

        if not self.use_mech and not self.xmpp.boundjid.user:
            self.use_mech = 'ANONYMOUS'

        def tls_active():
            return 'starttls' in self.xmpp.features

        def basic_callback(mech, values):
            creds = self.xmpp.credentials
            for value in values:
                if value == 'username':
                    values['username'] = self.xmpp.boundjid.user
                elif value == 'password':
                    values['password'] = creds['password']
                elif value == 'email':
                    jid = self.xmpp.boundjid.bare
                    values['email'] = creds.get('email', jid)
                elif value in creds:
                    values[value] = creds[value]
            mech.fulfill(values)

        sasl_callback = self.config.get('sasl_callback', None)
        if sasl_callback is None:
            sasl_callback = basic_callback

        self.mech = None
        self.sasl = suelta.SASL(self.xmpp.boundjid.domain, 'xmpp',
                                username=self.xmpp.boundjid.user,
                                sec_query=suelta.sec_query_allow,
                                request_values=sasl_callback,
                                tls_active=tls_active,
                                mech=self.use_mech)

        self.mech_list = set()
        self.attempted_mechs = set()

        register_stanza_plugin(StreamFeatures, stanza.Mechanisms)

        self.xmpp.register_stanza(stanza.Success)
        self.xmpp.register_stanza(stanza.Failure)
        self.xmpp.register_stanza(stanza.Auth)
        self.xmpp.register_stanza(stanza.Challenge)
        self.xmpp.register_stanza(stanza.Response)
        self.xmpp.register_stanza(stanza.Abort)

        self.xmpp.register_handler(
                Callback('SASL Success',
                         MatchXPath(stanza.Success.tag_name()),
                         self._handle_success,
                         instream=True))
        self.xmpp.register_handler(
                Callback('SASL Failure',
                         MatchXPath(stanza.Failure.tag_name()),
                         self._handle_fail,
                         instream=True))
        self.xmpp.register_handler(
                Callback('SASL Challenge',
                         MatchXPath(stanza.Challenge.tag_name()),
                         self._handle_challenge))

        self.xmpp.register_feature('mechanisms',
                self._handle_sasl_auth,
                restart=True,
                order=self.config.get('order', 100))
Beispiel #18
0
    def __init__(self, jid='', default_ns='jabber:client'):
        XMLStream.__init__(self)

        self.default_ns = default_ns
        self.stream_ns = 'http://etherx.jabber.org/streams'
        self.namespace_map[self.stream_ns] = 'stream'

        #: An identifier for the stream as given by the server.
        self.stream_id = None

        #: The JabberID (JID) requested for this connection.
        self.requested_jid = JID(jid, cache_lock=True)

        #: The JabberID (JID) used by this connection,
        #: as set after session binding. This may even be a
        #: different bare JID than what was requested.
        self.boundjid = JID(jid, cache_lock=True)

        self._expected_server_name = self.boundjid.host
        self._redirect_attempts = 0

        #: The maximum number of consecutive see-other-host
        #: redirections that will be followed before quitting.
        self.max_redirects = 5

        self.session_bind_event = threading.Event()

        #: A dictionary mapping plugin names to plugins.
        self.plugin = PluginManager(self)

        #: Configuration options for whitelisted plugins.
        #: If a plugin is registered without any configuration,
        #: and there is an entry here, it will be used.
        self.plugin_config = {}

        #: A list of plugins that will be loaded if
        #: :meth:`register_plugins` is called.
        self.plugin_whitelist = []

        #: The main roster object. This roster supports multiple
        #: owner JIDs, as in the case for components. For clients
        #: which only have a single JID, see :attr:`client_roster`.
        self.roster = roster.Roster(self)
        self.roster.add(self.boundjid)

        #: The single roster for the bound JID. This is the
        #: equivalent of::
        #:
        #:     self.roster[self.boundjid.bare]
        self.client_roster = self.roster[self.boundjid]

        #: The distinction between clients and components can be
        #: important, primarily for choosing how to handle the
        #: ``'to'`` and ``'from'`` JIDs of stanzas.
        self.is_component = False

        #: Messages may optionally be tagged with ID values. Setting
        #: :attr:`use_message_ids` to `True` will assign all outgoing
        #: messages an ID. Some plugin features require enabling
        #: this option.
        self.use_message_ids = False

        #: Presence updates may optionally be tagged with ID values.
        #: Setting :attr:`use_message_ids` to `True` will assign all
        #: outgoing messages an ID.
        self.use_presence_ids = False

        #: The API registry is a way to process callbacks based on
        #: JID+node combinations. Each callback in the registry is
        #: marked with:
        #:
        #:   - An API name, e.g. xep_0030
        #:   - The name of an action, e.g. get_info
        #:   - The JID that will be affected
        #:   - The node that will be affected
        #:
        #: API handlers with no JID or node will act as global handlers,
        #: while those with a JID and no node will service all nodes
        #: for a JID, and handlers with both a JID and node will be
        #: used only for that specific combination. The handler that
        #: provides the most specificity will be used.
        self.api = APIRegistry(self)

        #: Flag indicating that the initial presence broadcast has
        #: been sent. Until this happens, some servers may not
        #: behave as expected when sending stanzas.
        self.sentpresence = False

        #: A reference to :mod:`sleekxmpp.stanza` to make accessing
        #: stanza classes easier.
        self.stanza = stanza

        self.register_handler(
            Callback('IM',
                     MatchXPath('{%s}message/{%s}body' % (self.default_ns,
                                                          self.default_ns)),
                     self._handle_message))
        self.register_handler(
            Callback('Presence',
                     MatchXPath("{%s}presence" % self.default_ns),
                     self._handle_presence))

        self.register_handler(
            Callback('Stream Error',
                     MatchXPath("{%s}error" % self.stream_ns),
                     self._handle_stream_error))

        self.add_event_handler('session_start',
                               self._handle_session_start)
        self.add_event_handler('disconnected',
                               self._handle_disconnected)
        self.add_event_handler('presence_available',
                               self._handle_available)
        self.add_event_handler('presence_dnd',
                               self._handle_available)
        self.add_event_handler('presence_xa',
                               self._handle_available)
        self.add_event_handler('presence_chat',
                               self._handle_available)
        self.add_event_handler('presence_away',
                               self._handle_available)
        self.add_event_handler('presence_unavailable',
                               self._handle_unavailable)
        self.add_event_handler('presence_subscribe',
                               self._handle_subscribe)
        self.add_event_handler('presence_subscribed',
                               self._handle_subscribed)
        self.add_event_handler('presence_unsubscribe',
                               self._handle_unsubscribe)
        self.add_event_handler('presence_unsubscribed',
                               self._handle_unsubscribed)
        self.add_event_handler('roster_subscription_request',
                               self._handle_new_subscription)

        # Set up the XML stream with XMPP's root stanzas.
        self.register_stanza(Message)
        self.register_stanza(Iq)
        self.register_stanza(Presence)
        self.register_stanza(StreamError)

        # Initialize a few default stanza plugins.
        register_stanza_plugin(Iq, Roster)
        register_stanza_plugin(Message, Nick)
Beispiel #19
0
    def __init__(self, jid='', default_ns='jabber:client'):
        XMLStream.__init__(self)

        self.default_ns = default_ns
        self.stream_ns = 'http://etherx.jabber.org/streams'
        self.namespace_map[self.stream_ns] = 'stream'

        #: An identifier for the stream as given by the server.
        self.stream_id = None

        #: The JabberID (JID) used by this connection.
        self.boundjid = JID(jid)

        #: A dictionary mapping plugin names to plugins.
        self.plugin = PluginManager(self)

        #: Configuration options for whitelisted plugins.
        #: If a plugin is registered without any configuration,
        #: and there is an entry here, it will be used.
        self.plugin_config = {}

        #: A list of plugins that will be loaded if
        #: :meth:`register_plugins` is called.
        self.plugin_whitelist = []

        #: The main roster object. This roster supports multiple
        #: owner JIDs, as in the case for components. For clients
        #: which only have a single JID, see :attr:`client_roster`.
        self.roster = roster.Roster(self)
        self.roster.add(self.boundjid.bare)

        #: The single roster for the bound JID. This is the
        #: equivalent of::
        #:
        #:     self.roster[self.boundjid.bare]
        self.client_roster = self.roster[self.boundjid.bare]

        #: The distinction between clients and components can be
        #: important, primarily for choosing how to handle the
        #: ``'to'`` and ``'from'`` JIDs of stanzas.
        self.is_component = False

        #: Flag indicating that the initial presence broadcast has
        #: been sent. Until this happens, some servers may not
        #: behave as expected when sending stanzas.
        self.sentpresence = False

        #: A reference to :mod:`sleekxmpp.stanza` to make accessing
        #: stanza classes easier.
        self.stanza = sleekxmpp.stanza

        self.register_handler(
            Callback(
                'IM',
                MatchXPath('{%s}message/{%s}body' %
                           (self.default_ns, self.default_ns)),
                self._handle_message))
        self.register_handler(
            Callback('Presence', MatchXPath("{%s}presence" % self.default_ns),
                     self._handle_presence))
        self.register_handler(
            Callback('Stream Error', MatchXPath("{%s}error" % self.stream_ns),
                     self._handle_stream_error))

        self.add_event_handler('disconnected', self._handle_disconnected)
        self.add_event_handler('presence_available', self._handle_available)
        self.add_event_handler('presence_dnd', self._handle_available)
        self.add_event_handler('presence_xa', self._handle_available)
        self.add_event_handler('presence_chat', self._handle_available)
        self.add_event_handler('presence_away', self._handle_available)
        self.add_event_handler('presence_unavailable',
                               self._handle_unavailable)
        self.add_event_handler('presence_subscribe', self._handle_subscribe)
        self.add_event_handler('presence_subscribed', self._handle_subscribed)
        self.add_event_handler('presence_unsubscribe',
                               self._handle_unsubscribe)
        self.add_event_handler('presence_unsubscribed',
                               self._handle_unsubscribed)
        self.add_event_handler('roster_subscription_request',
                               self._handle_new_subscription)

        # Set up the XML stream with XMPP's root stanzas.
        self.register_stanza(Message)
        self.register_stanza(Iq)
        self.register_stanza(Presence)
        self.register_stanza(StreamError)

        # Initialize a few default stanza plugins.
        register_stanza_plugin(Iq, Roster)
        register_stanza_plugin(Message, Nick)
        register_stanza_plugin(Message, HTMLIM)
Beispiel #20
0
    def plugin_init(self):
        """Start the XEP-0198 plugin."""

        # Only enable stream management for non-components,
        # since components do not yet perform feature negotiation.
        if self.xmpp.is_component:
            return

        self.window_counter = self.window
        self.window_counter_lock = threading.Lock()

        self.enabled = threading.Event()
        self.unacked_queue = collections.deque()

        self.seq_lock = threading.Lock()
        self.handled_lock = threading.Lock()
        self.ack_lock = threading.Lock()

        register_stanza_plugin(StreamFeatures, stanza.StreamManagement)
        self.xmpp.register_stanza(stanza.Enable)
        self.xmpp.register_stanza(stanza.Enabled)
        self.xmpp.register_stanza(stanza.Resume)
        self.xmpp.register_stanza(stanza.Resumed)
        self.xmpp.register_stanza(stanza.Ack)
        self.xmpp.register_stanza(stanza.RequestAck)

        # Only end the session when a </stream> element is sent,
        # not just because the connection has died.
        self.xmpp.end_session_on_disconnect = False

        # Register the feature twice because it may be ordered two
        # different ways: enabling after binding and resumption
        # before binding.
        self.xmpp.register_feature('sm',
                                   self._handle_sm_feature,
                                   restart=True,
                                   order=self.order)
        self.xmpp.register_feature('sm',
                                   self._handle_sm_feature,
                                   restart=True,
                                   order=self.resume_order)

        self.xmpp.register_handler(
            Callback('Stream Management Enabled',
                     MatchXPath(stanza.Enabled.tag_name()),
                     self._handle_enabled,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Resumed',
                     MatchXPath(stanza.Resumed.tag_name()),
                     self._handle_resumed,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Failed',
                     MatchXPath(stanza.Failed.tag_name()),
                     self._handle_failed,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Ack',
                     MatchXPath(stanza.Ack.tag_name()),
                     self._handle_ack,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Request Ack',
                     MatchXPath(stanza.RequestAck.tag_name()),
                     self._handle_request_ack,
                     instream=True))

        self.xmpp.add_filter('in', self._handle_incoming)
        self.xmpp.add_filter('out_sync', self._handle_outgoing)

        self.xmpp.add_event_handler('session_end', self.session_end)
Beispiel #21
0
    def plugin_init(self):
        """Start the XEP-0198 plugin."""

        # Only enable stream management for non-components,
        # since components do not yet perform feature negotiation.
        if self.xmpp.is_component:
            return

        #: The stream management ID for the stream. Knowing this value is
        #: required in order to do stream resumption.
        self.sm_id = self.config.get('sm_id', None)

        #: A counter of handled incoming stanzas, mod 2^32.
        self.handled = self.config.get('handled', 0)

        #: A counter of unacked outgoing stanzas, mod 2^32.
        self.seq = self.config.get('seq', 0)

        #: The last ack number received from the server.
        self.last_ack = self.config.get('last_ack', 0)

        #: The number of stanzas to wait between sending ack requests to
        #: the server. Setting this to ``1`` will send an ack request after
        #: every sent stanza. Defaults to ``5``.
        self.window = self.config.get('window', 5)
        self.window_counter = self.window
        self.window_counter_lock = threading.Lock()

        #: Control whether or not the ability to resume the stream will be
        #: requested when enabling stream management. Defaults to ``True``.
        self.allow_resume = self.config.get('allow_resume', True)

        self.enabled = threading.Event()
        self.unacked_queue = collections.deque()

        self.seq_lock = threading.Lock()
        self.handled_lock = threading.Lock()
        self.ack_lock = threading.Lock()

        register_stanza_plugin(StreamFeatures, stanza.StreamManagement)
        self.xmpp.register_stanza(stanza.Enable)
        self.xmpp.register_stanza(stanza.Enabled)
        self.xmpp.register_stanza(stanza.Resume)
        self.xmpp.register_stanza(stanza.Resumed)
        self.xmpp.register_stanza(stanza.Ack)
        self.xmpp.register_stanza(stanza.RequestAck)

        # Only end the session when a </stream> element is sent,
        # not just because the connection has died.
        self.xmpp.end_session_on_disconnect = False

        # Register the feature twice because it may be ordered two
        # different ways: enabling after binding and resumption
        # before binding.
        self.xmpp.register_feature('sm',
                                   self._handle_sm_feature,
                                   restart=True,
                                   order=self.config.get('order', 10100))
        self.xmpp.register_feature('sm',
                                   self._handle_sm_feature,
                                   restart=True,
                                   order=self.config.get('resume_order', 9000))

        self.xmpp.register_handler(
            Callback('Stream Management Enabled',
                     MatchXPath(stanza.Enabled.tag_name()),
                     self._handle_enabled,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Resumed',
                     MatchXPath(stanza.Resumed.tag_name()),
                     self._handle_resumed,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Failed',
                     MatchXPath(stanza.Failed.tag_name()),
                     self._handle_failed,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Ack',
                     MatchXPath(stanza.Ack.tag_name()),
                     self._handle_ack,
                     instream=True))

        self.xmpp.register_handler(
            Callback('Stream Management Request Ack',
                     MatchXPath(stanza.RequestAck.tag_name()),
                     self._handle_request_ack,
                     instream=True))

        self.xmpp.add_filter('in', self._handle_incoming)
        self.xmpp.add_filter('out_sync', self._handle_outgoing)

        self.xmpp.add_event_handler('session_end', self.session_end)