예제 #1
0
    def bind(self, resource):
        while self.bound is None and self.owner.process(1):
            pass

        resource = Node('resource', payload=[resource])
        res = self.owner.Dispatcher.send_and_wait_for_response(
            Protocol('iq',
                     tye='set',
                     payload=[
                         Node('bind',
                              attrs={'xmlns': NS_BIND},
                              payload=[resource])
                     ]))
        if is_result_node(res):
            self.bound.append(res.get_tag('bind').get_tag_data('jid'))
            jid = JID(res.get_tag('bind').get_tag_data('jid'))
            self.owner.user = jid.get_node()
            self.owner.resource = jid.get_resource()
            self.enable()
            res = self.owner.Dispatcher.send_and_wait_for_response(
                Protocol(
                    'iq',
                    tye='set',
                    payload=[Node('session', attrs={'xmlns': NS_SESSION})]))
            if is_result_node(res):
                self.session = 1
                return 'ok'
            else:
                self.session = 0
        else:
            return ''
예제 #2
0
    def features_handler(self, dis, feature):
        if not feature.get_tag("mechanisms", namespace=NS_SASL):
            self.startsasl = "not-supported"
            return

        mecs = []
        for mec in feature.get_tag("mechanisms",
                                   namespace=NS_SASL).get_tags("mechanism"):
            mecs.append(mec.get_data())

        self.owner.register_handler("challenge",
                                    self.sasl_handler,
                                    xmlns=NS_SASL)
        self.owner.register_handler("failure",
                                    self.sasl_handler,
                                    xmlns=NS_SASL)
        self.owner.register_handler("success",
                                    self.sasl_handler,
                                    xmlns=NS_SASL)

        if "ANONYMOUS" in mecs and self.username == None:
            node = Node('auth',
                        attrs={
                            "xmlns": NS_SASL,
                            "mechanism": "ANONYMOUS"
                        })
        elif "DIGEST-MD5" in mecs:
            node = Node('auth',
                        attrs={
                            "xmlns": NS_SASL,
                            "mechanism": "DIGEST-MD5"
                        })
        elif "PLAIN" in mecs:
            sasl_data = "%s\x00%s\x00%s" % (self.username + '@' +
                                            self.owner.server, self.username,
                                            self.password)
            node = Node('auth',
                        attrs={
                            "xmlns": NS_SASL,
                            "mechanism": "PLAIN"
                        },
                        payload=[
                            base64.encodestring(sasl_data).replace(
                                '\r', '').replace('\n', '')
                        ])
        else:
            self.startsasl = "fail"
            return

        self.startsasl = "in-process"
        self.owner.send(str(node))
예제 #3
0
 def __init__(self, name, code=None, typ=None, text=None):
     """ Mandatory parameter: name
         Optional parameters: code, typ, text."""
     if ERRORS.has_key(name): cod, type, txt = ERRORS[name]
     else: cod, type, txt = '', 'cancel', ''
     if typ: type = typ
     if code: cod = code
     if text: txt = text
     Node.__init__(self, 'error', {'type': type},
                   [Node(NS_STANZAS + ' ' + name)])
     if txt:
         self.addChild(node=Node(NS_STANZAS + ' text', {}, [txt]))
         self.addData(txt)
     if cod: self.setAttr('code', cod)
예제 #4
0
def gen_error(node,
              error_code='500',
              error_type='wait',
              error_name='internal-server-error',
              text=None,
              childs=False):
    """Генерирует ошибку из Node. По умолчанию internal-server-error."""
    err = Node(node.getName())
    if node['to']: err['from'] = node['to']
    if node['from']: err['to'] = node['from']
    if node['id']: err['id'] = node['id']
    err['type'] = 'error'
    if childs:
        for c in node.getChildren():
            if not c: continue
            err.addChild(node=c)
    e = err.addChild('error')
    e['type'] = error_type
    e['code'] = error_code
    e.addChild(error_name).setNamespace("urn:ietf:params:xml:ns:xmpp-stanzas")
    if text:
        t = e.addChild("text")
        t.setNamespace("urn:ietf:params:xml:ns:xmpp-stanzas")
        t.addData(text)
    return err
예제 #5
0
 def __init__(self, name, code=None, typ=None, text=None):
     """ Mandatory parameter: name
         Optional parameters: code, typ, text."""
     if ERRORS.has_key(name):
         cod, type, txt = ERRORS[name]
         ns = name.split()[0]
     else:
         cod, ns, type, txt = '500', NS_STANZAS, 'cancel', ''
     if typ: type = typ
     if code: cod = code
     if text: txt = text
     Node.__init__(self, 'error', {}, [Node(name)])
     if type: self.setAttr('type', type)
     if not cod: self.setName('stream:error')
     if txt: self.addChild(node=Node(ns + ' text', {}, [txt]))
     if cod: self.setAttr('code', cod)
예제 #6
0
 def __init__(self, name, code=None, typ=None, text=None):
     """ Create new error node object.
         Mandatory parameter: name - name of error condition.
         Optional parameters: code, typ, text. Used for backwards compartibility with older jabber protocol."""
     if ERRORS.has_key(name):
         cod, type, txt = ERRORS[name]
         ns = name.split()[0]
     else:
         cod, ns, type, txt = '500', NS_STANZAS, 'cancel', ''
     if typ: type = typ
     if code: cod = code
     if text: txt = text
     Node.__init__(self, 'error', {}, [Node(name)])
     if type: self.setAttr('type', type)
     if not cod: self.setName('stream:error')
     if txt: self.addChild(node=Node(ns + ' text', {}, [txt]))
     if cod: self.setAttr('code', cod)
예제 #7
0
def gen_iq_result(iq, query=None):
    """Генерирует iq-result из iq-get/set.
	iq - iq-get/set Node, из которого генерировать result
	query - Node, который добавить в iq-result"""
    node = Node('iq')
    node['type'] = 'result'
    if iq['from']: node['to'] = iq['from']
    node['id'] = iq['id']
    node['from'] = iq['to']
    if query and isinstance(query, Node): node.addChild(node=query)
    return node
예제 #8
0
 def enable(self):
     self.owner.send(
         Node('enable', attrs={
             'xmlns': NS_SESSION_TWO,
             'resume': 'true'
         }))
     self.owner.Dispatcher.register_handler('enabled',
                                            self.enable_handler,
                                            xmlns=NS_SESSION_TWO)
     while not self.owner.process(1):
         pass
예제 #9
0
def node_reader(read, nb=None):
    """Читает входящие данные и возвращает по одному объекту Node."""
    if not nb:
        nb = NodeBuilder()
        #nb.Parse('<stream:stream xmlns="jabber:client">')
    #print 'go'

    if nb.has_received_endtag(1) and nb.getDom().getChildren():
        for node in nb.getDom().getChildren():
            yield node

    while 1:
        d = read()
        #print d
        #print 'read',d
        if not d:
            #print 'no data'
            return
        while '<?' in d:
            d1, nd = d.split('<?', 1)
            nd, d2 = nd.split('>', 1)
            d = d1 + d2
            d = d.strip()
            del nd
        #print 'parse',d
        nb.Parse(d.replace('\x00', ''))
        if not nb.has_received_endtag(1) or not nb.getDom().getChildren():
            if nb.has_received_endtag(0):
                #print nb.getDom()
                #print 'ret'
                return
            elif nb.getDom() and not nb.getDom().getChildren():
                yield Node(node=nb.getDom())
                #nb.getDom().namespace = None
                #if nb.getDom().attrs.get('xmlns'):
                #    nb.getDom().attrs.pop('xmlns')
                #nb.getDom().nsp_cache={}
            #else: print 'wtf?', unicode(nb.getDom()).encode('utf-8'), unicode(nb.getDom().getChildren()[0]).encode('utf-8')
            continue
        #print unicode(nb.getDom()).encode('utf-8')
        for node in nb.getDom().getChildren():
            #self.last_node=node
            node.parent = None
            yield node
        nb.getDom().setPayload([])
예제 #10
0
    def sasl_handler(self, conn, challenge):
        if challenge.get_namespace() != NS_SASL:
            return

        if challenge.get_name() == "failure":
            self.startsasl = "failure"
            try:
                reason = challenge.get_children()[0]
            except Exception as e:
                print e
                reason = challenge
            print str(reason)
            return
        elif challenge.get_name() == "success":
            self.startsasl = "success"
            handlers = self.owner.Dispatcher.dump_handlers()
            self.owner.Dispatcher.Plugout()
            Dispatcher().Plugin(self.owner)
            self.owner.Dispatcher.store_handlers(handlers)
            return
        else:
            incoming_data = challenge.get_data()
            data = base64.decodestring(incoming_data)
            chal = {}
            for pair in re.findall('(\w+\s*=\s*(?:(?:"[^"]+")|(?:[^,]+)))',
                                   data):
                key, val = [x.strip() for x in pair.split("=", 1)]
                if val[0] == '"' and val[-1] == '"':
                    val = val[1:-1]
                chal[key] = val

            if chal.has_key("qop") and "auth" in [
                    x.strip() for x in chal['qop'].split(",")
            ]:
                res = {}
                res['username'] = self.username
                res['realm'] = self.owner.server
                res['nonce'] = chal['nonce']
                cnonce = ''
                for i in range(7):
                    cnonce += hex(int(random.random() * 65536 * 4096))[2:]
                res['cnonce'] = cnonce
                res['nc'] = ('00000001')
                res['qop'] = 'auth'
                res['digest-uri'] = 'xmpp/localhost'
                A1 = C([
                    H(C([res['username'], res['realm'], self.password])),
                    res['nonce'], res['cnonce']
                ])
                A2 = C(['AUTHENTICATE', res['digest-uri']])
                response = HH(
                    C([
                        HH(A1), res['nonce'], res['nc'], res['cnonce'],
                        res['qop'],
                        HH(A2)
                    ]))
                res['response'] = response
                res['charset'] = 'utf-8'
                sasl_data = ''
                for key in [
                        'charset', 'username', 'realm', 'nonce', 'nc',
                        'cnonce', 'digest-uri', 'response', 'qop'
                ]:
                    if key in ['nc', 'qop', 'response', 'charset']:
                        sasl_data += "%s=%s," % (key, res[key])
                    else:
                        sasl_data += '%s="%s",' % (key, res[key])
                node = Node("response",
                            attrs={'xmlns': NS_SASL},
                            payload=[
                                base64.encodestring(sasl_data[:-1]).replace(
                                    '\r', '').replace('\n', '')
                            ])
                self.owner.send(str(node))
            elif chal.has_key("rspauth"):
                node = Node("response", attrs={'xmlns': NS_SASL})
                self.owner.send(str(node))
            else:
                self.startsasl = "failure"
예제 #11
0
 def handler_a(self, dis, stanza):
     global R_H
     R_H += 1
     _id = R_H
     self.send(Node('a', attrs={'xmlns': NS_SESSION_TWO, 'h': _id}))