Beispiel #1
0
 def start_file_transfer(self, jid, file_props, request=False):
     logger.info("start file transfer with file: %s" % file_props)
     contact = gajim.contacts.get_contact_with_highest_priority(self.name,
         gajim.get_jid_without_resource(jid))
     if gajim.contacts.is_gc_contact(self.name,jid):
         gcc = jid.split('/')
         if len(gcc) == 2:
             contact = gajim.contacts.get_gc_contact(self.name, gcc[0], gcc[1])
     if contact is None:
         return
     use_security = contact.supports(nbxmpp.NS_JINGLE_XTLS)
     jingle = JingleSession(self, weinitiate=True, jid=jid, werequest=request)
     # this is a file transfer
     jingle.session_type_FT = True
     self._sessions[jingle.sid] = jingle
     file_props.sid = jingle.sid
     if contact.supports(nbxmpp.NS_JINGLE_BYTESTREAM):
         transport = JingleTransportSocks5()
     elif contact.supports(nbxmpp.NS_JINGLE_IBB):
         transport = JingleTransportIBB()
     c = JingleFileTransfer(jingle, transport=transport,
         file_props=file_props, use_security=use_security)
     file_props.algo = self.__hash_support(contact)
     jingle.add_content('file' + helpers.get_random_string_16(), c)
     jingle.start_session()
     return c.transport.sid
Beispiel #2
0
 def __on_transport_info(self, stanza, content, error, action):
     log.info("__on_transport_info")
     candError = content.getTag('transport').getTag('candidate-error')
     candUsed  = content.getTag('transport').getTag('candidate-used')
     if (candError or candUsed) and \
             self.state >= STATE_CAND_SENT_AND_RECEIVED:
         raise nbxmpp.NodeProcessed
     if candError:
         if not gajim.socks5queue.listener.connections:
             gajim.socks5queue.listener.disconnect()
         self.nominated_cand['peer-cand'] = False
         if self.state == STATE_CAND_SENT:
             if not self.nominated_cand['our-cand'] and \
                not self.nominated_cand['peer-cand']:
                 if not self.weinitiate:
                     return
                 self.__state_changed(STATE_TRANSPORT_REPLACE)
             else:
                 response = stanza.buildReply('result')
                 response.delChild(response.getQuery())
                 self.session.connection.connection.send(response)
                 self.__state_changed(STATE_TRANSFERING)
                 raise nbxmpp.NodeProcessed
         else:
             args = {'candError' : True}
             self.__state_changed(STATE_CAND_RECEIVED, args)
         return
     if candUsed:
         streamhost_cid = candUsed.getAttr('cid')
         streamhost_used = None
         for cand in self.transport.candidates:
             if cand['candidate_id'] == streamhost_cid:
                 streamhost_used = cand
                 break
         if streamhost_used == None or streamhost_used['type'] == 'proxy':
             if gajim.socks5queue.listener and \
             not gajim.socks5queue.listener.connections:
                 gajim.socks5queue.listener.disconnect()
     if content.getTag('transport').getTag('activated'):
         self.state = STATE_TRANSFERING
         jid = gajim.get_jid_without_resource(self.session.ourjid)
         gajim.socks5queue.send_file(self.file_props,
             self.session.connection.name, 'client')
         return
     args = {'content' : content,
             'sendCand' : False}
     if self.state == STATE_CAND_SENT:
         self.__state_changed(STATE_CAND_SENT_AND_RECEIVED, args)
         self.__state_changed(STATE_TRANSFERING)
         raise nbxmpp.NodeProcessed
     else:
         self.__state_changed(STATE_CAND_RECEIVED, args)
Beispiel #3
0
 def __send_hash(self):
     # Send hash in a session info
     checksum = nbxmpp.Node(tag='checksum', payload=[nbxmpp.Node(tag='file',
         payload=[self._calcHash()])])
     checksum.setNamespace(nbxmpp.NS_JINGLE_FILE_TRANSFER)
     self.session.__session_info(checksum )
     pjid = gajim.get_jid_without_resource(self.session.peerjid)
     file_info = {'name' : self.file_props.name,
                  'file-name' : self.file_props.file_name,
                  'hash' : self.file_props.hash_,
                  'size' : self.file_props.size,
                  'date' : self.file_props.date,
                  'peerjid' : pjid
                 }
     self.session.connection.set_file_info(file_info)
Beispiel #4
0
 def save_if_not_exists(self, with_, direction, tim, msg='', nick=None):
     if tim:
         time_col = int(float(time.mktime(tim)))
     else:
         time_col = int(float(time.time()))
     if not msg:
         return
     if self.jid_is_from_pm(with_) or nick:
         # It's a groupchat message
         if nick:
             # It's a message from a groupchat occupent
             type_ = 'gc_msg'
             with_ = with_ + '/' + nick
         else:
             # It's a server message message, we don't log them
             return
     else:
         if direction == 'from':
             type_ = 'chat_msg_recv'
         elif direction == 'to':
             type_ = 'chat_msg_sent'
     jid_id = self.get_jid_id(with_)
     where_sql = 'jid_id = %s AND message=?' % jid_id
     if type_ == 'gc_msg':
         # We cannot differentiate gc message and pm messages, so look in
         # both logs
         with_2 = gajim.get_jid_without_resource(with_)
         if with_ != with_2:
             jid_id2 = self.get_jid_id(with_2)
             where_sql = 'jid_id in (%s, %s) AND message=?' % (jid_id,
                 jid_id2)
     start_time = time_col - 300 # 5 minutes arrount given time
     end_time = time_col + 300 # 5 minutes arrount given time
     self.cur.execute('''
         SELECT log_line_id FROM logs
         WHERE (%s)
         AND time BETWEEN %d AND %d
         ORDER BY time
         ''' % (where_sql, start_time, end_time), (msg,))
     results = self.cur.fetchall()
     if results:
         log.debug('Log already in DB, ignoring it')
         return
     log.debug('New log received from server archives, storing it')
     self.write(type_, with_, message=msg, tim=tim)
Beispiel #5
0
 def __on_session_accept(self, stanza, content, error, action):
     log.info("__on_session_accept")
     con = self.session.connection
     security = content.getTag('security')
     if not security: # responder can not verify our fingerprint
         self.use_security = False
     else:
         fingerprint = security.getTag('fingerprint')
         if fingerprint:
             fingerprint = fingerprint.getData()
             self.x509_fingerprint = fingerprint
             if not jingle_xtls.check_cert(gajim.get_jid_without_resource(
             self.session.responder), fingerprint):
                 id_ = jingle_xtls.send_cert_request(con,
                     self.session.responder)
                 jingle_xtls.key_exchange_pend(id_,
                     self.continue_session_accept, [stanza])
                 raise nbxmpp.NodeProcessed
     self.continue_session_accept(stanza)
Beispiel #6
0
 def _fill_content(self, content):
     description_node = nbxmpp.simplexml.Node(tag=nbxmpp.NS_JINGLE_FILE_TRANSFER + " description")
     if self.session.werequest:
         simode = nbxmpp.simplexml.Node(tag="request")
     else:
         simode = nbxmpp.simplexml.Node(tag="offer")
     file_tag = simode.setTag("file")
     if self.file_props.name:
         node = nbxmpp.simplexml.Node(tag="name")
         node.addData(self.file_props.name)
         file_tag.addChild(node=node)
     if self.file_props.date:
         node = nbxmpp.simplexml.Node(tag="date")
         node.addData(self.file_props.date)
         file_tag.addChild(node=node)
     if self.file_props.size:
         node = nbxmpp.simplexml.Node(tag="size")
         node.addData(self.file_props.size)
         file_tag.addChild(node=node)
     if self.file_props.type_ == "r":
         if self.file_props.hash_:
             h = file_tag.addChild(
                 "hash",
                 attrs={"algo": self.file_props.algo},
                 namespace=nbxmpp.NS_HASHES,
                 payload=self.file_props.hash_,
             )
     else:
         # if the file is less than 10 mb, then it is small
         # lets calculate it right away
         if self.file_props.size < 10000000 and not self.file_props.hash_:
             h = self._calcHash()
             if h:
                 file_tag.addChild(node=h)
             pjid = gajim.get_jid_without_resource(self.session.peerjid)
             file_info = {
                 "name": self.file_props.name,
                 "file-name": self.file_props.file_name,
                 "hash": self.file_props.hash_,
                 "size": self.file_props.size,
                 "date": self.file_props.date,
                 "peerjid": pjid,
             }
             self.session.connection.set_file_info(file_info)
     desc = file_tag.setTag("desc")
     if self.file_props.desc:
         desc.setData(self.file_props.desc)
     description_node.addChild(node=simode)
     if self.use_security:
         security = nbxmpp.simplexml.Node(tag=nbxmpp.NS_JINGLE_XTLS + " security")
         certpath = os.path.join(gajim.MY_CERT_DIR, SELF_SIGNED_CERTIFICATE) + ".cert"
         cert = load_cert_file(certpath)
         if cert:
             try:
                 digest_algo = cert.get_signature_algorithm().split("With")[0]
             except AttributeError, e:
                 # Old py-OpenSSL is missing get_signature_algorithm
                 digest_algo = "sha256"
             security.addChild("fingerprint").addData(cert.digest(digest_algo))
             for m in ("x509",):  # supported authentication methods
                 method = nbxmpp.simplexml.Node(tag="method")
                 method.setAttr("name", m)
                 security.addChild(node=method)
             content.addChild(node=security)
Beispiel #7
0
def get_jid_from_iq(iq_obj):
    '''return the jid (without resource) from an iq as unicode'''
    jid = get_full_jid_from_iq(iq_obj)
    return gajim.get_jid_without_resource(jid)
Beispiel #8
0
def get_jid_from_iq(iq_obj):
	'''return the jid (without resource) from an iq as unicode'''
	jid = get_full_jid_from_iq(iq_obj)
	return gajim.get_jid_without_resource(jid)
Beispiel #9
0
 def __on_session_initiate(self, stanza, jingle, error, action):
     """
     We got a jingle session request from other entity, therefore we are the
     receiver... Unpack the data, inform the user
     """
     if self.state != JingleStates.ended:
         raise OutOfOrder
     self.initiator = jingle['initiator']
     self.responder = self.ourjid
     self.peerjid = self.initiator
     self.accepted = False   # user did not accept this session yet
     # TODO: If the initiator is unknown to the receiver (e.g., via presence
     # subscription) and the receiver has a policy of not communicating via
     # Jingle with unknown entities, it SHOULD return a <service-unavailable/>
     # error.
     # Lets check what kind of jingle session does the peer want
     contents, contents_rejected, reason_txt = self.__parse_contents(jingle)
     # If we are not receivin a file
     # Check if there's already a session with this user:
     if contents[0][0] != 'file':
         for session in self.connection.iter_jingle_sessions(self.peerjid):
             if not session is self:
                 reason = nbxmpp.Node('reason')
                 alternative_session = reason.setTag('alternative-session')
                 alternative_session.setTagData('sid', session.sid)
                 self.__ack(stanza, jingle, error, action)
                 self._session_terminate(reason)
                 raise nbxmpp.NodeProcessed
     else:
         # Stop if we don't have the requested file or the peer is not
         # allowed to request the file
         request = \
              jingle.getTag('content').getTag('description').getTag('request')
         if request:
             self.request = True
             h = request.getTag('file').getTag('hash')
             h = h.getData() if h else None
             n = request.getTag('file').getTag('name')
             n = n.getData() if n else None
             pjid = gajim.get_jid_without_resource(self.peerjid)
             file_info = self.connection.get_file_info(pjid, h, n,
                                                  self.connection.name)
             if not file_info:
                 log.warning('The peer ' + pjid + \
                             ' is requesting a ' + \
                             'file that we dont have or ' + \
                             'it is not allowed to request')
                 self.decline_session()
                 raise nbxmpp.NodeProcessed
     # If there's no content we understand...
     if not contents:
         # TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate
         reason = nbxmpp.Node('reason')
         reason.setTag(reason_txt)
         self.__ack(stanza, jingle, error, action)
         self._session_terminate(reason)
         raise nbxmpp.NodeProcessed
     self.state = JingleStates.pending
     # Send event about starting a session
     gajim.nec.push_incoming_event(JingleRequestReceivedEvent(None,
         conn=self.connection, jingle_session=self, contents=contents))
Beispiel #10
0
    def __start_SOCK5_transfer(self):
        # It tells wether we start the transfer as client or server
        mode = None
        if self.jft.isOurCandUsed():
            mode = 'client'
            streamhost_used = self.jft.nominated_cand['our-cand']
            gajim.socks5queue.remove_server(self.jft.file_props.sid)
        else:
            mode = 'server'
            streamhost_used = self.jft.nominated_cand['peer-cand']
            gajim.socks5queue.remove_client(self.jft.file_props.sid)
#            our_cand = self.jft.nominated_cand['our-cand']
#            gajim.socks5queue.remove_receiver(our_cand['idx'])
        if streamhost_used['type'] == 'proxy':
            self.jft.file_props.is_a_proxy = True
            if self.jft.file_props.type_ == 's' and self.jft.weinitiate:
                self.jft.file_props.proxy_sender = streamhost_used['initiator']
                self.jft.file_props.proxy_receiver = streamhost_used['target']
            else:
                self.jft.file_props.proxy_sender = streamhost_used['target']
                self.jft.file_props.proxy_receiver = streamhost_used[
                    'initiator']
            if self.jft.file_props.type_ == 's':
                s = gajim.socks5queue.senders
                for sender in s:
                    if s[sender].host == streamhost_used['host'] and \
                    s[sender].connected:
                        return
            elif self.jft.file_props.type_ == 'r':
                r = gajim.socks5queue.readers
                for reader in r:
                    if r[reader].host == streamhost_used['host'] and \
                    r[reader].connected:
                        return
            else:
                raise TypeError
            self.jft.file_props.streamhost_used = True
            streamhost_used['sid'] = self.jft.file_props.sid
            self.jft.file_props.streamhosts = []
            self.jft.file_props.streamhosts.append(streamhost_used)
            self.jft.file_props.proxyhosts = []
            self.jft.file_props.proxyhosts.append(streamhost_used)
            if self.jft.file_props.type_ == 's':
                gajim.socks5queue.idx += 1
                idx = gajim.socks5queue.idx
                sockobj = Socks5SenderClient(gajim.idlequeue, idx,
                    gajim.socks5queue, _sock=None,
                    host=str(streamhost_used['host']),
                    port=int(streamhost_used['port']), fingerprint=None,
                    connected=False, file_props=self.jft.file_props)
            else:
                sockobj = Socks5ReceiverClient(gajim.idlequeue, streamhost_used,
                    sid=self.jft.file_props.sid,
                    file_props=self.jft.file_props, fingerprint=None)
            sockobj.proxy = True
            sockobj.streamhost = streamhost_used
            gajim.socks5queue.add_sockobj(self.jft.session.connection.name,
                sockobj)
            streamhost_used['idx'] = sockobj.queue_idx
            # If we offered the nominated candidate used, we activate
            # the proxy
            if not self.jft.isOurCandUsed():
                gajim.socks5queue.on_success[self.jft.file_props.sid] = \
                self.jft.transport._on_proxy_auth_ok
            # TODO: add on failure
        else:
            jid = gajim.get_jid_without_resource(self.jft.session.ourjid)
            gajim.socks5queue.send_file(self.jft.file_props,
                self.jft.session.connection.name, mode)