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 ''
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))
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)
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
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)
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)
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
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
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([])
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"
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}))