Пример #1
0
 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
Пример #2
0
 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
Пример #3
0
 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
Пример #4
0
 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
Пример #5
0
 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
Пример #6
0
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()
Пример #7
0
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()
Пример #8
0
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()
Пример #9
0
 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
Пример #10
0
 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
Пример #11
0
 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
Пример #12
0
 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
Пример #13
0
    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
Пример #14
0
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()
Пример #15
0
    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
Пример #16
0
    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
Пример #17
0
 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
Пример #18
0
 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
Пример #19
0
 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
Пример #20
0
 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
Пример #21
0
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>"
Пример #22
0
 def CreateStanza(self):
     return xm(self.SendStmHdr)
Пример #23
0
 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
Пример #24
0
    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
Пример #25
0
    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
Пример #26
0
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>"
Пример #27
0
    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