def timercheck(self): for ses in self.sessionlist: if ses.TmPing+60<int(time.time()): ses.stream.ping() a={'from':self.manager.servname, 'id':utils.randstr(8), 'type':'get'} if ses.ident()!='': a['to']=ses.ident() nx = xm(ses.SentHeader,tag='iq',attrib=a, sub=[xm(ses.SentHeader, tag='ping', attrib={'xmlns':'urn:xmpp:ping'})]) ses.send(nx.tostring(),force=True) ses.TmPing = int(time.time()) pass if ses.TmRmsg+(180*3)<int(time.time()): if ses.Type==ns.TYPE_S: if ses.activeopen==False: ses.stream.close() pass else: ses.stream.close() pass pass pass pass
def timercheck(self): for ses in self.sessionlist: if ses.TmPing + 60 < int(time.time()): ses.stream.ping() a = { 'from': self.manager.servname, 'id': utils.randstr(8), 'type': 'get' } if ses.ident() != '': a['to'] = ses.ident() nx = xm(ses.SentHeader, tag='iq', attrib=a, sub=[ xm(ses.SentHeader, tag='ping', attrib={'xmlns': 'urn:xmpp:ping'}) ]) ses.send(nx.tostring(), force=True) ses.TmPing = int(time.time()) pass if ses.TmRmsg + (180 * 3) < int(time.time()): if ses.Type == ns.TYPE_S: if ses.activeopen == False: ses.stream.close() pass else: ses.stream.close() pass pass pass pass
def add_active_socket(self, peeraddr, peername): try: peersock = socket.create_connection(peeraddr, 10) peersock.settimeout(None) ses = session() ses.activeopen = True ses.manager = self.manager ses.peername = peername ses.stream = xmpp.stream.stream() ses.stream.CBF_recv = ses.recv ses.stream.CBF_closed = self.closed ses.stream.CBF_pong = ses.recv_pong ses.stream.peeraddr = peeraddr ses.stream.socket = peersock nx = xm('') a = { 'xmlns:stream': 'http://etherx.jabber.org/streams', 'xmlns': 'jabber:server', 'xmlns:db': 'jabber:server:dialback', 'version': '1.0' } nx.create(tag='stream:stream', attrib=a) sthdr = nx.tostring() ses.send(sthdr) ses.SentHeader = sthdr ses.authorized = False ses.sendkey = True ses.stream.start() self.sessionlist.append(ses) except: print("Unexpected error:", sys.exc_info()) return pass
def add_active_socket(self, peeraddr, peername): try: peersock = socket.create_connection(peeraddr, 10) peersock.settimeout(None) ses = session() ses.activeopen = True ses.manager = self.manager ses.peername = peername ses.stream = xmpp.stream.stream() ses.stream.CBF_recv = ses.recv ses.stream.CBF_closed = self.closed ses.stream.CBF_pong = ses.recv_pong ses.stream.peeraddr = peeraddr ses.stream.socket = peersock nx = xm('') a = {'xmlns:stream':'http://etherx.jabber.org/streams', 'xmlns':'jabber:server', 'xmlns:db':'jabber:server:dialback', 'version':'1.0'} nx.create(tag='stream:stream', attrib=a) sthdr = nx.tostring() ses.send(sthdr) ses.SentHeader = sthdr ses.authorized = False ses.sendkey = True ses.stream.start() self.sessionlist.append(ses) except: print("Unexpected error:", sys.exc_info()) return pass
def connect(self, sv, pt, us, pw, rs): self.server = sv self.port = pt self.username = us self.password = pw self.resource = rs self.stream.CBF_recv = self.received self.stream.CBF_closed = self.closed self.stream.connect(sv,pt) if self.CBF_connected!=None: self.CBF_connected() attr = {'to':sv, 'version':'1.0', 'xmlns:stream':'http://etherx.jabber.org/streams'} if self.Type=='client': attr['xmlns'] = 'jabber:client' pass elif self.Type=='component': attr['xmlns'] = 'jabber:component:accept' attr['from'] = us pass x=xm('',tag='stream:stream', attrib=attr) self.SendStmHdr = x.tostring() self.stream.send(x.tostring()) self.stream.start() pass
def md5ch1(h, r, n): chal = 'realm="{R}",nonce="{N}",qop="auth",charset=utf-8,algorithm=md5-sess' chal = chal.format(R=r, N=n) chal = chal.encode("cp932") b64str = binascii.b2a_base64(chal).decode("utf-8") b64str = b64str.replace('\n', '') m = xm(h,tag=ns.TAG_CHLNG,attrib={ns.XMLNS:ns.XMPP_SASL},text=b64str) return m.tostring()
def md5ch1(h, r, n): chal = 'realm="{R}",nonce="{N}",qop="auth",charset=utf-8,algorithm=md5-sess' chal = chal.format(R=r, N=n) chal = chal.encode("cp932") b64str = binascii.b2a_base64(chal).decode("utf-8") b64str = b64str.replace('\n', '') m = xm(h, tag=ns.TAG_CHLNG, attrib={ns.XMLNS: ns.XMPP_SASL}, text=b64str) return m.tostring()
def success(sthdr, rspauth=''): ratext = '' if rspauth != '': chal = ('rspauth={R}'.format(R=rspauth)).encode("cp932") b64str = binascii.b2a_base64(chal).decode("utf-8") ratext = b64str.replace('\n', '') pass m = xm(sthdr,tag=ns.TAG_SUCC,attrib={ns.XMLNS:ns.XMPP_SASL},text=ratext) return m.tostring()
def ProcMsgAuthentication(self, m): x = xm(self.recvsthdr) x.fromstring(m) mc = x.e.attrib['mechanism'] if self.mech is None: self.mech = self.mechlist[mc].__call__(self) self.mech.proc(m) pass pass
def proc(self, m): x = xm(self.recvsthdr) x.fromstring(m) msgtype = x.e.tag pos=msgtype.find('}') if pos>0: msgtype = msgtype[pos+1:] #utils.dprint(msgtype) if self.mech is None: self.ProcMsgAuthentication(m) else: self.mech.proc(m) pass
def proc(self, m): x = xm(self.recvsthdr) x.fromstring(m) msgtype = x.e.tag pos = msgtype.find('}') if pos > 0: msgtype = msgtype[pos + 1:] #utils.dprint(msgtype) if self.mech is None: self.ProcMsgAuthentication(m) else: self.mech.proc(m) pass
def pendmsgcheck(self): # if pending message doesn't exist if len(self.pendingmsg)==0: return # obtain a pending message (s,m,t,stat) = self.pendingmsg[0] # if its a too old message, discard it if t<int(time.time()-60): try: self.pendingmsg.remove((s,m,t,stat)) except: pass return if t<int(time.time()-5) and int(time.time()-5)%5==0: try: self.pendingmsg.remove((s,m,t,stat)) self.pendingmsg.append((s,m,t,'init')) except: pass pass # obtain servname and to-connect-hostname x = xm(s.RcvdHeader) x.fromstring(m) if ('to' in x.e.attrib) == False: try: self.pendingmsg.remove((s,m,t,stat)) except: pass return (uname, sname, rname) = splitjid(x.e.attrib['to']) try: hostportlist = self.srvrec(sname) except: try: self.pendingmsg.remove((s,m,t,stat)) except: pass return # if already have connection, send it for ses in self.sessionlist: if ses.ident()==sname and ses.authorized and ses.activeopen==True: s.forward(ses,m) try: self.pendingmsg.remove((s,m,t,stat)) except: pass return pass # if not yet connected if stat=='init': self.add_active_socket(hostportlist[0],sname) try: self.pendingmsg.remove((s,m,t,stat)) self.pendingmsg.append((s,m,t,'connecting')) except: pass pass pass
def success(sthdr, rspauth=''): ratext = '' if rspauth != '': chal = ('rspauth={R}'.format(R=rspauth)).encode("cp932") b64str = binascii.b2a_base64(chal).decode("utf-8") ratext = b64str.replace('\n', '') pass m = xm(sthdr, tag=ns.TAG_SUCC, attrib={ns.XMLNS: ns.XMPP_SASL}, text=ratext) return m.tostring()
def forward(self, sess, m): try: x = xm(self.RcvdHeader) x.fromstring(m) #utils.dprint("#forward to "+sess.ident()+" type is "+sess.Type) inttag = '' posa = m.find('>') posb = m.rfind('<') inttag = m[posa + 1:posb] #utils.dprint(inttag) att = {'to': x.e.attrib['to']} if 'from' in x.e.attrib: att['from'] = x.e.attrib['from'] elif self.ident() != '': att['from'] = self.ident() if 'id' in x.e.attrib: att['id'] = x.e.attrib['id'] if 'type' in x.e.attrib: att['type'] = x.e.attrib['type'] atstr = '' for k, v in att.items(): tmpstr = ' {N}="{VAL}" '.format(N=k, VAL=v) atstr += tmpstr pass nt = 'iq' if x.e.tag.find('}message') > 0: nt = 'message' elif x.e.tag.find('}iq') > 0: nt = 'iq' elif x.e.tag.find('}presence') > 0: nt = 'presence' newmsg = '<{T} {A}>{I}</{T}>'.format(T=nt, A=atstr, I=inttag) nx = xm(sess.SentHeader) nx.fromstring(newmsg) sess.send(nx.tostring()) except: pass pass
def forward(self,sess,m): try: x = xm(self.RcvdHeader) x.fromstring(m) #utils.dprint("#forward to "+sess.ident()+" type is "+sess.Type) inttag = '' posa = m.find('>') posb = m.rfind('<') inttag = m[posa+1:posb] #utils.dprint(inttag) att={'to':x.e.attrib['to']} if 'from' in x.e.attrib: att['from']=x.e.attrib['from'] elif self.ident()!='': att['from']=self.ident() if 'id' in x.e.attrib: att['id']=x.e.attrib['id'] if 'type' in x.e.attrib: att['type']=x.e.attrib['type'] atstr = '' for k,v in att.items(): tmpstr = ' {N}="{VAL}" '.format(N=k,VAL=v) atstr += tmpstr pass nt='iq' if x.e.tag.find('}message')>0: nt='message' elif x.e.tag.find('}iq')>0: nt='iq' elif x.e.tag.find('}presence')>0: nt='presence' newmsg = '<{T} {A}>{I}</{T}>'.format(T=nt,A=atstr,I=inttag) nx=xm(sess.SentHeader) nx.fromstring(newmsg) sess.send(nx.tostring()) except: pass pass
def proc(self, m): x = xm(self.manager.recvsthdr) x.fromstring(m) (self.manager.username,pw)=self.plainparse(x.e.text) if pw == self.manager.CBF_GetPasswordFunc(self.manager.username): m = success(self.manager.sendsthdr) self.manager.CBF_SendFunc(m) self.manager.authenticated = True self.manager.CBF_AuthenticatedFunc(True) pass else: m = failure(self.manager.sendsthdr) self.manager.CBF_SendFunc(m) self.manager.authenticated = False self.manager.CBF_AuthenticatedFunc(False) pass pass
def proc(self, m): x = xm(self.manager.recvsthdr) x.fromstring(m) (self.manager.username, pw) = self.plainparse(x.e.text) if pw == self.manager.CBF_GetPasswordFunc(self.manager.username): m = success(self.manager.sendsthdr) self.manager.CBF_SendFunc(m) self.manager.authenticated = True self.manager.CBF_AuthenticatedFunc(True) pass else: m = failure(self.manager.sendsthdr) self.manager.CBF_SendFunc(m) self.manager.authenticated = False self.manager.CBF_AuthenticatedFunc(False) pass pass
def proc(self, m): if self.state == self.STATE_INIT: m = md5ch1(self.manager.sendsthdr,self.realm, self.nonce) self.manager.CBF_SendFunc(m) self.state = self.STATE_CHALLENGE pass elif self.state == self.STATE_CHALLENGE: x=xm(self.manager.recvsthdr) x.fromstring(m) userinfo = self.response(x.e.text) self.manager.username = userinfo["username"] u = userinfo["username"] username = u password = self.manager.CBF_GetPasswordFunc(u) realm = self.realm nonce = self.nonce cnonce = userinfo["cnonce"] nc = userinfo["nc"] uri = userinfo["digest-uri"] qop = userinfo["qop"] response = userinfo["response"] chkreshex = self.GetDigestMD5Str(username, password, realm, nonce, cnonce, nc, uri, qop, 1) #utils.dprint("RECV: "+response) #utils.dprint("SEND: "+chkreshex) if chkreshex == response: authresult = True else: authresult = False if authresult == True: ra = self.GetDigestMD5Str(username, password, realm, nonce, cnonce, nc, uri, qop, 2) m = success(self.manager.sendsthdr,ra) self.manager.CBF_SendFunc(m) self.state = self.STATE_CHALLENGEOK self.manager.authenticated = True self.manager.CBF_AuthenticatedFunc(True) pass else: m = failure(self.manager.sendsthdr) self.manager.CBF_SendFunc(m) self.manager.authenticated = False self.manager.CBF_AuthenticatedFunc(False) pass pass pass
def proc(self, m): if self.state == self.STATE_INIT: m = md5ch1(self.manager.sendsthdr, self.realm, self.nonce) self.manager.CBF_SendFunc(m) self.state = self.STATE_CHALLENGE pass elif self.state == self.STATE_CHALLENGE: x = xm(self.manager.recvsthdr) x.fromstring(m) userinfo = self.response(x.e.text) self.manager.username = userinfo["username"] u = userinfo["username"] username = u password = self.manager.CBF_GetPasswordFunc(u) realm = self.realm nonce = self.nonce cnonce = userinfo["cnonce"] nc = userinfo["nc"] uri = userinfo["digest-uri"] qop = userinfo["qop"] response = userinfo["response"] chkreshex = self.GetDigestMD5Str(username, password, realm, nonce, cnonce, nc, uri, qop, 1) #utils.dprint("RECV: "+response) #utils.dprint("SEND: "+chkreshex) if chkreshex == response: authresult = True else: authresult = False if authresult == True: ra = self.GetDigestMD5Str(username, password, realm, nonce, cnonce, nc, uri, qop, 2) m = success(self.manager.sendsthdr, ra) self.manager.CBF_SendFunc(m) self.state = self.STATE_CHALLENGEOK self.manager.authenticated = True self.manager.CBF_AuthenticatedFunc(True) pass else: m = failure(self.manager.sendsthdr) self.manager.CBF_SendFunc(m) self.manager.authenticated = False self.manager.CBF_AuthenticatedFunc(False) pass pass pass
def failure(sthdr): m = xm(sthdr, tag=ns.TAG_FAIL, attrib={ns.XMLNS: ns.XMPP_SASL}, sub=[xm(sthdr, "temporary-auth-failure")]) return m.tostring() + "</stream:stream>"
def CreateStanza(self): return xm(self.SendStmHdr)
def received(self,s,m): self.stream.send(' ') x=xm(self.RecvStmHdr) x.fromstring(m) #utils.dprint(x.e.tag) if '{http://etherx.jabber.org/streams}stream'==x.e.tag: self.RecvStmHdr = m if self.Type == 'component': key = 'jkasdf988zxcvjiajkdsfa8sdf7a9ufoilj2kl3jasdfuya98d7aijdfklasjf13' self.stream.send('<handshake>'+ key +'</handshake>') pass pass elif '{jabber:component:accept}handshake'==x.e.tag: if self.Type == 'component': self.Authorized = True pass pass elif '{http://etherx.jabber.org/streams}features'==x.e.tag and \ self.Type == 'client': if self.Authorized == False: pwstr = '\0' + self.username + '\0' + self.password + '\0' pwstr = base64.b64encode(pwstr.encode('cp932')).decode('utf-8') nx=xm(self.SendStmHdr) nx.create(tag='auth', attrib={'xmlns':'urn:ietf:params:xml:ns:xmpp-sasl', 'mechanism':'PLAIN'}, text=pwstr) self.stream.send(nx.tostring()) pass else: rm = '<iq type="set" id="bind_1" >'+\ '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>' +\ self.resource + '</resource></bind></iq>' sm = '<iq type="set" id="sess_1" >' +\ '<session xmlns="urn:ietf:params:xml:ns:xmpp-session" /></iq>' self.stream.send(rm+sm) pass pass elif '{urn:ietf:params:xml:ns:xmpp-sasl}success'==x.e.tag and \ self.Type == 'client': self.Authorized = True self.SendStmHdr = '' self.RecvStmHdr = '' x=xm('',tag='stream:stream', attrib={'to':self.server, 'version':'1.0', 'xmlns':'jabber:client', 'xmlns:stream':'http://etherx.jabber.org/streams'}) self.SendStmHdr = x.tostring() self.stream.send(self.SendStmHdr) pass elif ('{jabber:client}iq'==x.e.tag or '{jabber:component:accept}iq'==x.e.tag) and \ 'id' in x.e.attrib and \ (x.e.attrib['id'] == 'bind_1' or x.e.attrib['id'] == 'sess_1') and \ self.Type == 'client': pass elif ('{jabber:client}iq'==x.e.tag or '{jabber:component:accept}iq'==x.e.tag) and \ 'id' in x.e.attrib: ch = x.e.find('{urn:xmpp:ping}ping') if ch!=None and self.AutoPong: pong = xm(self.SendStmHdr) pong.create(tag='iq', attrib={'from':x.e.attrib['to'], 'to':x.e.attrib['from'], 'id':x.e.attrib['id'], 'type':'result'}) self.stream.send(pong.tostring()) pass else: x=xm(self.RecvStmHdr) x.fromstring(m) if self.CBF_received!=None: self.CBF_received(x) pass pass else: x=xm(self.RecvStmHdr) x.fromstring(m) if self.CBF_received!=None: self.CBF_received(x) pass pass
def recv_internal(self, stream, m): self.CntRMsg += 1 self.TmRmsg = int(time.time()) x = xm(self.RcvdHeader) x.fromstring(m) # ============================================================ # receive stream header # ============================================================ if x.e.tag == '{http://etherx.jabber.org/streams}stream': self.RcvdHeader = m nx = xm(self.SentHeader) a = { 'xmlns:stream': 'http://etherx.jabber.org/streams', 'xmlns:xml': "http://www.w3.org/XML/1998/namespace" } if 'version' in x.e.attrib: self.streamver = float(x.e.attrib['version']) if self.streamver == 1.0: a['version'] = '1.0' elif self.streamver == 0.9: pass else: pass # ERROR: unknown version pass else: self.streamver = 0.9 pass #utils.dprint("stream version: "+ str(self.streamver)) if m.find('jabber:client') > 0: self.Type = ns.TYPE_C a['xmlns'] = 'jabber:client' a['from'] = self.manager.servname nx.create(tag='stream:stream', attrib=a) self.SentHeader = '' if self.SentHeader == '': self.SentHeader = nx.tostring() self.send(self.SentHeader) pass mec = xm(self.SentHeader) mec.create( tag='mechanisms', attrib={'xmlns': 'urn:ietf:params:xml:ns:xmpp-sasl'}, sub=[ xm(self.SentHeader, tag='mechanism', text='PLAIN'), xm(self.SentHeader, tag='mechanism', text='DIGEST-MD5'), xm(self.SentHeader, tag='required') ]) bid = xm(self.SentHeader) bid.create( tag='bind', attrib={'xmlns': 'urn:ietf:params:xml:ns:xmpp-bind'}, sub=[xm(self.SentHeader, tag='required')]) stg = xm(self.SentHeader) stg.create( tag='session', attrib={'xmlns': 'urn:ietf:params:xml:ns:xmpp-session'}, sub=[xm(self.SentHeader, tag='optional')]) nx = xm(self.SentHeader) subtag = [] if self.username == '': subtag = [mec] else: subtag = [bid, stg] nx.create(tag='stream:features', sub=subtag) self.send(nx.tostring()) pass elif m.find('jabber:component:accept') > 0: self.Type = ns.TYPE_M a['xmlns'] = 'jabber:component:accept' a['id'] = utils.randstr(8) a['from'] = self.manager.servname nx.create(tag='stream:stream', attrib=a) if self.SentHeader == '': self.SentHeader = nx.tostring() self.send(self.SentHeader) pass self.peername = x.e.attrib['from'] pass elif m.find('jabber:server') > 0: self.Type = ns.TYPE_S if 'from' in x.e.attrib: self.peername = x.e.attrib['from'] a['xmlns'] = 'jabber:server' a['xmlns:db'] = 'jabber:server:dialback' if self.peername != '': a['to'] = self.peername self.streamid = utils.randstr(16) a['id'] = self.streamid nx.create(tag='stream:stream', attrib=a) msg = '' if self.SentHeader == '': self.SentHeader = nx.tostring() msg = msg + nx.tostring() if self.streamver == 1.0: msg += '<stream:features>'+\ '<dialback xmlns="urn:xmpp:features:dialback">'+\ '<optional/></dialback></stream:features>' pass self.send(msg) if self.activeopen: key = create_key(utils.randstr(16), self.manager.servname, self.peername, self.streamid) nx = xm(self.SentHeader, tag='db:result', attrib={ 'from': self.manager.servname, 'to': self.peername }, text=key) self.send(nx.tostring(), force=True) pass pass return # ============================================================ # msg forward check # ============================================================ #utils.dprint(x.e.tag) if 'to' in x.e.attrib: #utils.dprint(x.e.attrib['to']) (uname, sname, rname) = splitjid(x.e.attrib['to']) #utils.dprint((uname, sname, rname)) for sess in self.manager.sessmanager.sessionlist: fw = False if sess == self: continue if sess.Type == ns.TYPE_S and sname == sess.ident(): if sess.activeopen and sess.authorized: fw = True pass elif x.e.attrib['to'] == sess.ident(): fw = True elif sess.Type == ns.TYPE_C and x.e.attrib[ 'to'] == sess.barejid(): fw = True elif sess.Type == ns.TYPE_C and (uname + '@' + sname) == sess.barejid(): fw = True elif sname == sess.ident(): fw = True if fw == True: if sess.Type == ns.TYPE_S: if sess.ident()==sname and \ sess.authorized and \ sess.activeopen==True: self.forward(sess, m) pass pass else: self.forward(sess, m) return pass if sname != self.manager.servname: item = (self, m, int(time.time()), 'init') self.manager.sessmanager.pendingmsg.append(item) return pass # ============================================================ # in case of client connection # ============================================================ if self.Type == ns.TYPE_C: if x.e.tag=='{urn:ietf:params:xml:ns:xmpp-sasl}auth' or \ x.e.tag=='{urn:ietf:params:xml:ns:xmpp-sasl}response': if self.authman == None: self.authman = xmpp.auth.manager(self.manager.servname, self.send, self.pwfunc, self.authenticated) (self.authman.sendsthdr, self.authman.recvsthdr) = (self.SentHeader, self.RcvdHeader) pass if self.authman.authenticated == False: self.authman.proc(m) return return if x.e.tag == '{jabber:client}iq': ResourceTag = '{NS}bind/{NS}resource' ResourceTag = ResourceTag.format( NS='{urn:ietf:params:xml:ns:xmpp-bind}') ResourceStz = x.e.find(ResourceTag) if ResourceStz != None: self.resource = ResourceStz.text #utils.dprint("# Client Resource is " + self.resource) nx = xm(self.SentHeader) nx.create(tag='iq', attrib={ 'id': x.e.attrib['id'], 'type': 'result' }, sub=[ xm(self.SentHeader, tag='bind', attrib={ 'xmlns': 'urn:ietf:params:xml:ns:xmpp-bind' }, sub=[ xm(self.SentHeader, tag='jid', text=self.fulljid()) ]) ]) self.send(nx.tostring()) return SessionTag = '{NS}session' SessionTag = SessionTag.format( NS='{urn:ietf:params:xml:ns:xmpp-session}') SessionStz = x.e.find(SessionTag) if SessionStz != None: nx = xm(self.SentHeader, tag='iq', attrib={ 'id': x.e.attrib['id'], 'type': 'result' }) self.send(nx.tostring()) return RosterQueryTag = '{jabber:iq:roster}query' RosterQueryStz = x.e.find(RosterQueryTag) if RosterQueryStz != None: nx = xm(self.SentHeader, tag='iq', attrib={ 'id': x.e.attrib['id'], 'type': 'result' }, sub=[ xm(self.SentHeader, tag='query', attrib={'xmlns': 'jabber:iq:roster'}) ]) self.send(nx.tostring()) return if 'type' in x.e.attrib: if x.e.attrib['type'] == 'get' or x.e.attrib[ 'type'] == 'set': nx = xm(self.SentHeader, tag='iq', attrib={ 'id': x.e.attrib['id'], 'type': 'result' }) self.send(nx.tostring()) return return pass pass # ============================================================ # in case of component connection # ============================================================ elif self.Type == ns.TYPE_M: if x.e.tag == '{jabber:component:accept}handshake': self.send('<handshake />') #utils.dprint(m) self.send('<handshake />') return pass # ============================================================ # in case of server connection # ============================================================ elif self.Type == ns.TYPE_S: if x.e.tag == '{jabber:server:dialback}verify': nx = xm(self.SentHeader, tag='db:verify', attrib={ 'xmlns:db': 'jabber:server:dialback', 'from': x.e.attrib['to'], 'to': x.e.attrib['from'], 'id': x.e.attrib['id'], 'type': 'valid' }, text=x.e.text) self.send(nx.tostring()) return if x.e.tag == '{jabber:server:dialback}result': #self.NeedStFeat = False if 'type' in x.e.attrib: if x.e.attrib['type'] == 'valid': self.authorized = True else: self.stream.close() return else: nx = xm(self.SentHeader, tag='db:result', attrib={ 'from': x.e.attrib['to'], 'to': x.e.attrib['from'], 'type': 'valid' }) time.sleep(1) self.send(nx.tostring()) return return pass # ============================================================ # error # ============================================================ else: self.stream.close() pass
def pendmsgcheck(self): # if pending message doesn't exist if len(self.pendingmsg) == 0: return # obtain a pending message (s, m, t, stat) = self.pendingmsg[0] # if its a too old message, discard it if t < int(time.time() - 60): try: self.pendingmsg.remove((s, m, t, stat)) except: pass return if t < int(time.time() - 5) and int(time.time() - 5) % 5 == 0: try: self.pendingmsg.remove((s, m, t, stat)) self.pendingmsg.append((s, m, t, 'init')) except: pass pass # obtain servname and to-connect-hostname x = xm(s.RcvdHeader) x.fromstring(m) if ('to' in x.e.attrib) == False: try: self.pendingmsg.remove((s, m, t, stat)) except: pass return (uname, sname, rname) = splitjid(x.e.attrib['to']) try: hostportlist = self.srvrec(sname) except: try: self.pendingmsg.remove((s, m, t, stat)) except: pass return # if already have connection, send it for ses in self.sessionlist: if ses.ident( ) == sname and ses.authorized and ses.activeopen == True: s.forward(ses, m) try: self.pendingmsg.remove((s, m, t, stat)) except: pass return pass # if not yet connected if stat == 'init': self.add_active_socket(hostportlist[0], sname) try: self.pendingmsg.remove((s, m, t, stat)) self.pendingmsg.append((s, m, t, 'connecting')) except: pass pass pass
def failure(sthdr): m = xm(sthdr, tag=ns.TAG_FAIL, attrib={ns.XMLNS:ns.XMPP_SASL}, sub=[xm(sthdr,"temporary-auth-failure")]) return m.tostring()+"</stream:stream>"
def recv_internal(self, stream, m): self.CntRMsg += 1 self.TmRmsg = int(time.time()) x = xm(self.RcvdHeader) x.fromstring(m) # ============================================================ # receive stream header # ============================================================ if x.e.tag=='{http://etherx.jabber.org/streams}stream': self.RcvdHeader = m nx = xm(self.SentHeader) a = {'xmlns:stream':'http://etherx.jabber.org/streams', 'xmlns:xml':"http://www.w3.org/XML/1998/namespace"} if 'version' in x.e.attrib: self.streamver = float(x.e.attrib['version']) if self.streamver == 1.0: a['version'] = '1.0' elif self.streamver == 0.9: pass else: pass # ERROR: unknown version pass else: self.streamver = 0.9 pass #utils.dprint("stream version: "+ str(self.streamver)) if m.find('jabber:client')>0: self.Type=ns.TYPE_C a['xmlns'] = 'jabber:client' a['from'] = self.manager.servname nx.create(tag='stream:stream', attrib=a) self.SentHeader = '' if self.SentHeader=='': self.SentHeader = nx.tostring() self.send(self.SentHeader) pass mec = xm(self.SentHeader) mec.create(tag='mechanisms', attrib={'xmlns':'urn:ietf:params:xml:ns:xmpp-sasl'}, sub=[xm(self.SentHeader,tag='mechanism',text='PLAIN'), xm(self.SentHeader,tag='mechanism',text='DIGEST-MD5'), xm(self.SentHeader,tag='required')]) bid = xm(self.SentHeader) bid.create(tag='bind', attrib={'xmlns':'urn:ietf:params:xml:ns:xmpp-bind'}, sub=[xm(self.SentHeader,tag='required')]) stg = xm(self.SentHeader) stg.create(tag='session', attrib={'xmlns':'urn:ietf:params:xml:ns:xmpp-session'}, sub=[xm(self.SentHeader,tag='optional')]) nx = xm(self.SentHeader) subtag=[] if self.username == '': subtag=[mec] else: subtag=[bid,stg] nx.create(tag='stream:features', sub=subtag) self.send(nx.tostring()) pass elif m.find('jabber:component:accept')>0: self.Type=ns.TYPE_M a['xmlns'] = 'jabber:component:accept' a['id'] = utils.randstr(8) a['from'] = self.manager.servname nx.create(tag='stream:stream', attrib=a) if self.SentHeader=='': self.SentHeader = nx.tostring() self.send(self.SentHeader) pass self.peername = x.e.attrib['from'] pass elif m.find('jabber:server')>0: self.Type=ns.TYPE_S if 'from' in x.e.attrib: self.peername = x.e.attrib['from'] a['xmlns'] = 'jabber:server' a['xmlns:db']='jabber:server:dialback' if self.peername!='': a['to'] = self.peername self.streamid = utils.randstr(16) a['id'] = self.streamid nx.create(tag='stream:stream', attrib=a) msg = '' if self.SentHeader=='': self.SentHeader = nx.tostring() msg = msg+nx.tostring() if self.streamver == 1.0: msg += '<stream:features>'+\ '<dialback xmlns="urn:xmpp:features:dialback">'+\ '<optional/></dialback></stream:features>' pass self.send(msg) if self.activeopen: key=create_key(utils.randstr(16), self.manager.servname,self.peername, self.streamid) nx = xm(self.SentHeader,tag='db:result', attrib={'from':self.manager.servname, 'to':self.peername}, text=key) self.send(nx.tostring(),force=True) pass pass return # ============================================================ # msg forward check # ============================================================ #utils.dprint(x.e.tag) if 'to' in x.e.attrib: #utils.dprint(x.e.attrib['to']) (uname, sname, rname) = splitjid(x.e.attrib['to']) #utils.dprint((uname, sname, rname)) for sess in self.manager.sessmanager.sessionlist: fw = False if sess==self: continue if sess.Type==ns.TYPE_S and sname==sess.ident(): if sess.activeopen and sess.authorized: fw = True pass elif x.e.attrib['to']==sess.ident(): fw = True elif sess.Type==ns.TYPE_C and x.e.attrib['to']==sess.barejid(): fw = True elif sess.Type==ns.TYPE_C and (uname+'@'+sname)==sess.barejid(): fw = True elif sname==sess.ident(): fw = True if fw==True: if sess.Type == ns.TYPE_S: if sess.ident()==sname and \ sess.authorized and \ sess.activeopen==True: self.forward(sess,m) pass pass else: self.forward(sess,m) return pass if sname!=self.manager.servname: item = (self,m,int(time.time()),'init') self.manager.sessmanager.pendingmsg.append(item) return pass # ============================================================ # in case of client connection # ============================================================ if self.Type==ns.TYPE_C: if x.e.tag=='{urn:ietf:params:xml:ns:xmpp-sasl}auth' or \ x.e.tag=='{urn:ietf:params:xml:ns:xmpp-sasl}response': if self.authman == None: self.authman = xmpp.auth.manager(self.manager.servname, self.send, self.pwfunc, self.authenticated) (self.authman.sendsthdr, self.authman.recvsthdr) = (self.SentHeader,self.RcvdHeader) pass if self.authman.authenticated == False: self.authman.proc(m) return return if x.e.tag=='{jabber:client}iq': ResourceTag='{NS}bind/{NS}resource' ResourceTag=ResourceTag.format(NS='{urn:ietf:params:xml:ns:xmpp-bind}') ResourceStz = x.e.find(ResourceTag) if ResourceStz!=None: self.resource = ResourceStz.text #utils.dprint("# Client Resource is " + self.resource) nx = xm(self.SentHeader) nx.create(tag='iq', attrib={'id':x.e.attrib['id'], 'type':'result'}, sub=[xm(self.SentHeader, tag='bind', attrib={'xmlns':'urn:ietf:params:xml:ns:xmpp-bind'}, sub=[xm(self.SentHeader,tag='jid', text=self.fulljid())])]) self.send(nx.tostring()) return SessionTag='{NS}session' SessionTag=SessionTag.format(NS='{urn:ietf:params:xml:ns:xmpp-session}') SessionStz = x.e.find(SessionTag) if SessionStz!=None: nx = xm(self.SentHeader,tag='iq', attrib={'id':x.e.attrib['id'],'type':'result'}) self.send(nx.tostring()) return RosterQueryTag='{jabber:iq:roster}query' RosterQueryStz=x.e.find(RosterQueryTag) if RosterQueryStz!=None: nx = xm(self.SentHeader,tag='iq', attrib={'id':x.e.attrib['id'],'type':'result'}, sub=[xm(self.SentHeader,tag='query', attrib={'xmlns':'jabber:iq:roster'})]) self.send(nx.tostring()) return if 'type' in x.e.attrib: if x.e.attrib['type']=='get' or x.e.attrib['type']=='set': nx = xm(self.SentHeader,tag='iq', attrib={'id':x.e.attrib['id'],'type':'result'}) self.send(nx.tostring()) return return pass pass # ============================================================ # in case of component connection # ============================================================ elif self.Type==ns.TYPE_M: if x.e.tag=='{jabber:component:accept}handshake': self.send('<handshake />') #utils.dprint(m) self.send('<handshake />') return pass # ============================================================ # in case of server connection # ============================================================ elif self.Type==ns.TYPE_S: if x.e.tag=='{jabber:server:dialback}verify': nx = xm(self.SentHeader,tag='db:verify', attrib={'xmlns:db':'jabber:server:dialback', 'from':x.e.attrib['to'], 'to':x.e.attrib['from'], 'id':x.e.attrib['id'], 'type':'valid'}, text=x.e.text) self.send(nx.tostring()) return if x.e.tag=='{jabber:server:dialback}result': #self.NeedStFeat = False if 'type' in x.e.attrib: if x.e.attrib['type']=='valid': self.authorized = True else: self.stream.close() return else: nx = xm(self.SentHeader,tag='db:result', attrib={'from':x.e.attrib['to'], 'to':x.e.attrib['from'], 'type':'valid'}) time.sleep(1) self.send(nx.tostring()) return return pass # ============================================================ # error # ============================================================ else: self.stream.close() pass