Smacks class added, responds to ack requests
This commit is contained in:
parent
9cf9de2a14
commit
5b1edd03b8
|
@ -21,7 +21,7 @@ Can be used both for client and transport authentication
|
|||
See client_nb.py
|
||||
"""
|
||||
|
||||
from protocol import NS_SASL, NS_SESSION, NS_STREAMS, NS_BIND, NS_AUTH
|
||||
from protocol import NS_SASL, NS_SESSION, NS_STREAMS, NS_BIND, NS_AUTH, NS_STREAM_MGMT
|
||||
from protocol import Node, NodeProcessed, isResultNode, Iq, Protocol, JID
|
||||
from plugin import PlugIn
|
||||
import base64
|
||||
|
@ -31,7 +31,7 @@ import dispatcher_nb
|
|||
import hashlib
|
||||
import hmac
|
||||
import hashlib
|
||||
|
||||
from smacks import Smacks
|
||||
import logging
|
||||
log = logging.getLogger('gajim.c.x.auth_nb')
|
||||
|
||||
|
@ -491,7 +491,8 @@ class NonBlockingNonSASL(PlugIn):
|
|||
self.password = password
|
||||
self.resource = resource
|
||||
self.on_auth = on_auth
|
||||
|
||||
|
||||
|
||||
def plugin(self, owner):
|
||||
"""
|
||||
Determine the best auth method (digest/0k/plain) and use it for auth.
|
||||
|
@ -564,6 +565,7 @@ class NonBlockingBind(PlugIn):
|
|||
def __init__(self):
|
||||
PlugIn.__init__(self)
|
||||
self.bound = None
|
||||
self.supports_sm = False
|
||||
|
||||
def plugin(self, owner):
|
||||
''' Start resource binding, if allowed at this time. Used internally. '''
|
||||
|
@ -580,8 +582,14 @@ class NonBlockingBind(PlugIn):
|
|||
def FeaturesHandler(self, conn, feats):
|
||||
"""
|
||||
Determine if server supports resource binding and set some internal
|
||||
attributes accordingly
|
||||
attributes accordingly.
|
||||
|
||||
It also checks if server supports stream management
|
||||
"""
|
||||
|
||||
if feats.getTag('sm', namespace=NS_STREAM_MGMT):
|
||||
self.supports_sm = True # server supports stream management
|
||||
|
||||
if not feats.getTag('bind', namespace=NS_BIND):
|
||||
log.info('Server does not requested binding.')
|
||||
# we try to bind resource anyway
|
||||
|
@ -625,6 +633,14 @@ class NonBlockingBind(PlugIn):
|
|||
jid = JID(resp.getTag('bind').getTagData('jid'))
|
||||
self._owner.User = jid.getNode()
|
||||
self._owner.Resource = jid.getResource()
|
||||
# Only negociate stream management after bounded
|
||||
if self.supports_sm:
|
||||
# starts negociation
|
||||
sm = Smacks(self._owner)
|
||||
self._owner.Dispatcher.supports_sm = True
|
||||
self._owner.Dispatcher.sm = sm
|
||||
sm.negociate()
|
||||
|
||||
if hasattr(self, 'session') and self.session == -1:
|
||||
# Server don't want us to initialize a session
|
||||
log.info('No session required.')
|
||||
|
|
|
@ -75,7 +75,7 @@ class XMPPDispatcher(PlugIn):
|
|||
stream headers (used by SASL f.e.).
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self):
|
||||
PlugIn.__init__(self)
|
||||
self.handlers = {}
|
||||
self._expected = {}
|
||||
|
@ -89,6 +89,9 @@ class XMPPDispatcher(PlugIn):
|
|||
self.UnregisterHandler, self.RegisterProtocol,
|
||||
self.SendAndWaitForResponse, self.SendAndCallForResponse,
|
||||
self.getAnID, self.Event, self.send]
|
||||
|
||||
# Let the dispatcher know if there is support for stream management
|
||||
self.supports_sm = False
|
||||
|
||||
def getAnID(self):
|
||||
global outgoingID
|
||||
|
@ -110,6 +113,7 @@ class XMPPDispatcher(PlugIn):
|
|||
"""
|
||||
self.handlers = handlers
|
||||
|
||||
|
||||
def _init(self):
|
||||
"""
|
||||
Register default namespaces/protocols/handlers. Used internally
|
||||
|
@ -125,7 +129,7 @@ class XMPPDispatcher(PlugIn):
|
|||
self.RegisterDefaultHandler(self.returnStanzaHandler)
|
||||
self.RegisterEventHandler(self._owner._caller._event_dispatcher)
|
||||
self.on_responses = {}
|
||||
|
||||
|
||||
def plugin(self, owner):
|
||||
"""
|
||||
Plug the Dispatcher instance into Client class instance and send initial
|
||||
|
@ -416,7 +420,11 @@ class XMPPDispatcher(PlugIn):
|
|||
typ = ''
|
||||
stanza.props = stanza.getProperties()
|
||||
ID = stanza.getID()
|
||||
|
||||
if self.supports_sm and (stanza.getName() != 'r' and
|
||||
stanza.getName() != 'a' and
|
||||
stanza.getName() != 'enabled') :
|
||||
# increments the number of stanzas that has been handled
|
||||
self.sm.in_h = self.sm.in_h + 1
|
||||
list_ = ['default'] # we will use all handlers:
|
||||
if typ in self.handlers[xmlns][name]:
|
||||
list_.append(typ) # from very common...
|
||||
|
|
|
@ -143,7 +143,7 @@ NS_DATA_LAYOUT = 'http://jabber.org/protocol/xdata-layout' # XEP-0141
|
|||
NS_DATA_VALIDATE = 'http://jabber.org/protocol/xdata-validate' # XEP-0122
|
||||
NS_XMPP_STREAMS = 'urn:ietf:params:xml:ns:xmpp-streams'
|
||||
NS_RECEIPTS = 'urn:xmpp:receipts'
|
||||
NS_STREAM_MGMT = 'urn:xmpp:sm:3' # XEP-198
|
||||
NS_STREAM_MGMT = 'urn:xmpp:sm:2' # XEP-198
|
||||
|
||||
xmpp_stream_error_conditions = '''
|
||||
bad-format -- -- -- The entity has sent XML that cannot be processed.
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
from protocol import Acks
|
||||
from protocol import NS_STREAM_MGMT
|
||||
|
||||
class Smacks():
|
||||
'''
|
||||
This is Smacks is the Stream Management class. It takes care of requesting
|
||||
and sending acks. Also, it keeps track of the unhandled outgoing stanzas.
|
||||
|
||||
The dispatcher has to be able to access this class to increment the
|
||||
number of handled stanzas
|
||||
'''
|
||||
|
||||
|
||||
def __init__(self, owner):
|
||||
self._owner = owner
|
||||
self.out_h = 0 # Outgoing stanzas handled
|
||||
self.in_h = 0 # Incoming stanzas handled
|
||||
self.uqueue = [] # Unhandled stanzas queue
|
||||
|
||||
#Register handlers
|
||||
owner.Dispatcher.RegisterNamespace(NS_STREAM_MGMT)
|
||||
owner.Dispatcher.RegisterHandler('enabled', self._neg_response
|
||||
,xmlns=NS_STREAM_MGMT)
|
||||
owner.Dispatcher.RegisterHandler('r', self.send_ack
|
||||
,xmlns=NS_STREAM_MGMT)
|
||||
|
||||
|
||||
def negociate(self):
|
||||
stanza = Acks()
|
||||
stanza.buildEnable()
|
||||
self._owner.Connection.send(stanza, True)
|
||||
|
||||
def _neg_response(self, disp, stanza):
|
||||
pass
|
||||
|
||||
def send_ack(self, disp, stanza):
|
||||
ack = Acks()
|
||||
ack.buildAnswer(self.in_h)
|
||||
self._owner.Connection.send(ack, False)
|
||||
|
||||
def request_ack(self):
|
||||
r = Acks()
|
||||
r.buildRequest()
|
||||
self._owner.Connection.send(r, False)
|
Loading…
Reference in New Issue