mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-06 11:00:13 +02:00
5dcb48831f
apksigner v0.7 (build-tools 26.0.1), Google made it require that the AndroidManifest.xml was present in the archive before it verifies the signature. So this needs to stick with the jarsigner hack for JARs.
127 lines
4.9 KiB
Python
Executable File
127 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import inspect
|
|
import optparse
|
|
import os
|
|
import sys
|
|
import unittest
|
|
import zipfile
|
|
from unittest.mock import patch
|
|
|
|
import requests
|
|
|
|
localmodule = os.path.realpath(
|
|
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..'))
|
|
print('localmodule: ' + localmodule)
|
|
if localmodule not in sys.path:
|
|
sys.path.insert(0, localmodule)
|
|
|
|
import fdroidserver.common
|
|
import fdroidserver.index
|
|
import fdroidserver.signindex
|
|
|
|
|
|
GP_FINGERPRINT = 'B7C2EEFD8DAC7806AF67DFCD92EB18126BC08312A7F2D6F3862E46013C7A6135'
|
|
|
|
|
|
class IndexTest(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
fdroidserver.common.config = None
|
|
config = fdroidserver.common.read_config(fdroidserver.common.options)
|
|
config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner')
|
|
fdroidserver.common.config = config
|
|
fdroidserver.signindex.config = config
|
|
|
|
@staticmethod
|
|
def test_verify_jar_signature_succeeds():
|
|
basedir = os.path.dirname(__file__)
|
|
source_dir = os.path.join(basedir, 'signindex')
|
|
for f in ('testy.jar', 'guardianproject.jar'):
|
|
testfile = os.path.join(source_dir, f)
|
|
fdroidserver.common.verify_jar_signature(testfile)
|
|
|
|
def test_verify_jar_signature_fails(self):
|
|
basedir = os.path.dirname(__file__)
|
|
source_dir = os.path.join(basedir, 'signindex')
|
|
testfile = os.path.join(source_dir, 'unsigned.jar')
|
|
with self.assertRaises(fdroidserver.index.VerificationException):
|
|
fdroidserver.common.verify_jar_signature(testfile)
|
|
|
|
def test_get_public_key_from_jar_succeeds(self):
|
|
basedir = os.path.dirname(__file__)
|
|
source_dir = os.path.join(basedir, 'signindex')
|
|
for f in ('testy.jar', 'guardianproject.jar'):
|
|
testfile = os.path.join(source_dir, f)
|
|
jar = zipfile.ZipFile(testfile)
|
|
_, fingerprint = fdroidserver.index.get_public_key_from_jar(jar)
|
|
# comparing fingerprints should be sufficient
|
|
if f == 'testy.jar':
|
|
self.assertTrue(fingerprint ==
|
|
'818E469465F96B704E27BE2FEE4C63AB' +
|
|
'9F83DDF30E7A34C7371A4728D83B0BC1')
|
|
if f == 'guardianproject.jar':
|
|
self.assertTrue(fingerprint == GP_FINGERPRINT)
|
|
|
|
def test_get_public_key_from_jar_fails(self):
|
|
basedir = os.path.dirname(__file__)
|
|
source_dir = os.path.join(basedir, 'signindex')
|
|
testfile = os.path.join(source_dir, 'unsigned.jar')
|
|
jar = zipfile.ZipFile(testfile)
|
|
with self.assertRaises(fdroidserver.index.VerificationException):
|
|
fdroidserver.index.get_public_key_from_jar(jar)
|
|
|
|
def test_download_repo_index_no_fingerprint(self):
|
|
with self.assertRaises(fdroidserver.index.VerificationException):
|
|
fdroidserver.index.download_repo_index("http://example.org")
|
|
|
|
def test_download_repo_index_no_jar(self):
|
|
with self.assertRaises(requests.exceptions.HTTPError):
|
|
fdroidserver.index.download_repo_index("http://example.org?fingerprint=nope")
|
|
|
|
@patch('requests.head')
|
|
def test_download_repo_index_same_etag(self, head):
|
|
url = 'http://example.org?fingerprint=test'
|
|
etag = '"4de5-54d840ce95cb9"'
|
|
|
|
head.return_value.headers = {'ETag': etag}
|
|
index, new_etag = fdroidserver.index.download_repo_index(url, etag=etag)
|
|
|
|
self.assertIsNone(index)
|
|
self.assertEqual(etag, new_etag)
|
|
|
|
@patch('requests.get')
|
|
@patch('requests.head')
|
|
def test_download_repo_index_new_etag(self, head, get):
|
|
url = 'http://example.org?fingerprint=' + GP_FINGERPRINT
|
|
etag = '"4de5-54d840ce95cb9"'
|
|
|
|
# fake HTTP answers
|
|
head.return_value.headers = {'ETag': 'new_etag'}
|
|
get.return_value.headers = {'ETag': 'new_etag'}
|
|
get.return_value.status_code = 200
|
|
testfile = os.path.join(os.path.dirname(__file__), 'signindex', 'guardianproject-v1.jar')
|
|
with open(testfile, 'rb') as file:
|
|
get.return_value.content = file.read()
|
|
|
|
index, new_etag = fdroidserver.index.download_repo_index(url, etag=etag)
|
|
|
|
# assert that the index was retrieved properly
|
|
self.assertEqual('Guardian Project Official Releases', index['repo']['name'])
|
|
self.assertEqual(GP_FINGERPRINT, index['repo']['fingerprint'])
|
|
self.assertTrue(len(index['repo']['pubkey']) > 500)
|
|
self.assertEqual(10, len(index['apps']))
|
|
self.assertEqual(10, len(index['packages']))
|
|
self.assertEqual('new_etag', new_etag)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = optparse.OptionParser()
|
|
parser.add_option("-v", "--verbose", action="store_true", default=False,
|
|
help="Spew out even more information than normal")
|
|
(fdroidserver.common.options, args) = parser.parse_args(['--verbose'])
|
|
|
|
newSuite = unittest.TestSuite()
|
|
newSuite.addTest(unittest.makeSuite(IndexTest))
|
|
unittest.main()
|