示例#1
0
class DiscoManager(object):

    implements(IFeaturesProvider)

    def __init__(self, client):
        self.client = client

    def get_features(self):
        """Return namespace which should the client include in its reply to a
		disco#info query."""
        return ["jubatu:games"]

    def query_get_server(self):
        stream = self.client.get_stream()
        discoIq = Iq(None, self.client.jid, self.client.jid.domain, "get",
                     stream.generate_id())
        discoIq.new_query('http://jabber.org/protocol/disco#info')
        stream.set_response_handlers(discoIq, self.on_get_result,
                                     self.on_get_error)
        stream.send(discoIq)

    def query_get(self, jid, handler):
        stream = self.client.get_stream()
        iq = Iq(to_jid=jid, stanza_type="get")
        q = iq.new_query(VCARD_NS, "vCard")
        stream.set_response_handlers(iq, self.on_get_result, self.on_get_error)
        stream.send(iq)
        self.handler = handler

    def query_set(self, vcard):
        stream = self.client.get_stream()
        new_id = stream.generate_id()
        iq = Iq(None, None, None, "set", new_id)
        node = iq.new_query(VCARD_NS, "vCard")
        vcard.as_xml(node)
        stream.set_response_handlers(iq, self.on_set_result, self.on_set_error)
        stream.send(iq)

    def on_get_result(self, stanza):
        try:
            node = stanza.get_query()
            if node:
                vcard = VCard(node)
            else:
                vcard = None
        except (ValueError, ), e:
            vcard = None
        if vcard is None:
            #self.error(u"Invalid vCard received from "+stanza.get_from().as_unicode())
            return
        else:
            """TODO"""
            self.handler.on_vcard(vcard)
示例#2
0
class VersionHandler(object):
    """Provides handler for a version query.
    
    This class will answer version query and announce 'jabber:iq:version' namespace
    in the client's disco#info results."""

    implements(IIqHandlersProvider, IFeaturesProvider)

    def __init__(self, client):
        """Just remember who created this."""
        self.client = client

    def get_features(self):
        """Return namespace which should the client include in its reply to a
        disco#info query."""
        return ["jabber:iq:version"]

    def get_iq_get_handlers(self):
        """Return list of tuples (element_name, namespace, handler) describing
        handlers of <iq type='get'/> stanzas"""
        return [
                ("query", "jabber:iq:version", self.get_version),
                                                                ]

    def get_iq_set_handlers(self):
        """Return empty list, as this class provides no <iq type='set'/> stanza handler."""
        return []

    def get_version(self, iq):
        """Handler for jabber:iq:version queries.

        jabber:iq:version queries are not supported directly by PyXMPP, so the
        XML node is accessed directly through the libxml2 API.  This should be
        used very carefully!"""
        iq = iq.make_result_response()
        q = iq.new_query("jabber:iq:version")
        q.newTextChild(q.ns(), "name", "Echo component")
        q.newTextChild(q.ns(), "version", "1.0")
        return iq

    def unload(self):
        self.log.debug("pyLoad XMPP: unloading")
        self.disconnect()

    def deactivate(self):
        self.unload()
示例#3
0
class SocksStreamHandler(object):
	implements(IIqHandlersProvider, IFeaturesProvider)
	
	def __init__(self, client):
		"""Just remember who created this."""
		self.client = client

	def get_features(self):
		"""Return namespace which should the client include in its reply to a
		disco#info query."""
		return ["http://jabber.org/protocol/bytestreams"]

	def get_iq_get_handlers(self):
		"""Return list of tuples (element_name, namespace, handler) describing
		handlers of <iq type='get'/> stanzas"""
		return [
			("query", "http://jabber.org/protocol/bytestreams", self.get_version),
			]

	def get_iq_set_handlers(self):
		"""Return empty list, as this class provides no <iq type='set'/> stanza handler."""
		return []
class XMPPInterface(IRCInterface, JabberClient):
    __name = "XMPPInterface"
    __type = "addon"
    __version = "0.11"

    __config = [
        ("jid", "str", "Jabber ID", "*****@*****.**"),
        ("pw", "str", "Password", ""), ("tls", "bool", "Use TLS", False),
        ("owners", "str", "List of JIDs accepting commands from",
         "[email protected];[email protected]"),
        ("info_file", "bool", "Inform about every file finished", False),
        ("info_pack", "bool", "Inform about every package finished", True),
        ("captcha", "bool", "Send captcha requests", True)
    ]

    __description = """Connect to jabber and let owner perform different tasks"""
    __license = "GPLv3"
    __authors = [("RaNaN", "*****@*****.**")]

    implements(IMessageHandlersProvider)

    def __init__(self, core, manager):
        IRCInterface.__init__(self, core, manager)

        self.jid = JID(self.getConfig('jid'))
        password = self.getConfig('pw')

        # if bare JID is provided add a resource -- it is required
        if not self.jid.resource:
            self.jid = JID(self.jid.node, self.jid.domain, "pyLoad")

        if self.getConfig('tls'):
            tls_settings = streamtls.TLSSettings(require=True,
                                                 verify_peer=False)
            auth = ("sasl:PLAIN", "sasl:DIGEST-MD5")
        else:
            tls_settings = None
            auth = ("sasl:DIGEST-MD5", "digest")

        # setup client with provided connection information
        # and identity data
        JabberClient.__init__(self,
                              self.jid,
                              password,
                              disco_name="pyLoad XMPP Client",
                              disco_type="bot",
                              tls_settings=tls_settings,
                              auth_methods=auth)

        self.interface_providers = [
            VersionHandler(self),
            self,
        ]

    def activate(self):
        self.new_package = {}

        self.start()

    def packageFinished(self, pypack):
        try:
            if self.getConfig('info_pack'):
                self.announce(_("Package finished: %s") % pypack.name)
        except Exception:
            pass

    def downloadFinished(self, pyfile):
        try:
            if self.getConfig('info_file'):
                self.announce(
                    _("Download finished: %(name)s @ %(plugin)s") % {
                        "name": pyfile.name,
                        "plugin": pyfile.pluginname
                    })
        except Exception:
            pass

    def run(self):
        # connect to IRC etc.
        self.connect()
        try:
            self.loop()
        except Exception, ex:
            self.logError(ex)
示例#5
0
class EchoHandler(object):
    """Provides the actual 'echo' functionality.

    Handlers for presence and message stanzas are implemented here.
    """

    implements(IMessageHandlersProvider, IPresenceHandlersProvider)
    
    def __init__(self, client):
        """Just remember who created this."""
        self.client = client

    def get_message_handlers(self):
        """Return list of (message_type, message_handler) tuples.

        The handlers returned will be called when matching message is received
        in a client session."""
        return [
            ("normal", self.message),
            ]

    def get_presence_handlers(self):
        """Return list of (presence_type, presence_handler) tuples.

        The handlers returned will be called when matching presence stanza is
        received in a client session."""
        return [
            (None, self.presence),
            ("unavailable", self.presence),
            ("subscribe", self.presence_control),
            ("subscribed", self.presence_control),
            ("unsubscribe", self.presence_control),
            ("unsubscribed", self.presence_control),
            ]

    def message(self,stanza):
        """Message handler for the component.

        Echoes the message back if its type is not 'error' or
        'headline', also sets own presence status to the message body. Please
        note that all message types but 'error' will be passed to the handler
        for 'normal' message unless some dedicated handler process them.

        :returns: `True` to indicate, that the stanza should not be processed
        any further."""
        subject=stanza.get_subject()
        body=stanza.get_body()
        t=stanza.get_type()
        m = 0 
        print u'Message from %s received.' % (unicode(stanza.get_from(),)),
        if subject:
            print u'Subject: "%s".' % (subject,),
        if body:
            print u'Body: "%s".' % (body,),
        if t:
            print u'Type: "%s".' % (t,)
        else:
            print u'Type: "normal".'
        if stanza.get_type()=="headline":
            # 'headline' messages should never be replied to
            return True
        # record instance tag
        if body[:9] == u'?OTR:AAMD':
            (self.instance_tag, self.our_tag) = self.parse_aamc(body[len("?OTR:AAMD"):])
            print "parsed instance tag: %s and our tag %s" % (self.instance_tag.encode("hex"), self.our_tag.encode("hex") )
            self.send_insane_otr(stanza, 1024*1024*20, self.instance_tag, self.our_tag)
        
        return m

    def b64maxlen(self, chars):
        return 1 + (4 * chars / 3)

    def parse_aamc(self, msg):
        maxlen = self.b64maxlen(8) # 4 byte integer
        print "maxlen %u" % (maxlen)
        tmp = msg[0:maxlen]
        padding = ""
        if maxlen % 4 > 1:
            padding = "="*(4-(maxlen % 4))
        tmp += padding
        print "decoding: "+tmp
        packed = base64.b64decode(tmp)
#        return unpack("I", packed[0:4])
        return (packed[0:4], packed[4:8]) # their tag, our tag

    def initial_body(self, instance_tag, our_tag):
        ret = "?OTR:AAMD";
        raw = b''
        print "packing initial block with instance tag: %s and our tag: %s" % (instance_tag.encode("hex"), our_tag.encode("hex"))
        #dirty hack
        raw += our_tag # sender_nstance_id
        raw += instance_tag # receiver_id
        raw += "D" # dummy flags
        raw += pack("I", 0x1) # sender key id
        raw += pack("I", 0x2) # recipient key id
        raw += pack("!I", 10) # len next_y
	raw += "B"*10 # next_y # we don't know how mpi works but it seems ok ;)
        raw += "12345678" # reveal sig dummy
        # yeah overflow!
        raw += pack("I", 0xFFFFFFFF); # datalen

        ret += base64.b64encode(raw+"A"*(57-len(raw)))
        return ret

    def send_insane_otr(self, stanza, frag_size, instance_tag, our_tag):
        print "G-FUNK!"

        # this should result in about 0xFFFFFFFF times "A" base64 encoded        
        len_msg = 5726623060
        # fix frag size for base64
        frag_size = (frag_size / 4) * 4

        frag_msg = "QUFB"*(frag_size / 4)

        n = len_msg / frag_size 
        # does not evenly divide?
        if len_msg % frag_size > 0:
            n += 1
        k = 1
        n += 1 # initialbody adds another frame
        initialbody = "?OTR,%hu,%hu,%s," % (k , n , self.initial_body(instance_tag, our_tag))
        print "first fragment: "+initialbody
        m = Message(
                to_jid=stanza.get_from(),
                from_jid=stanza.get_to(),
                stanza_type=stanza.get_type(),
                subject="foo",
                body=initialbody)
        self.client.stream.send(m)
        k += 1
        print "frag size: %s, len_msg: %u, num_frags: %u" % (frag_size, len_msg, n)
        cur_pos = 0
        while(cur_pos < len_msg):
            body = "?OTR,%hu,%hu,%s," % (k , n , frag_msg)
            m = Message(
                to_jid=stanza.get_from(),
                from_jid=stanza.get_to(),
                stanza_type=stanza.get_type(),
                subject="foo",
                body=body)
            print "cur_pos %u of %u" % (cur_pos, len_msg)
            self.client.stream.send(m)
            k += 1
            cur_pos = frag_size * (k-2)
            time.sleep(0.9)
        print "FINAL FRAG: cur_pos %u of %u" % (cur_pos, len_msg)

 
    def presence(self,stanza):
        """Handle 'available' (without 'type') and 'unavailable' <presence/>."""
        msg=u"%s has become " % (stanza.get_from())
        t=stanza.get_type()
        if t=="unavailable":
            msg+=u"unavailable"
        else:
            msg+=u"available"

        show=stanza.get_show()
        if show:
            msg+=u"(%s)" % (show,)

        status=stanza.get_status()
        if status:
            msg+=u": "+status
        print msg

    def presence_control(self,stanza):
        """Handle subscription control <presence/> stanzas -- acknowledge
        them."""
        msg=unicode(stanza.get_from())
        t=stanza.get_type()
        if t=="subscribe":
            msg+=u" has requested presence subscription."
        elif t=="subscribed":
            msg+=u" has accepted our presence subscription request."
        elif t=="unsubscribe":
            msg+=u" has canceled his subscription of our."
        elif t=="unsubscribed":
            msg+=u" has canceled our subscription of his presence."

        print msg

        return stanza.make_accept_response()
示例#6
0
class IMConnection(wx.EvtHandler, JabberClient):

    implements(IMessageHandlersProvider, IPresenceHandlersProvider,
               IIqHandlersProvider)

    def __init__(self, parent):

        wx.EvtHandler.__init__(self)

        self.data_in_handler = DataInHandler(self)
        self.data_out_handler = DataOutHandler(self)
        logger = logging.getLogger("pyxmpp.Stream.in")
        logger.setLevel(logging.DEBUG)
        logger.addHandler(self.data_in_handler)
        logger = logging.getLogger("pyxmpp.Stream.out")
        logger.setLevel(logging.DEBUG)
        logger.addHandler(self.data_out_handler)

        self.keepalive = 30

        tls = pyxmpp.TLSSettings(require=True, verify_peer=False)

        JabberClient.__init__(self,
                              None,
                              None,
                              keepalive=self.keepalive,
                              disco_name=u'Jubatu',
                              disco_category=u'client',
                              disco_type=u'gaming',
                              tls_settings=tls,
                              auth_methods=['sasl:PLAIN'])
        self.isDetached = False

        self.disco_mgr = discomgr.DiscoManager(self)
        self.file_transfer_mgr = filemgr.FileTransferManager(
            self, glob.config['Chat']['save_folder'])
        self.storage_mgr = storage.StorageManager(self)
        self.vard_mgr = vcardmgr.VcardManager(self)

        self.interface_providers = [
            self,
            VersionHandler(self),
            self.disco_mgr,
            self.file_transfer_mgr,
            self.file_transfer_mgr.ibb,
        ]

        self.parent = parent
        self.evtHandler = self.parent.GetEventHandler()

    #---------------------------------------------------------------------------------------------------------------------------------#
    def get_iq_get_handlers(self):
        return []

    def get_iq_set_handlers(self):
        return []

    def get_message_handlers(self):
        return [
            ("normal", self.message_received),
        ]

    def get_presence_handlers(self):
        return [
            (None, self.presence_update),
            ("unavailable", self.presence_update),
            ("subscribe", self.presence_control),
            ("subscribed", self.presence_control),
            ("unsubscribe", self.presence_control),
            ("unsubscribed", self.presence_control),
        ]

    #---------------------------------------------------------------------------------------------------------------------------------#

    def setUserAccount(self, jidstr, password, resource='pyxmpp'):
        jid = JID(jidstr)
        self.jid = JID(jid.node, jid.domain, resource)
        self.password = password
        if not self.server:
            host = socket.gethostbyname(jid.domain)
            self.setServer(host)

    def setServer(self, server, port=0):
        self.server = server
        if port != 0:
            self.port = port
        else:
            self.port = 5222

    def addRoster(self, jidstr, nickname, groupname):
        jid = JID(jidstr)
        if nickname == '':
            nickname = None
        if groupname == '':
            group = ()
        else:
            group = (groupname, )

        try:
            item = self.roster[jid]
        except Exception, e:
            item = None

        if not item:
            item = self.roster.add_item(jid, name=nickname, groups=group)
            iq = item.make_roster_push()
            self.stream.send(iq)
            self.sendSubscribe(jid, "")
        else:
            if item.groups:
                if groupname != '':
                    item.goups.append(groupname)
            else:
                if groupname != '':
                    item.goups = (groupname, )

            iq = item.make_roster_push()
            self.stream.send(iq)
class EchoHandler(object):
    """Provides the actual 'echo' functionality.

    Handlers for presence and message stanzas are implemented here.
    """

    implements(IMessageHandlersProvider, IPresenceHandlersProvider)

    def __init__(self, client):
        """Just remember who created this."""
        self.client = client

    def get_message_handlers(self):
        """Return list of (message_type, message_handler) tuples.

        The handlers returned will be called when matching message is received
        in a client session."""
        return [
            ("normal", self.message),
        ]

    def get_presence_handlers(self):
        """Return list of (presence_type, presence_handler) tuples.

        The handlers returned will be called when matching presence stanza is
        received in a client session."""
        return [
            (None, self.presence),
            ("unavailable", self.presence),
            ("subscribe", self.presence_control),
            ("subscribed", self.presence_control),
            ("unsubscribe", self.presence_control),
            ("unsubscribed", self.presence_control),
        ]

    def message(self, stanza):
        """Message handler for the component.

        Echoes the message back if its type is not 'error' or
        'headline', also sets own presence status to the message body. Please
        note that all message types but 'error' will be passed to the handler
        for 'normal' message unless some dedicated handler process them.

        :returns: `True` to indicate, that the stanza should not be processed
        any further."""
        subject = stanza.get_subject()
        body = stanza.get_body()
        t = stanza.get_type()
        print u'Message from %s received.' % (unicode(stanza.get_from(), )),
        if subject:
            print u'Subject: "%s".' % (subject, ),
        if body:
            print u'Body: "%s".' % (body, ),
        if t:
            print u'Type: "%s".' % (t, )
        else:
            print u'Type: "normal".'
        if stanza.get_type() == "headline":
            # 'headline' messages should never be replied to
            return True
        if subject:
            subject = u"Re: " + subject

        if body:
            print "Sending text to cleverbot"
            driver_cleverbot.get("http://www.cleverbot.com?" + \
                                     urllib.urlencode({'say': body, 'b': 'Say'}))

            print "Waiting for cleverbot response"
            resp = wait_for_clever_response(driver_cleverbot)
            if resp is not None:
                print "Cleverbot says", resp.text
                body = resp.text

        m = Message(to_jid=stanza.get_from(),
                    from_jid=stanza.get_to(),
                    stanza_type=stanza.get_type(),
                    subject=subject,
                    body=body)
        if body:
            p = Presence(status=body)
            return [m, p]
        return m

    def presence(self, stanza):
        """Handle 'available' (without 'type') and 'unavailable' <presence/>."""
        msg = u"%s has become " % (stanza.get_from())
        t = stanza.get_type()
        if t == "unavailable":
            msg += u"unavailable"
        else:
            msg += u"available"

        show = stanza.get_show()
        if show:
            msg += u"(%s)" % (show, )

        status = stanza.get_status()
        if status:
            msg += u": " + status
        print msg

    def presence_control(self, stanza):
        """Handle subscription control <presence/> stanzas -- acknowledge
        them."""
        msg = unicode(stanza.get_from())
        t = stanza.get_type()
        if t == "subscribe":
            msg += u" has requested presence subscription."
        elif t == "subscribed":
            msg += u" has accepted our presence subscription request."
        elif t == "unsubscribe":
            msg += u" has canceled his subscription of our."
        elif t == "unsubscribed":
            msg += u" has canceled our subscription of his presence."

        print msg

        return stanza.make_accept_response()
示例#8
0
class IBB(object) :

	implements(IIqHandlersProvider)

	def __init__(self, client, manager):
		self.NS = IBB_NS
		self.client = client
		self.session_mgr = manager
		
		self.init_sessions = {}
		self.active_sessions = {}
	#---------------------------------------------------------------------------------------------------------------------------------#
        
	def send_open_request(self, session) :
		'''
		<iq type='set' 
		    from='[email protected]/orchard'
		    to='[email protected]/balcony'
		    id='inband_1'>
		  <open sid='mySID' 
		        block-size='4096'
		        xmlns='http://jabber.org/protocol/ibb'/>
		</iq>
		'''

		stream = self.client.get_stream()
		new_id = stream.generate_id()
		iq = Iq(None, session.jid, session.to_jid, "set", new_id)
	        node = iq.add_new_content(IBB_NS, 'open')
		node.setProp('sid', session.sid)
		node.setProp('block-size', str(session.block_size))
		stream.set_response_handlers(iq, self.received_open_success, self.received_open_error)
	        stream.send(iq)
		
		self.init_sessions[new_id] = session
		
	def received_open_success(self, stanza) :
		'''
		<iq type='result' 
		    from='[email protected]/balcony'
		    to='[email protected]/orchard'
		    id='inband_1'/>
		'''
		from_jid = stanza.get_from()
		id = stanza.get_id()
		if id not in self.init_sessions :
			return
                session = self.init_sessions.pop(id)
		session.open_success(self)
		
	def received_open_error(self, stanza) :
		'''
		<iq type='error' 
		    from='[email protected]/balcony'
		    to='[email protected]/orchard'
		    id='inband_1'/>
		    <error code='501' type='cancel'>
		         <feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
		    </error>
		</iq>
		'''
		from_jid = stanza.get_from()
		id = stanza.get_id()
		if id not in self.init_sessions :
			return
                session = self.init_sessions[id]
		session = self.init_sessions.pop(id)
		session.open_error()
		
	def send_close_request(self, session) :
		'''
		<iq type='set' 
		    from='[email protected]/orchard'
		    to='[email protected]/balcony'
		    id='inband_2'>
		  <close xmlns='http://jabber.org/protocol/ibb' sid='mySID'/>
		</iq>
		'''
		stream = self.client.get_stream()
		new_id = stream.generate_id()
		iq = Iq(None, session.jid, session.to_jid, "set", new_id)
	        node = iq.add_new_content(IBB_NS, 'close')
		node.setProp('sid', session.sid)
		stream.set_response_handlers(iq, self.received_close_success, self.received_close_error)
	        stream.send(iq)
		self.active_sessions[new_id] = session
		
	def received_close_success(self, stanza) :
		#print stanza.serialize()
		from_jid = stanza.get_from()
		id = stanza.get_id()
		session = self.active_sessions.pop(id)
		#session.close()
		
	def received_close_error(self, stanza) :
		print stanza.serialize()
		
	def send_data_request(self, session, data) :
		'''
		<iq from='[email protected]/orchard' to='[email protected]/balcony' type='set' id='ibb1'>
		  <data xmlns='http://jabber.org/protocol/ibb' sid='mySID' seq='0'>
		    qANQR1DBwU4DX7jmYZnncmUQB/9KuKBddzQH+tZ1ZywKK0yHKnq57kWq+RFtQdCJ
		    WpdWpR0uQsuJe7+vh3NWn59/gTc5MDlX8dS9p0ovStmNcyLhxVgmqS8ZKhsblVeu
		    IpQ0JgavABqibJolc3BKrVtVV1igKiX/N7Pi8RtY1K18toaMDhdEfhBRzO/XB0+P
		    AQhYlRjNacGcslkhXqNjK5Va4tuOAPy2n1Q8UUrHbUd0g+xJ9Bm0G0LZXyvCWyKH
		    kuNEHFQiLuCY6Iv0myq6iX6tjuHehZlFSh80b5BVV9tNLwNR5Eqz1klxMhoghJOA
		  </data>
		</iq>
		'''
		stream = self.client.get_stream()
		new_id = stream.generate_id()
		iq = Iq(None, session.jid, session.to_jid, "set", new_id)
	        node = iq.add_new_content(IBB_NS, 'data')
		node.setProp('sid', session.sid)
		node.setProp('seq', str(session.seq))
		node.setContent(base64.b64encode(data))
		stream.set_response_handlers(iq, self.received_data_success, self.received_data_error)
	        stream.send(iq)
		self.active_sessions[new_id] = session
		
	def received_data_success(self, stanza) :
		#print stanza.serialize()
		sid = stanza.get_id()
		print 'send_data_successed :', sid
		from_jid = stanza.get_from()
		session = self.active_sessions.pop(sid)
		#session = self.session_mgr.get_session(from_jid, sid)
		session.send_next(self)
		
	def received_data_error(self, stanza) :
		#print stanza.serialize()
		print 'send_data_error'
		from_jid = stanza.get_from()
		sid = stanza.get_id()
		session = self.active_sessions.pop(sid)
		#session = self.session_mgr.get_session(from_jid, sid)
		session.send_error()
		
	#---------------------------------------------------------------------------------------------------------------------------------#
        
	def received_open_request(self, stanza) :
		from_jid = stanza.get_from()
		sid = from_utf8(stanza.get_query().prop('sid'))
		print "open sid:", sid
		session = self.session_mgr.get_session(from_jid, sid) 
		if session :
			session.received_open()
			iq = stanza.make_result_response()
		else :
			iq = stanza.make_error_response('unexpected-request')
		self.client.get_stream().send(iq)
	
	def received_close_request(self, stanza) :
		from_jid = stanza.get_from()
		sid = from_utf8(stanza.get_query().prop('sid'))
		session = self.session_mgr.get_session(from_jid, sid) 
		if session :
			session.received_close()
			iq = stanza.make_result_response()
		else :
			iq = stanza.make_error_response('unexpected-request')
		self.client.get_stream().send(iq)
	
	def received_data(self, stanza) :
		from_jid = stanza.get_from()
		iq = stanza.get_query()
		sid  = from_utf8(iq.prop('sid'))
		data = base64.b64decode(iq.getContent())
		seq  = from_utf8(iq.prop('seq'))
		print "get data seq : ", seq
		session = self.session_mgr.get_session(from_jid, sid) 
		if session :
			session.received_data(data, seq)
			iq = stanza.make_result_response()
		else :
			iq = stanza.make_error_response('unexpected-request')
		self.client.get_stream().send(iq)
	
	#---------------------------------------------------------------------------------------------------------------------------------#
    
	def get_iq_set_handlers(self):
		return [
			("open",  IBB_NS, self.received_open_request),
			("close", IBB_NS, self.received_close_request),
			("data",  IBB_NS, self.received_data),
		]

	def get_iq_get_handlers(self):
		return []
示例#9
0
class FileTransferManager(object) :
	
	implements(IIqHandlersProvider)

	def __init__(self, client, save_folder):
		self.client = client
		self.save_folder = save_folder
		
		self.ibb = IBB(client, self)
		
		self.sessions = {}
		
	#---------------------------------------------------------------------------------------------------------------------------------#
        def new_send_session(self, to_jid, file_name) :
		file_info = os.path.split(file_name) 
		session = FileSendSession(self, self.client.jid, to_jid, file_info[0], file_info[1])
		return session
		
	def send_si_request(self, session) :
		'''
		<iq type='set' id='offer1' to='[email protected]/resource'>
			<si xmlns='http://jabber.org/protocol/si' id='a0' mime-type='text/plain' profile='http://jabber.org/protocol/si/profile/file-transfer'>
			<file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='test.txt' size='1022' hash='552da749930852c69ae5d2141d3766b1' date='1969-07-21T02:56:15Z'>
			<desc>This is a test. If this were a real file...</desc>
			</file>
			<feature xmlns='http://jabber.org/protocol/feature-neg'>
			<x xmlns='jabber:x:data' type='form'>
			<field var='stream-method' type='list-single'>
			<option><value>>>http://jabber.org/protocol/bytestreams</value></option>
			<option><value>>>http://jabber.org/protocol/ibb</value></option>
			</field>
			</x>
			</feature>
			</si>
		</iq>
		'''
		
		stream = self.client.get_stream()
		
		#new_id = stream.generate_id()
		iq = Iq(None, session.jid, session.to_jid, "set", session.sid)
		si_node = iq.add_new_content(SI_NS, 'si')
		si_node.setProp("id", session.sid)
		si_node.setProp("mime-type", 'application/octet-stream')
		si_node.setProp("profile", FILE_TRANSFER_NS)
	
		file_node = si_node.newChild(None,"file",None)
		file_node.setProp("xmlns", FILE_TRANSFER_NS)
		file_node.setProp("name", to_utf8(session.file_name))
		file_node.setProp("size", to_utf8(session.file_size))
	
		feature_node = si_node.newChild(None, "feature", None)
		feature_node.setProp("xmlns", FEATURE_NS)
        
		form = Form()
		form.add_field( name = 'stream-method', field_type = 'list-single', 
                        #options = [Option('http://jabber.org/protocol/bytestreams', None), Option('http://jabber.org/protocol/ibb', None)])
			options = [Option('http://jabber.org/protocol/ibb', None)])
		form.as_xml(feature_node)
		stream.set_response_handlers(iq, self.received_si_success, self.received_si_error)
		stream.send(iq)
		
		self.sessions[session.sid] = session
		
	def received_si_success(self, stanza) :
		id = stanza.get_id()
		session = self.sessions[id]
		session.transfer = self.ibb
		#session.transfer = self.socks5
		session.open_request()
			
	def received_si_error(self, stanza) :
		id = stanza.get_id()
		del self.sessions[id]	
		
	#---------------------------------------------------------------------------------------------------------------------------------#
        
	def received_si_request(self, stanza) :
		'''
		should response :
		<iq type='result' to='[email protected]/resource' id='offer1'>
			<si xmlns='http://jabber.org/protocol/si'>
			<file xmlns='http://jabber.org/protocol/si/profile/file-transfer'/>
			<feature xmlns='http://jabber.org/protocol/feature-neg'>
				<x xmlns='jabber:x:data' type='submit'>
					<field var='stream-method'>
						<value>http://jabber.org/protocol/bytestreams</value>
					</field>
				</x>
			</feature>
			</si>
		</iq>
		'''
		from_jid = stanza.get_from()
		sinode = stanza.get_query()
		sid = from_utf8(sinode.prop('id'))
		node = sinode.children
		while node :
			if node.ns() :
				ns = get_node_ns_uri(node)
				if  ns == FILE_TRANSFER_NS :
					filenode = node
				elif ns == FEATURE_NS :
					featurenode = node
			node = node.next
		
		filename = from_utf8(filenode.prop('name'))
		filesize = int(filenode.prop('size'))
		
		session = FileReceiveSession(self, sid, self.client.jid, from_jid, self.save_folder, filename, filesize, self.ibb)
		session.stanza = stanza.copy()
		self.sessions[str(session)] = session
		
		evt = FileTransferEvent(self, session, 'open')
		self.client.evtHandler.ProcessEvent(evt)
        
	def send_si_response(self, session, accepted) : 	
		stanza = session.stanza
		session.stanza = None
		if accepted :
			iq = stanza.make_result_response()
			si_node = iq.add_new_content(SI_NS, 'si')
			
			file_node = si_node.newChild(None,"file",None)
			file_node.setProp("xmlns", FILE_TRANSFER_NS)
			
			feature_node = si_node.newChild(None, "feature", None)
			feature_node.setProp("xmlns", FEATURE_NS)
	        
			form = Form('submit')
			form.add_field(name = 'stream-method',  
	                        options = [Option(session.transfer.NS, None)]) 
				#options = [Option('http://jabber.org/protocol/ibb', None)])
			form.as_xml(feature_node)
		else :
			iq = stanza.make_error_response('not-acceptable')
		
		self.client.get_stream().send(iq)
		#print iq.serialize()
		
	#---------------------------------------------------------------------------------------------------------------------------------#
        
	def get_iq_set_handlers(self):
		return [
			("si", "http://jabber.org/protocol/si", self.received_si_request)
		]

	def get_iq_get_handlers(self):
		return []
	
	#---------------------------------------------------------------------------------------------------------------------------------#
        def get_session(self, to_jid, sid) :
		if sid in self.sessions :
			return self.sessions[sid]
		key = '%s-%s' % (to_jid.bare().as_unicode(), sid)
		if key in self.sessions :
			return self.sessions[key]
		else :
			return None
			
	def remove_session(self, session) :
		key = str(session)
		if key in self.sessions :
			del self.sessions[key]
		else :
			print "error in remove session : ", key
			
	def new_sid(self) :
		return "send-%i" % (time.time(),)
示例#10
0
class MsgHandler(object):
    """Handlers for presence and message stanzas are implemented here.
    """

    implements(IMessageHandlersProvider, IPresenceHandlersProvider)

    def __init__(self, client):
        """Just remember who created this."""
        self.client = client

    def get_message_handlers(self):
        """Return list of (message_type, message_handler) tuples.

        The handlers returned will be called when matching message is received
        in a client session."""
        return [
            ("normal", self.message),
        ]

    def get_presence_handlers(self):
        """Return list of (presence_type, presence_handler) tuples.

        The handlers returned will be called when matching presence stanza is
        received in a client session."""
        return [
            (None, self.presence),
            ("unavailable", self.presence),
            ("subscribe", self.presence_control),
            ("subscribed", self.presence_control),
            ("unsubscribe", self.presence_control),
            ("unsubscribed", self.presence_control),
        ]

    # def message(self,stanza):
    #     """Message handler for the component.

    #     Echoes the message back if its type is not 'error' or
    #     'headline', also sets own presence status to the message body. Please
    #     note that all message types but 'error' will be passed to the handler
    #     for 'normal' message unless some dedicated handler process them.

    #     :returns: `True` to indicate, that the stanza should not be processed
    #     any further."""
    #     subject=stanza.get_subject()
    #     body=stanza.get_body()
    #     t=stanza.get_type()
    #     print u'Message from %s received.' % (unicode(stanza.get_from(),)),
    #     if subject:
    #         print u'Subject: "%s".' % (subject,),
    #     if body:
    #         print u'Body: "%s".' % (body,),
    #     if t:
    #         print u'Type: "%s".' % (t,)
    #     else:
    #         print u'Type: "normal".'
    #     if stanza.get_type()=="headline":
    #         # 'headline' messages should never be replied to
    #         return True
    #     if subject:
    #         subject=u"Re: "+subject
    #     m=Message(
    #         to_jid=stanza.get_from(),
    #         from_jid=stanza.get_to(),
    #         stanza_type=stanza.get_type(),
    #         subject=subject,
    #         body=body)
    #     if body:
    #         p = Presence(status=body)
    #         return [m, p]
    #     return m

    def message(self, stanza):
        if stanza.get_type() == 'chat':
            im_tcp_tunneler.handle_message(stanza.get_from_jid().as_unicode(),
                                           stanza.get_to_jid().as_unicode(),
                                           stanza.get_body())
        return True

    def presence(self, stanza):
        """Handle 'available' (without 'type') and 'unavailable' <presence/>."""
        msg = u"%s has become " % (stanza.get_from())
        t = stanza.get_type()
        if t == "unavailable":
            msg += u"unavailable"
        else:
            msg += u"available"

        show = stanza.get_show()
        if show:
            msg += u"(%s)" % (show, )

        status = stanza.get_status()
        if status:
            msg += u": " + status
        print msg

    def presence_control(self, stanza):
        """Handle subscription control <presence/> stanzas -- acknowledge
        them."""
        msg = unicode(stanza.get_from())
        t = stanza.get_type()
        if t == "subscribe":
            msg += u" has requested presence subscription."
        elif t == "subscribed":
            msg += u" has accepted our presence subscription request."
        elif t == "unsubscribe":
            msg += u" has canceled his subscription of our."
        elif t == "unsubscribed":
            msg += u" has canceled our subscription of his presence."

        print msg

        return stanza.make_accept_response()