check file integrity when transfer is completed
This commit is contained in:
parent
c51fb07d09
commit
5142ebd626
5 changed files with 35 additions and 15 deletions
|
@ -157,7 +157,7 @@ class ConnectionJingle(object):
|
||||||
transport = JingleTransportIBB()
|
transport = JingleTransportIBB()
|
||||||
c = JingleFileTransfer(jingle, transport=transport,
|
c = JingleFileTransfer(jingle, transport=transport,
|
||||||
file_props=file_props, use_security=use_security)
|
file_props=file_props, use_security=use_security)
|
||||||
c.hash_algo = self.__hash_support(contact)
|
jingle.hash_algo = self.__hash_support(contact)
|
||||||
jingle.add_content('file' + helpers.get_random_string_16(), c)
|
jingle.add_content('file' + helpers.get_random_string_16(), c)
|
||||||
jingle.start_session()
|
jingle.start_session()
|
||||||
return c.transport.sid
|
return c.transport.sid
|
||||||
|
|
|
@ -103,9 +103,7 @@ class JingleFileTransfer(JingleContent):
|
||||||
self.media = 'file'
|
self.media = 'file'
|
||||||
self.nominated_cand = {}
|
self.nominated_cand = {}
|
||||||
|
|
||||||
# Hash algorithm that we are using to calculate the integrity of the
|
|
||||||
# file. Could be 'md5', 'sha-1', etc...
|
|
||||||
self.hash_algo = None
|
|
||||||
|
|
||||||
def __on_session_initiate(self, stanza, content, error, action):
|
def __on_session_initiate(self, stanza, content, error, action):
|
||||||
gajim.nec.push_incoming_event(FileRequestReceivedEvent(None,
|
gajim.nec.push_incoming_event(FileRequestReceivedEvent(None,
|
||||||
|
@ -117,14 +115,16 @@ class JingleFileTransfer(JingleContent):
|
||||||
self.hashThread.start()
|
self.hashThread.start()
|
||||||
|
|
||||||
def __calcHash(self):
|
def __calcHash(self):
|
||||||
if self.hash_algo == None:
|
if self.session.hash_algo == None:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
file = open(self.file_props['file-name'], 'r')
|
file = open(self.file_props['file-name'], 'r')
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
h = xmpp.Hashes()
|
h = xmpp.Hashes()
|
||||||
h.calculateHash(self.hash_algo, file)
|
hash = h.calculateHash(self.session.hash_algo, file)
|
||||||
|
self.file_props['hash'] = hash
|
||||||
|
h.addHash(hash, self.session.hash_algo)
|
||||||
checksum = xmpp.Node(tag='checksum',
|
checksum = xmpp.Node(tag='checksum',
|
||||||
payload=[xmpp.Node(tag='file', payload=[h])])
|
payload=[xmpp.Node(tag='file', payload=[h])])
|
||||||
checksum.setNamespace(xmpp.NS_JINGLE_FILE_TRANSFER)
|
checksum.setNamespace(xmpp.NS_JINGLE_FILE_TRANSFER)
|
||||||
|
|
|
@ -98,6 +98,9 @@ class JingleSession(object):
|
||||||
|
|
||||||
|
|
||||||
self.accepted = True # is this session accepted by user
|
self.accepted = True # is this session accepted by user
|
||||||
|
# Hash algorithm that we are using to calculate the integrity of the
|
||||||
|
# file. Could be 'md5', 'sha-1', etc...
|
||||||
|
self.hash_algo = None
|
||||||
self.file_hash = None
|
self.file_hash = None
|
||||||
# callbacks to call on proper contents
|
# callbacks to call on proper contents
|
||||||
# use .prepend() to add new callbacks, especially when you're going
|
# use .prepend() to add new callbacks, especially when you're going
|
||||||
|
@ -424,9 +427,11 @@ class JingleSession(object):
|
||||||
for hash in hashes.getChildren():
|
for hash in hashes.getChildren():
|
||||||
algo = hash.getAttr('algo')
|
algo = hash.getAttr('algo')
|
||||||
if algo in xmpp.Hashes.supported:
|
if algo in xmpp.Hashes.supported:
|
||||||
|
self.hash_algo = algo
|
||||||
data = hash.getData()
|
data = hash.getData()
|
||||||
|
# This only works because there is only one session
|
||||||
|
# per file in jingleFT
|
||||||
self.file_hash = data
|
self.file_hash = data
|
||||||
print data
|
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
self.__send_error(stanza, 'feature-not-implemented', 'unsupported-info', type_='modify')
|
self.__send_error(stanza, 'feature-not-implemented', 'unsupported-info', type_='modify')
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
|
@ -1067,7 +1067,6 @@ class Hashes(Node):
|
||||||
"""
|
"""
|
||||||
hl = None
|
hl = None
|
||||||
hash = None
|
hash = None
|
||||||
|
|
||||||
# file_string can be a string or a file
|
# file_string can be a string or a file
|
||||||
if type(file_string) == str: # if it is a string
|
if type(file_string) == str: # if it is a string
|
||||||
if algo == 'md5':
|
if algo == 'md5':
|
||||||
|
@ -1104,7 +1103,7 @@ class Hashes(Node):
|
||||||
hl.update(line)
|
hl.update(line)
|
||||||
hash = hl.hexdigest()
|
hash = hl.hexdigest()
|
||||||
|
|
||||||
self.addHash(hash, algo)
|
return hash
|
||||||
|
|
||||||
def addHash(self, hash, algo):
|
def addHash(self, hash, algo):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -71,6 +71,7 @@ from session import ChatControlSession
|
||||||
import common.sleepy
|
import common.sleepy
|
||||||
|
|
||||||
from common.xmpp import idlequeue
|
from common.xmpp import idlequeue
|
||||||
|
from common.xmpp import Hashes
|
||||||
from common.zeroconf import connection_zeroconf
|
from common.zeroconf import connection_zeroconf
|
||||||
from common import resolver
|
from common import resolver
|
||||||
from common import caps_cache
|
from common import caps_cache
|
||||||
|
@ -908,6 +909,22 @@ class Interface:
|
||||||
self.last_ftwindow_update = time.time()
|
self.last_ftwindow_update = time.time()
|
||||||
self.instances['file_transfers'].set_progress(file_props['type'],
|
self.instances['file_transfers'].set_progress(file_props['type'],
|
||||||
file_props['sid'], file_props['received-len'])
|
file_props['sid'], file_props['received-len'])
|
||||||
|
def __compare_hashes(self, account, file_props):
|
||||||
|
session = gajim.connections[account].get_jingle_session(jid=None,
|
||||||
|
sid=file_props['session-sid'])
|
||||||
|
h = Hashes()
|
||||||
|
try:
|
||||||
|
file = open(file_props['file-name'], 'r')
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
hash = h.calculateHash(session.hash_algo, file)
|
||||||
|
# If the hash we received and the hash of the file are the same,
|
||||||
|
# then the file is not corrupt
|
||||||
|
if session.file_hash == hash:
|
||||||
|
print "they are te same"
|
||||||
|
# End jingle session
|
||||||
|
if session:
|
||||||
|
session.end_session()
|
||||||
|
|
||||||
def handle_event_file_rcv_completed(self, account, file_props):
|
def handle_event_file_rcv_completed(self, account, file_props):
|
||||||
ft = self.instances['file_transfers']
|
ft = self.instances['file_transfers']
|
||||||
|
@ -922,15 +939,14 @@ class Interface:
|
||||||
|
|
||||||
if file_props['type'] == 'r': # we receive a file
|
if file_props['type'] == 'r': # we receive a file
|
||||||
jid = unicode(file_props['sender'])
|
jid = unicode(file_props['sender'])
|
||||||
|
# Compare hashes in a new thread
|
||||||
|
self.hashThread = Thread(target=self.__compare_hashes,
|
||||||
|
args=(account, file_props))
|
||||||
|
self.hashThread.start()
|
||||||
gajim.socks5queue.remove_receiver(file_props['sid'], True, True)
|
gajim.socks5queue.remove_receiver(file_props['sid'], True, True)
|
||||||
else: # we send a file
|
else: # we send a file
|
||||||
jid = unicode(file_props['receiver'])
|
jid = unicode(file_props['receiver'])
|
||||||
gajim.socks5queue.remove_sender(file_props['sid'], True, True)
|
gajim.socks5queue.remove_sender(file_props['sid'], True, True)
|
||||||
# End jingle session
|
|
||||||
session = gajim.connections[account].get_jingle_session(jid,
|
|
||||||
sid=file_props['session-sid'])
|
|
||||||
if session:
|
|
||||||
session.end_session()
|
|
||||||
|
|
||||||
if helpers.allow_popup_window(account):
|
if helpers.allow_popup_window(account):
|
||||||
if file_props['error'] == 0:
|
if file_props['error'] == 0:
|
||||||
|
|
Loading…
Add table
Reference in a new issue