mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-05 18:50:09 +02:00
Merge branch 'ever-more-fixes' into 'master'
Ever more fixes Closes #395 and #306 See merge request fdroid/fdroidserver!423
This commit is contained in:
commit
463a1b5376
@ -57,6 +57,9 @@ from fdroidserver.exception import FDroidException, VCSException, NoSubmodulesEx
|
|||||||
BuildException, VerificationException
|
BuildException, VerificationException
|
||||||
from .asynchronousfilereader import AsynchronousFileReader
|
from .asynchronousfilereader import AsynchronousFileReader
|
||||||
|
|
||||||
|
# this is the build-tools version, aapt has a separate version that
|
||||||
|
# has to be manually set in test_aapt_version()
|
||||||
|
MINIMUM_AAPT_VERSION = '26.0.0'
|
||||||
|
|
||||||
# A signature block file with a .DSA, .RSA, or .EC extension
|
# A signature block file with a .DSA, .RSA, or .EC extension
|
||||||
CERT_PATH_REGEX = re.compile(r'^META-INF/.*\.(DSA|EC|RSA)$')
|
CERT_PATH_REGEX = re.compile(r'^META-INF/.*\.(DSA|EC|RSA)$')
|
||||||
@ -84,7 +87,7 @@ default_config = {
|
|||||||
'r16': None,
|
'r16': None,
|
||||||
},
|
},
|
||||||
'qt_sdk_path': None,
|
'qt_sdk_path': None,
|
||||||
'build_tools': "25.0.2",
|
'build_tools': MINIMUM_AAPT_VERSION,
|
||||||
'force_build_tools': False,
|
'force_build_tools': False,
|
||||||
'java_paths': None,
|
'java_paths': None,
|
||||||
'ant': "ant",
|
'ant': "ant",
|
||||||
@ -397,13 +400,13 @@ def test_aapt_version(aapt):
|
|||||||
# the Debian package has the version string like "v0.2-23.0.2"
|
# the Debian package has the version string like "v0.2-23.0.2"
|
||||||
too_old = False
|
too_old = False
|
||||||
if '.' in bugfix:
|
if '.' in bugfix:
|
||||||
if LooseVersion(bugfix) < LooseVersion('24.0.0'):
|
if LooseVersion(bugfix) < LooseVersion(MINIMUM_AAPT_VERSION):
|
||||||
too_old = True
|
too_old = True
|
||||||
elif LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.2964546'):
|
elif LooseVersion('.'.join((major, minor, bugfix))) < LooseVersion('0.2.4062713'):
|
||||||
too_old = True
|
too_old = True
|
||||||
if too_old:
|
if too_old:
|
||||||
logging.warning(_("'{aapt}' is too old, fdroid requires build-tools-24.0.0 or newer!")
|
logging.warning(_("'{aapt}' is too old, fdroid requires build-tools-{version} or newer!")
|
||||||
.format(aapt=aapt))
|
.format(aapt=aapt, version=MINIMUM_AAPT_VERSION))
|
||||||
else:
|
else:
|
||||||
logging.warning(_('Unknown version of aapt, might cause problems: ') + output)
|
logging.warning(_('Unknown version of aapt, might cause problems: ') + output)
|
||||||
|
|
||||||
@ -2463,7 +2466,7 @@ def sign_apk(unsigned_path, signed_path, keyalias):
|
|||||||
if get_minSdkVersion_aapt(unsigned_path) < 18:
|
if get_minSdkVersion_aapt(unsigned_path) < 18:
|
||||||
signature_algorithm = ['-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1']
|
signature_algorithm = ['-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1']
|
||||||
else:
|
else:
|
||||||
signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA256']
|
signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256']
|
||||||
|
|
||||||
p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
|
p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
|
||||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||||
|
@ -47,7 +47,7 @@ DISTINGUISHED_NAME = 'CN=Android Debug,O=Android,C=US'
|
|||||||
NIGHTLY = '-nightly'
|
NIGHTLY = '-nightly'
|
||||||
|
|
||||||
|
|
||||||
def _ssh_key_from_debug_keystore():
|
def _ssh_key_from_debug_keystore(keystore=KEYSTORE_FILE):
|
||||||
tmp_dir = tempfile.mkdtemp(prefix='.')
|
tmp_dir = tempfile.mkdtemp(prefix='.')
|
||||||
privkey = os.path.join(tmp_dir, '.privkey')
|
privkey = os.path.join(tmp_dir, '.privkey')
|
||||||
key_pem = os.path.join(tmp_dir, '.key.pem')
|
key_pem = os.path.join(tmp_dir, '.key.pem')
|
||||||
@ -55,7 +55,7 @@ def _ssh_key_from_debug_keystore():
|
|||||||
_config = dict()
|
_config = dict()
|
||||||
common.fill_config_defaults(_config)
|
common.fill_config_defaults(_config)
|
||||||
subprocess.check_call([_config['keytool'], '-importkeystore',
|
subprocess.check_call([_config['keytool'], '-importkeystore',
|
||||||
'-srckeystore', KEYSTORE_FILE, '-srcalias', KEY_ALIAS,
|
'-srckeystore', keystore, '-srcalias', KEY_ALIAS,
|
||||||
'-srcstorepass', PASSWORD, '-srckeypass', PASSWORD,
|
'-srcstorepass', PASSWORD, '-srckeypass', PASSWORD,
|
||||||
'-destkeystore', p12, '-destalias', KEY_ALIAS,
|
'-destkeystore', p12, '-destalias', KEY_ALIAS,
|
||||||
'-deststorepass', PASSWORD, '-destkeypass', PASSWORD,
|
'-deststorepass', PASSWORD, '-destkeypass', PASSWORD,
|
||||||
@ -87,6 +87,8 @@ def main():
|
|||||||
|
|
||||||
parser = ArgumentParser(usage="%(prog)s")
|
parser = ArgumentParser(usage="%(prog)s")
|
||||||
common.setup_global_opts(parser)
|
common.setup_global_opts(parser)
|
||||||
|
parser.add_argument("--keystore", default=KEYSTORE_FILE,
|
||||||
|
help=_("Specify which debug keystore file to use."))
|
||||||
parser.add_argument("--show-secret-var", action="store_true", default=False,
|
parser.add_argument("--show-secret-var", action="store_true", default=False,
|
||||||
help=_("Print the secret variable to the terminal for easy copy/paste"))
|
help=_("Print the secret variable to the terminal for easy copy/paste"))
|
||||||
parser.add_argument("--file", default='app/build/outputs/apk/*.apk',
|
parser.add_argument("--file", default='app/build/outputs/apk/*.apk',
|
||||||
@ -291,19 +293,19 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base,
|
|||||||
shutil.rmtree(os.path.dirname(ssh_private_key_file))
|
shutil.rmtree(os.path.dirname(ssh_private_key_file))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not os.path.isfile(KEYSTORE_FILE):
|
if not os.path.isfile(options.keystore):
|
||||||
androiddir = os.path.dirname(KEYSTORE_FILE)
|
androiddir = os.path.dirname(options.keystore)
|
||||||
if not os.path.exists(androiddir):
|
if not os.path.exists(androiddir):
|
||||||
os.mkdir(androiddir)
|
os.mkdir(androiddir)
|
||||||
logging.info(_('created {path}').format(path=androiddir))
|
logging.info(_('created {path}').format(path=androiddir))
|
||||||
logging.error(_('{path} does not exist! Create it by running:').format(path=KEYSTORE_FILE)
|
logging.error(_('{path} does not exist! Create it by running:').format(path=options.keystore)
|
||||||
+ '\n keytool -genkey -v -keystore ' + KEYSTORE_FILE + ' -storepass android \\'
|
+ '\n keytool -genkey -v -keystore ' + options.keystore + ' -storepass android \\'
|
||||||
+ '\n -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 \\'
|
+ '\n -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 \\'
|
||||||
+ '\n -dname "CN=Android Debug,O=Android,C=US"')
|
+ '\n -dname "CN=Android Debug,O=Android,C=US"')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
ssh_dir = os.path.join(os.getenv('HOME'), '.ssh')
|
ssh_dir = os.path.join(os.getenv('HOME'), '.ssh')
|
||||||
os.makedirs(os.path.dirname(ssh_dir), exist_ok=True)
|
os.makedirs(os.path.dirname(ssh_dir), exist_ok=True)
|
||||||
privkey = _ssh_key_from_debug_keystore()
|
privkey = _ssh_key_from_debug_keystore(options.keystore)
|
||||||
ssh_private_key_file = os.path.join(ssh_dir, os.path.basename(privkey))
|
ssh_private_key_file = os.path.join(ssh_dir, os.path.basename(privkey))
|
||||||
shutil.move(privkey, ssh_private_key_file)
|
shutil.move(privkey, ssh_private_key_file)
|
||||||
shutil.move(privkey + '.pub', ssh_private_key_file + '.pub')
|
shutil.move(privkey + '.pub', ssh_private_key_file + '.pub')
|
||||||
@ -311,10 +313,10 @@ Last updated: {date}'''.format(repo_git_base=repo_git_base,
|
|||||||
shutil.rmtree(os.path.dirname(privkey))
|
shutil.rmtree(os.path.dirname(privkey))
|
||||||
|
|
||||||
if options.show_secret_var:
|
if options.show_secret_var:
|
||||||
with open(KEYSTORE_FILE, 'rb') as fp:
|
with open(options.keystore, 'rb') as fp:
|
||||||
debug_keystore = base64.standard_b64encode(fp.read()).decode('ascii')
|
debug_keystore = base64.standard_b64encode(fp.read()).decode('ascii')
|
||||||
print(_('\n{path} encoded for the DEBUG_KEYSTORE secret variable:')
|
print(_('\n{path} encoded for the DEBUG_KEYSTORE secret variable:')
|
||||||
.format(path=KEYSTORE_FILE))
|
.format(path=options.keystore))
|
||||||
print(debug_keystore)
|
print(debug_keystore)
|
||||||
|
|
||||||
os.umask(umask)
|
os.umask(umask)
|
||||||
|
@ -521,6 +521,18 @@ class CommonTest(unittest.TestCase):
|
|||||||
self.assertFalse(os.path.isfile(unsigned))
|
self.assertFalse(os.path.isfile(unsigned))
|
||||||
self.assertTrue(fdroidserver.common.verify_apk_signature(signed))
|
self.assertTrue(fdroidserver.common.verify_apk_signature(signed))
|
||||||
|
|
||||||
|
# now sign an APK with minSdkVersion >= 18
|
||||||
|
unsigned = os.path.join(testdir, 'duplicate.permisssions_9999999-unsigned.apk')
|
||||||
|
signed = os.path.join(testdir, 'duplicate.permisssions_9999999.apk')
|
||||||
|
shutil.copy(os.path.join(self.basedir, 'repo', 'duplicate.permisssions_9999999.apk'),
|
||||||
|
os.path.join(unsigned))
|
||||||
|
fdroidserver.common.apk_strip_signatures(unsigned, strip_manifest=True)
|
||||||
|
fdroidserver.common.sign_apk(unsigned, signed, config['keyalias'])
|
||||||
|
self.assertTrue(os.path.isfile(signed))
|
||||||
|
self.assertFalse(os.path.isfile(unsigned))
|
||||||
|
self.assertTrue(fdroidserver.common.verify_apk_signature(signed))
|
||||||
|
self.assertEqual(18, fdroidserver.common.get_minSdkVersion_aapt(signed))
|
||||||
|
|
||||||
def test_get_api_id_aapt(self):
|
def test_get_api_id_aapt(self):
|
||||||
|
|
||||||
config = dict()
|
config = dict()
|
||||||
|
4
tests/metadata/duplicate.permisssions.yml
Normal file
4
tests/metadata/duplicate.permisssions.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Categories:
|
||||||
|
- tests
|
||||||
|
Name: Duplicate Permisssions
|
||||||
|
Summary: 'Test app for all possible <uses-permissions>'
|
BIN
tests/repo/duplicate.permisssions_9999999.apk
Normal file
BIN
tests/repo/duplicate.permisssions_9999999.apk
Normal file
Binary file not shown.
@ -21,6 +21,19 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"apps": [
|
"apps": [
|
||||||
|
{
|
||||||
|
"categories": [
|
||||||
|
"tests"
|
||||||
|
],
|
||||||
|
"suggestedVersionCode": "9999999",
|
||||||
|
"license": "Unknown",
|
||||||
|
"name": "Duplicate Permisssions",
|
||||||
|
"summary": "Test app for all possible <uses-permissions>",
|
||||||
|
"added": 1513900800000,
|
||||||
|
"icon": "duplicate.permisssions.9999999.png",
|
||||||
|
"packageName": "duplicate.permisssions",
|
||||||
|
"lastUpdated": 1513900800000
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"categories": [
|
"categories": [
|
||||||
"System"
|
"System"
|
||||||
@ -271,6 +284,62 @@
|
|||||||
"versionName": "1.2"
|
"versionName": "1.2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"duplicate.permisssions": [
|
||||||
|
{
|
||||||
|
"added": 1513900800000,
|
||||||
|
"apkName": "duplicate.permisssions_9999999.apk",
|
||||||
|
"hash": "9ffc7e9b2740ce664059194805b2fbfc08b7970c8448a22b8bd828dfd6ad161c",
|
||||||
|
"hashType": "sha256",
|
||||||
|
"minSdkVersion": "18",
|
||||||
|
"packageName": "duplicate.permisssions",
|
||||||
|
"sig": "2d337e40aef77564bf62781ac424595c",
|
||||||
|
"signer": "f49af3f11efddf20dffd70f5e3117b9976674167adca280e6b1932a0601b26f6",
|
||||||
|
"size": 11988,
|
||||||
|
"targetSdkVersion": "27",
|
||||||
|
"uses-permission": [
|
||||||
|
[
|
||||||
|
"android.permission.INTERNET",
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"android.permission.ACCESS_NETWORK_STATE",
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"android.permission.ACCESS_WIFI_STATE",
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"android.permission.CHANGE_WIFI_MULTICAST_STATE",
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"android.permission.INTERNET",
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||||
|
18
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"android.permission.READ_EXTERNAL_STORAGE",
|
||||||
|
18
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"uses-permission-sdk-23": [
|
||||||
|
[
|
||||||
|
"android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS",
|
||||||
|
27
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"android.permission.REQUEST_INSTALL_PACKAGES",
|
||||||
|
null
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"versionCode": 9999999,
|
||||||
|
"versionName": "0.3-7-gb817ac8"
|
||||||
|
}
|
||||||
|
],
|
||||||
"fake.ota.update": [
|
"fake.ota.update": [
|
||||||
{
|
{
|
||||||
"added": 1457568000000,
|
"added": 1457568000000,
|
||||||
|
@ -8,6 +8,38 @@
|
|||||||
<install packageName="org.adaway"/>
|
<install packageName="org.adaway"/>
|
||||||
<uninstall packageName="com.android.vending"/>
|
<uninstall packageName="com.android.vending"/>
|
||||||
<uninstall packageName="com.facebook.orca"/>
|
<uninstall packageName="com.facebook.orca"/>
|
||||||
|
<application id="duplicate.permisssions">
|
||||||
|
<id>duplicate.permisssions</id>
|
||||||
|
<added>2017-12-22</added>
|
||||||
|
<lastupdated>2017-12-22</lastupdated>
|
||||||
|
<name>Duplicate Permisssions</name>
|
||||||
|
<summary>Test app for all possible <uses-permissions></summary>
|
||||||
|
<icon>duplicate.permisssions.9999999.png</icon>
|
||||||
|
<desc><p>No description available</p></desc>
|
||||||
|
<license>Unknown</license>
|
||||||
|
<categories>tests</categories>
|
||||||
|
<category>tests</category>
|
||||||
|
<web></web>
|
||||||
|
<source></source>
|
||||||
|
<tracker></tracker>
|
||||||
|
<marketversion></marketversion>
|
||||||
|
<marketvercode>9999999</marketvercode>
|
||||||
|
<package>
|
||||||
|
<version>0.3-7-gb817ac8</version>
|
||||||
|
<versioncode>9999999</versioncode>
|
||||||
|
<apkname>duplicate.permisssions_9999999.apk</apkname>
|
||||||
|
<hash type="sha256">9ffc7e9b2740ce664059194805b2fbfc08b7970c8448a22b8bd828dfd6ad161c</hash>
|
||||||
|
<size>11988</size>
|
||||||
|
<sdkver>18</sdkver>
|
||||||
|
<targetSdkVersion>27</targetSdkVersion>
|
||||||
|
<added>2017-12-22</added>
|
||||||
|
<sig>2d337e40aef77564bf62781ac424595c</sig>
|
||||||
|
<permissions>ACCESS_NETWORK_STATE,ACCESS_WIFI_STATE,CHANGE_WIFI_MULTICAST_STATE,INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE</permissions>
|
||||||
|
<uses-permission maxSdkVersion="18" name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission maxSdkVersion="18" name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission-sdk-23 maxSdkVersion="27" name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||||
|
</package>
|
||||||
|
</application>
|
||||||
<application id="fake.ota.update">
|
<application id="fake.ota.update">
|
||||||
<id>fake.ota.update</id>
|
<id>fake.ota.update</id>
|
||||||
<added>2016-03-10</added>
|
<added>2016-03-10</added>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
com.politedroid_3.apk repo/com.politedroid 2017-06-23
|
com.politedroid_3.apk com.politedroid 2017-06-23
|
||||||
com.politedroid_4.apk repo/com.politedroid 2017-06-23
|
com.politedroid_4.apk com.politedroid 2017-06-23
|
||||||
com.politedroid_5.apk repo/com.politedroid 2017-06-23
|
com.politedroid_5.apk com.politedroid 2017-06-23
|
||||||
com.politedroid_6.apk repo/com.politedroid 2017-06-23
|
com.politedroid_6.apk com.politedroid 2017-06-23
|
||||||
|
duplicate.permisssions_9999999.apk duplicate.permisssions 2017-12-22
|
||||||
fake.ota.update_1234.zip fake.ota.update 2016-03-10
|
fake.ota.update_1234.zip fake.ota.update 2016-03-10
|
||||||
obb.main.oldversion_1444412523.apk obb.main.oldversion 2013-12-31
|
obb.main.oldversion_1444412523.apk obb.main.oldversion 2013-12-31
|
||||||
obb.main.twoversions_1101613.apk obb.main.twoversions 2015-10-12
|
obb.main.twoversions_1101613.apk obb.main.twoversions 2015-10-12
|
||||||
|
@ -253,14 +253,14 @@ class UpdateTest(unittest.TestCase):
|
|||||||
apps = fdroidserver.metadata.read_metadata(xref=True)
|
apps = fdroidserver.metadata.read_metadata(xref=True)
|
||||||
knownapks = fdroidserver.common.KnownApks()
|
knownapks = fdroidserver.common.KnownApks()
|
||||||
apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False)
|
apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False)
|
||||||
self.assertEqual(len(apks), 11)
|
self.assertEqual(len(apks), 12)
|
||||||
apk = apks[0]
|
apk = apks[0]
|
||||||
self.assertEqual(apk['packageName'], 'com.politedroid')
|
self.assertEqual(apk['packageName'], 'com.politedroid')
|
||||||
self.assertEqual(apk['versionCode'], 3)
|
self.assertEqual(apk['versionCode'], 3)
|
||||||
self.assertEqual(apk['minSdkVersion'], '3')
|
self.assertEqual(apk['minSdkVersion'], '3')
|
||||||
self.assertEqual(apk['targetSdkVersion'], '3')
|
self.assertEqual(apk['targetSdkVersion'], '3')
|
||||||
self.assertFalse('maxSdkVersion' in apk)
|
self.assertFalse('maxSdkVersion' in apk)
|
||||||
apk = apks[4]
|
apk = apks[5]
|
||||||
self.assertEqual(apk['packageName'], 'obb.main.oldversion')
|
self.assertEqual(apk['packageName'], 'obb.main.oldversion')
|
||||||
self.assertEqual(apk['versionCode'], 1444412523)
|
self.assertEqual(apk['versionCode'], 1444412523)
|
||||||
self.assertEqual(apk['minSdkVersion'], '4')
|
self.assertEqual(apk['minSdkVersion'], '4')
|
||||||
@ -527,7 +527,7 @@ class UpdateTest(unittest.TestCase):
|
|||||||
knownapks = fdroidserver.common.KnownApks()
|
knownapks = fdroidserver.common.KnownApks()
|
||||||
apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False)
|
apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False)
|
||||||
fdroidserver.update.translate_per_build_anti_features(apps, apks)
|
fdroidserver.update.translate_per_build_anti_features(apps, apks)
|
||||||
self.assertEqual(len(apks), 11)
|
self.assertEqual(len(apks), 12)
|
||||||
foundtest = False
|
foundtest = False
|
||||||
for apk in apks:
|
for apk in apks:
|
||||||
if apk['packageName'] == 'com.politedroid' and apk['versionCode'] == 3:
|
if apk['packageName'] == 'com.politedroid' and apk['versionCode'] == 3:
|
||||||
|
Loading…
Reference in New Issue
Block a user