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
|
"""
SleekXMPP: The Sleek XMPP Library
Copyright (C) 2011 Nathanael C. Fritz
This file is part of SleekXMPP.
See the file LICENSE for copying permission.
"""
import logging
from sleekxmpp.stanza import StreamFeatures
from sleekxmpp.xmlstream import RestartStream, register_stanza_plugin
from sleekxmpp.plugins import BasePlugin
from sleekxmpp.xmlstream.matcher import MatchXPath
from sleekxmpp.xmlstream.handler import Callback
from sleekxmpp.features.feature_starttls import stanza
log = logging.getLogger(__name__)
class FeatureSTARTTLS(BasePlugin):
name = 'feature_starttls'
description = 'RFC 6120: Stream Feature: STARTTLS'
dependencies = set()
stanza = stanza
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)
def _handle_starttls(self, features):
"""
Handle notification that the server supports TLS.
Arguments:
features -- The stream:features element.
"""
if 'starttls' in self.xmpp.features:
# We have already negotiated TLS, but the server is
# offering it again, against spec.
return False
elif not self.xmpp.use_tls:
return False
else:
self.xmpp.send(features['starttls'], now=True)
return True
def _handle_starttls_proceed(self, proceed):
"""Restart the XML stream when TLS is accepted."""
log.debug("Starting TLS")
if self.xmpp.start_tls():
self.xmpp.features.add('starttls')
raise RestartStream()
|