mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-06 11:00:13 +02:00
Merge branch 'reproducible-bug' into 'master'
Fix reproducible builds See merge request fdroid/fdroidserver!505
This commit is contained in:
commit
00971941fd
@ -828,28 +828,12 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext
|
||||
|
||||
if common.get_file_extension(src) == 'apk':
|
||||
vercode, version = get_metadata_from_apk(app, build, src)
|
||||
if (version != build.versionName or vercode != build.versionCode):
|
||||
if version != build.versionName or vercode != build.versionCode:
|
||||
raise BuildException(("Unexpected version/version code in output;"
|
||||
" APK: '%s' / '%s', "
|
||||
" Expected: '%s' / '%s'")
|
||||
% (version, str(vercode), build.versionName,
|
||||
str(build.versionCode)))
|
||||
else:
|
||||
vercode = build.versionCode
|
||||
version = build.versionName
|
||||
|
||||
# Add information for 'fdroid verify' to be able to reproduce the build
|
||||
# environment.
|
||||
if onserver:
|
||||
metadir = os.path.join(tmp_dir, 'META-INF')
|
||||
if not os.path.exists(metadir):
|
||||
os.mkdir(metadir)
|
||||
homedir = os.path.expanduser('~')
|
||||
for fn in ['buildserverid', 'fdroidserverid']:
|
||||
shutil.copyfile(os.path.join(homedir, fn),
|
||||
os.path.join(metadir, fn))
|
||||
subprocess.call(['jar', 'uf', os.path.abspath(src),
|
||||
'META-INF/' + fn], cwd=tmp_dir)
|
||||
|
||||
# Copy the unsigned apk to our destination directory for further
|
||||
# processing (by publish.py)...
|
||||
|
@ -2360,7 +2360,7 @@ def place_srclib(root_dir, number, libpath):
|
||||
o.write('android.library.reference.%d=%s\n' % (number, relpath))
|
||||
|
||||
|
||||
apk_sigfile = re.compile(r'META-INF/[0-9A-Za-z_\-]+\.(SF|RSA|DSA|EC)')
|
||||
APK_SIGNATURE_FILES = re.compile(r'META-INF/[0-9A-Za-z_\-]+\.(SF|RSA|DSA|EC)')
|
||||
|
||||
|
||||
def signer_fingerprint_short(sig):
|
||||
@ -2515,7 +2515,7 @@ def apk_strip_signatures(signed_apk, strip_manifest=False):
|
||||
with ZipFile(tmp_apk, 'r') as in_apk:
|
||||
with ZipFile(signed_apk, 'w') as out_apk:
|
||||
for info in in_apk.infolist():
|
||||
if not apk_sigfile.match(info.filename):
|
||||
if not APK_SIGNATURE_FILES.match(info.filename):
|
||||
if strip_manifest:
|
||||
if info.filename != 'META-INF/MANIFEST.MF':
|
||||
buf = in_apk.read(info.filename)
|
||||
@ -2546,7 +2546,7 @@ def apk_implant_signatures(apkpath, signaturefile, signedfile, manifest):
|
||||
info.create_system = 0 # "Windows" aka "FAT", what Android SDK uses
|
||||
out_apk.writestr(info, buf)
|
||||
for info in in_apk.infolist():
|
||||
if not apk_sigfile.match(info.filename):
|
||||
if not APK_SIGNATURE_FILES.match(info.filename):
|
||||
if info.filename != 'META-INF/MANIFEST.MF':
|
||||
buf = in_apk.read(info.filename)
|
||||
out_apk.writestr(info, buf)
|
||||
@ -2565,7 +2565,7 @@ def apk_extract_signatures(apkpath, outdir, manifest=True):
|
||||
"""
|
||||
with ZipFile(apkpath, 'r') as in_apk:
|
||||
for f in in_apk.infolist():
|
||||
if apk_sigfile.match(f.filename) or \
|
||||
if APK_SIGNATURE_FILES.match(f.filename) or \
|
||||
(manifest and f.filename == 'META-INF/MANIFEST.MF'):
|
||||
newpath = os.path.join(outdir, os.path.basename(f.filename))
|
||||
with open(newpath, 'wb') as out_file:
|
||||
@ -2615,13 +2615,6 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
|
||||
the unsigned one. If the APK given as unsigned actually does have a
|
||||
signature, it will be stripped out and ignored.
|
||||
|
||||
There are two SHA1 git commit IDs that fdroidserver includes in the builds
|
||||
it makes: fdroidserverid and buildserverid. Originally, these were inserted
|
||||
into AndroidManifest.xml, but that makes the build not reproducible. So
|
||||
instead they are included as separate files in the APK's META-INF/ folder.
|
||||
If those files exist in the signed APK, they will be part of the signature
|
||||
and need to also be included in the unsigned APK for it to validate.
|
||||
|
||||
:param signed_apk: Path to a signed apk file
|
||||
:param unsigned_apk: Path to an unsigned apk file expected to match it
|
||||
:param tmp_dir: Path to directory for temporary files
|
||||
@ -2638,8 +2631,7 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
|
||||
with ZipFile(signed_apk, 'r') as signed:
|
||||
meta_inf_files = ['META-INF/MANIFEST.MF']
|
||||
for f in signed.namelist():
|
||||
if apk_sigfile.match(f) \
|
||||
or f in ['META-INF/fdroidserverid', 'META-INF/buildserverid']:
|
||||
if APK_SIGNATURE_FILES.match(f):
|
||||
meta_inf_files.append(f)
|
||||
if len(meta_inf_files) < 3:
|
||||
return "Signature files missing from {0}".format(signed_apk)
|
||||
@ -2652,8 +2644,7 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
|
||||
tmp.writestr(signed.getinfo(filename), signed.read(filename))
|
||||
for info in unsigned.infolist():
|
||||
if info.filename in meta_inf_files:
|
||||
logging.warning('Ignoring %s from %s',
|
||||
info.filename, unsigned_apk)
|
||||
logging.warning('Ignoring %s from %s', info.filename, unsigned_apk)
|
||||
continue
|
||||
if info.filename in tmp.namelist():
|
||||
return "duplicate filename found: " + info.filename
|
||||
@ -2800,7 +2791,7 @@ def compare_apks(apk1, apk2, tmp_dir, log_dir=None):
|
||||
'--max-report-size', '12345678', '--max-diff-block-lines', '100',
|
||||
'--html', htmlfile, '--text', textfile,
|
||||
absapk1, absapk2]) != 0:
|
||||
return("Failed to unpack " + apk1)
|
||||
return("Failed to run diffoscope " + apk1)
|
||||
|
||||
apk1dir = os.path.join(tmp_dir, apk_badchars.sub('_', apk1[0:-4])) # trim .apk
|
||||
apk2dir = os.path.join(tmp_dir, apk_badchars.sub('_', apk2[0:-4])) # trim .apk
|
||||
@ -2808,31 +2799,28 @@ def compare_apks(apk1, apk2, tmp_dir, log_dir=None):
|
||||
if os.path.exists(d):
|
||||
shutil.rmtree(d)
|
||||
os.mkdir(d)
|
||||
os.mkdir(os.path.join(d, 'jar-xf'))
|
||||
os.mkdir(os.path.join(d, 'content'))
|
||||
|
||||
if subprocess.call(['jar', 'xf',
|
||||
os.path.abspath(apk1)],
|
||||
cwd=os.path.join(apk1dir, 'jar-xf')) != 0:
|
||||
return("Failed to unpack " + apk1)
|
||||
if subprocess.call(['jar', 'xf',
|
||||
os.path.abspath(apk2)],
|
||||
cwd=os.path.join(apk2dir, 'jar-xf')) != 0:
|
||||
return("Failed to unpack " + apk2)
|
||||
# extract APK contents for comparision
|
||||
with ZipFile(absapk1, 'r') as f:
|
||||
f.extractall(path=os.path.join(apk1dir, 'content'))
|
||||
with ZipFile(absapk2, 'r') as f:
|
||||
f.extractall(path=os.path.join(apk2dir, 'content'))
|
||||
|
||||
if set_command_in_config('apktool'):
|
||||
if subprocess.call([config['apktool'], 'd', os.path.abspath(apk1), '--output', 'apktool'],
|
||||
if subprocess.call([config['apktool'], 'd', absapk1, '--output', 'apktool'],
|
||||
cwd=apk1dir) != 0:
|
||||
return("Failed to unpack " + apk1)
|
||||
if subprocess.call([config['apktool'], 'd', os.path.abspath(apk2), '--output', 'apktool'],
|
||||
return("Failed to run apktool " + apk1)
|
||||
if subprocess.call([config['apktool'], 'd', absapk2, '--output', 'apktool'],
|
||||
cwd=apk2dir) != 0:
|
||||
return("Failed to unpack " + apk2)
|
||||
return("Failed to run apktool " + apk2)
|
||||
|
||||
p = FDroidPopen(['diff', '-r', apk1dir, apk2dir], output=False)
|
||||
lines = p.output.splitlines()
|
||||
if len(lines) != 1 or 'META-INF' not in lines[0]:
|
||||
if set_command_in_config('meld'):
|
||||
p = FDroidPopen([config['meld'], apk1dir, apk2dir], output=False)
|
||||
return("Unexpected diff output - " + p.output)
|
||||
return("Unexpected diff output:\n" + p.output)
|
||||
|
||||
# since everything verifies, delete the comparison to keep cruft down
|
||||
shutil.rmtree(apk1dir)
|
||||
|
Loading…
Reference in New Issue
Block a user