fetcher: Check integrity of files before saving to disk.
Fetcher will check integrity of files using sha1sum file (and later with digital signatures) before saving them to their original locations.
This commit is contained in:
@@ -57,6 +57,7 @@ class Constants:
|
||||
self.__c.xz_suffix = ".xz"
|
||||
|
||||
self.__c.partial_suffix = ".part"
|
||||
self.__c.temporary_suffix = ".tmp"
|
||||
|
||||
# suffix for auto generated debug packages
|
||||
self.__c.debug_name_suffix = "-dbginfo"
|
||||
|
||||
+9
-7
@@ -105,19 +105,21 @@ class UIHandler:
|
||||
class Fetcher:
|
||||
"""Fetcher can fetch a file from various sources using various
|
||||
protocols."""
|
||||
def __init__(self, url, destdir):
|
||||
def __init__(self, url, destdir, destfile=None):
|
||||
if not isinstance(url, pisi.uri.URI):
|
||||
url = pisi.uri.URI(url)
|
||||
|
||||
if ctx.config.get_option("authinfo"):
|
||||
url.set_auth_info(ctx.config.get_option("authinfo"))
|
||||
|
||||
self.url = url
|
||||
self.destdir = destdir
|
||||
self.archive_file = os.path.join(self.destdir, self.url.filename())
|
||||
self.partial_file = self.archive_file + ctx.const.partial_suffix
|
||||
self.url = url
|
||||
self.destdir = destdir
|
||||
self.destfile = destfile
|
||||
self.progress = None
|
||||
|
||||
self.archive_file = os.path.join(destdir, destfile or url.filename())
|
||||
self.partial_file = os.path.join(self.destdir, self.url.filename()) + ctx.const.partial_suffix
|
||||
|
||||
util.ensure_dirs(self.destdir)
|
||||
|
||||
def fetch (self):
|
||||
@@ -222,7 +224,7 @@ class Fetcher:
|
||||
|
||||
|
||||
# helper function
|
||||
def fetch_url(url, destdir, progress=None):
|
||||
fetch = Fetcher(url, destdir)
|
||||
def fetch_url(url, destdir, progress=None, destfile=None):
|
||||
fetch = Fetcher(url, destdir, destfile)
|
||||
fetch.progress = progress
|
||||
fetch.fetch()
|
||||
|
||||
+22
-4
@@ -108,13 +108,17 @@ class File:
|
||||
|
||||
pisi.util.ensure_dirs(transfer_dir)
|
||||
|
||||
# Check file integrity before saving?
|
||||
check_integrity = sha1sum or sign
|
||||
|
||||
if sha1sum:
|
||||
sha1filename = File.download(pisi.uri.URI(uri.get_uri() + '.sha1sum'), transfer_dir)
|
||||
sha1f = file(sha1filename)
|
||||
newsha1 = sha1f.read().split("\n")[0]
|
||||
|
||||
if uri.is_remote_file() or copylocal:
|
||||
localfile = pisi.util.join_path(transfer_dir, uri.filename())
|
||||
tmpfile = check_integrity and uri.filename() + ctx.const.temporary_suffix
|
||||
localfile = pisi.util.join_path(transfer_dir, tmpfile or uri.filename())
|
||||
|
||||
# TODO: code to use old .sha1sum file, is this a necessary optimization?
|
||||
#oldsha1fn = localfile + '.sha1sum'
|
||||
@@ -128,10 +132,9 @@ class File:
|
||||
|
||||
if uri.is_remote_file():
|
||||
ctx.ui.info(_("Fetching %s") % uri.get_uri(), verbose=True)
|
||||
pisi.fetcher.fetch_url(uri, transfer_dir, ctx.ui.Progress)
|
||||
pisi.fetcher.fetch_url(uri, transfer_dir, ctx.ui.Progress, tmpfile)
|
||||
else:
|
||||
# copy to transfer dir,
|
||||
localfile = pisi.util.join_path(transfer_dir, uri.filename())
|
||||
# copy to transfer dir
|
||||
ctx.ui.info(_("Copying %s to transfer dir") % uri.get_uri(), verbose=True)
|
||||
shutil.copy(uri.get_uri(), transfer_dir)
|
||||
else:
|
||||
@@ -143,10 +146,25 @@ class File:
|
||||
localfile = pisi.util.join_path(transfer_dir, os.path.basename(localfile))
|
||||
shutil.copy(oldfn, localfile)
|
||||
|
||||
def clean_temporary():
|
||||
temp_files = [sha1filename]
|
||||
if check_integrity:
|
||||
temp_files.append(localfile)
|
||||
for filename in temp_files:
|
||||
try:
|
||||
os.unlink(filename)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if sha1sum:
|
||||
if (pisi.util.sha1_file(localfile) != newsha1):
|
||||
clean_temporary()
|
||||
raise Error(_("File integrity of %s compromised.") % uri)
|
||||
|
||||
if check_integrity:
|
||||
shutil.move(localfile, origfile)
|
||||
localfile = origfile
|
||||
|
||||
localfile = File.decompress(localfile, compress)
|
||||
|
||||
return localfile
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import pisi.context as ctx
|
||||
import pisi.archive as archive
|
||||
import pisi.uri
|
||||
import pisi.metadata
|
||||
import pisi.file
|
||||
import pisi.files
|
||||
import pisi.util as util
|
||||
import fetcher
|
||||
@@ -95,7 +96,7 @@ class Package:
|
||||
|
||||
if not os.path.exists(self.filepath):
|
||||
try:
|
||||
fetcher.fetch_url(url, dest, ctx.ui.Progress)
|
||||
pisi.file.File.download(url, dest)
|
||||
except pisi.fetcher.FetchError:
|
||||
# Bug 3465
|
||||
if ctx.get_option('reinstall'):
|
||||
|
||||
Reference in New Issue
Block a user