mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-04 18:20:13 +02:00
Merge branch 'androguard-fixes' into 'master'
Androguard fixes See merge request fdroid/fdroidserver!466
This commit is contained in:
commit
f55bb62a56
@ -43,18 +43,18 @@ debian_testing:
|
|||||||
only:
|
only:
|
||||||
- master@fdroid/fdroidserver
|
- master@fdroid/fdroidserver
|
||||||
script:
|
script:
|
||||||
- apt update -y
|
- apt-get -qy update
|
||||||
- apt dist-upgrade -y
|
- apt-get -qy dist-upgrade
|
||||||
- apt-get install -y --no-install-recommends
|
- apt-get -qy install --no-install-recommends
|
||||||
aapt adb android-platform-tools-base android-sdk-common fdroidserver
|
fdroidserver git gnupg python3-setuptools
|
||||||
git gnupg python3-setuptools zipalign
|
- sed -i -e 's,testing,sid,g' -e 's,testing,sid,g' /etc/apt/sources.list
|
||||||
|
- apt-get -qy update
|
||||||
|
- apt-get install -y --no-install-recommends aapt androguard android-platform-tools-base zipalign
|
||||||
|
- python3 -c 'import fdroidserver'
|
||||||
|
- python3 -c 'import androguard'
|
||||||
- export ANDROID_HOME=/usr/lib/android-sdk
|
- export ANDROID_HOME=/usr/lib/android-sdk
|
||||||
- export LANG=C.UTF-8
|
- export LANG=C.UTF-8
|
||||||
- cd tests
|
- cd tests
|
||||||
- rm -f install.TestCase # fails frequently and is unimportant
|
|
||||||
- echo "Debian's build-tools is too old, remove once the package has been updated"
|
|
||||||
- sed -i '/android.permission.READ_EXTERNAL_STORAGE/d' repo/index.xml
|
|
||||||
- sed -i '/^diff -uw .*index-v1.json$/d' run-tests
|
|
||||||
- ./run-tests
|
- ./run-tests
|
||||||
|
|
||||||
ubuntu_lts:
|
ubuntu_lts:
|
||||||
@ -62,20 +62,20 @@ ubuntu_lts:
|
|||||||
only:
|
only:
|
||||||
- master@fdroid/fdroidserver
|
- master@fdroid/fdroidserver
|
||||||
script:
|
script:
|
||||||
- apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 9AAC253193B65D4DF1D0A13EEC4632C79C5E0151
|
- while ! apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 9AAC253193B65D4DF1D0A13EEC4632C79C5E0151; do sleep 15; done
|
||||||
- export RELEASE=`sed -n 's,^deb [^ ][^ ]* \([a-z]*\).*,\1,p' /etc/apt/sources.list | head -1`
|
- export RELEASE=`sed -n 's,^deb [^ ][^ ]* \([a-z]*\).*,\1,p' /etc/apt/sources.list | head -1`
|
||||||
- echo "deb http://ppa.launchpad.net/fdroid/fdroidserver/ubuntu $RELEASE main" >> /etc/apt/sources.list
|
- echo "deb http://ppa.launchpad.net/fdroid/fdroidserver/ubuntu $RELEASE main" >> /etc/apt/sources.list
|
||||||
- apt update -y
|
- apt-get -qy update
|
||||||
- apt dist-upgrade -y
|
- apt-get -qy dist-upgrade
|
||||||
- apt-get install -y --no-install-recommends
|
- apt-get -qy install --no-install-recommends
|
||||||
aapt adb android-platform-tools-base android-sdk-common fdroidserver
|
aapt adb android-platform-tools-base android-sdk-common fdroidserver
|
||||||
git gnupg python3-setuptools unzip wget zipalign
|
git gnupg python3-setuptools unzip wget zipalign
|
||||||
- export ANDROID_HOME=/usr/lib/android-sdk
|
- export ANDROID_HOME=/usr/lib/android-sdk
|
||||||
# xenial's aapt is too old
|
# xenial's aapt is too old
|
||||||
- wget --no-verbose https://dl.google.com/android/repository/build-tools_r27.0.1-linux.zip
|
- wget --no-verbose https://dl.google.com/android/repository/build-tools_r27.0.3-linux.zip
|
||||||
- unzip -q build-tools_r27.0.1-linux.zip
|
- unzip -q build-tools_r27.0.3-linux.zip
|
||||||
- rm build-tools_r27.0.1-linux.zip
|
- rm build-tools_r27.0.3-linux.zip
|
||||||
- mv android-8.1.0 $ANDROID_HOME/build-tools/27.0.1
|
- mv android-8.1.0 $ANDROID_HOME/build-tools/27.0.3
|
||||||
- export LANG=C.UTF-8
|
- export LANG=C.UTF-8
|
||||||
- cd tests
|
- cd tests
|
||||||
- ./run-tests
|
- ./run-tests
|
||||||
|
@ -817,7 +817,7 @@ def build_local(app, build, vcs, build_dir, output_dir, log_dir, srclib_dir, ext
|
|||||||
src = os.path.normpath(apks[0])
|
src = os.path.normpath(apks[0])
|
||||||
|
|
||||||
# Make sure it's not debuggable...
|
# Make sure it's not debuggable...
|
||||||
if common.isApkAndDebuggable(src):
|
if common.is_apk_and_debuggable(src):
|
||||||
raise BuildException("APK is debuggable")
|
raise BuildException("APK is debuggable")
|
||||||
|
|
||||||
# By way of a sanity check, make sure the version and version
|
# By way of a sanity check, make sure the version and version
|
||||||
|
@ -1927,7 +1927,25 @@ def get_file_extension(filename):
|
|||||||
return os.path.splitext(filename)[1].lower()[1:]
|
return os.path.splitext(filename)[1].lower()[1:]
|
||||||
|
|
||||||
|
|
||||||
def get_apk_debuggable_aapt(apkfile):
|
def use_androguard():
|
||||||
|
"""Report if androguard is available, and config its debug logging"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
import androguard
|
||||||
|
if use_androguard.show_path:
|
||||||
|
logging.debug(_('Using androguard from "{path}"').format(path=androguard.__file__))
|
||||||
|
use_androguard.show_path = False
|
||||||
|
if options and options.verbose:
|
||||||
|
logging.getLogger("androguard.axml").setLevel(logging.INFO)
|
||||||
|
return True
|
||||||
|
except ImportError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
use_androguard.show_path = True
|
||||||
|
|
||||||
|
|
||||||
|
def is_apk_and_debuggable_aapt(apkfile):
|
||||||
p = SdkToolsPopen(['aapt', 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'],
|
p = SdkToolsPopen(['aapt', 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'],
|
||||||
output=False)
|
output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
@ -1938,7 +1956,7 @@ def get_apk_debuggable_aapt(apkfile):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_apk_debuggable_androguard(apkfile):
|
def is_apk_and_debuggable_androguard(apkfile):
|
||||||
try:
|
try:
|
||||||
from androguard.core.bytecodes.apk import APK
|
from androguard.core.bytecodes.apk import APK
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -1952,7 +1970,7 @@ def get_apk_debuggable_androguard(apkfile):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def isApkAndDebuggable(apkfile):
|
def is_apk_and_debuggable(apkfile):
|
||||||
"""Returns True if the given file is an APK and is debuggable
|
"""Returns True if the given file is an APK and is debuggable
|
||||||
|
|
||||||
:param apkfile: full path to the apk to check"""
|
:param apkfile: full path to the apk to check"""
|
||||||
@ -1960,10 +1978,10 @@ def isApkAndDebuggable(apkfile):
|
|||||||
if get_file_extension(apkfile) != 'apk':
|
if get_file_extension(apkfile) != 'apk':
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if SdkToolsPopen(['aapt', 'version'], output=False):
|
if use_androguard():
|
||||||
return get_apk_debuggable_aapt(apkfile)
|
return is_apk_and_debuggable_androguard(apkfile)
|
||||||
else:
|
else:
|
||||||
return get_apk_debuggable_androguard(apkfile)
|
return is_apk_and_debuggable_aapt(apkfile)
|
||||||
|
|
||||||
|
|
||||||
def get_apk_id_aapt(apkfile):
|
def get_apk_id_aapt(apkfile):
|
||||||
@ -1972,7 +1990,7 @@ def get_apk_id_aapt(apkfile):
|
|||||||
:param apkfile: path to an APK file.
|
:param apkfile: path to an APK file.
|
||||||
:returns: triplet (appid, version code, version name)
|
:returns: triplet (appid, version code, version name)
|
||||||
"""
|
"""
|
||||||
r = re.compile("package: name='(?P<appid>.*)' versionCode='(?P<vercode>.*)' versionName='(?P<vername>.*)' platformBuildVersionName='.*'")
|
r = re.compile("^package: name='(?P<appid>.*)' versionCode='(?P<vercode>.*)' versionName='(?P<vername>.*)'.*")
|
||||||
p = SdkToolsPopen(['aapt', 'dump', 'badging', apkfile], output=False)
|
p = SdkToolsPopen(['aapt', 'dump', 'badging', apkfile], output=False)
|
||||||
for line in p.output.splitlines():
|
for line in p.output.splitlines():
|
||||||
m = r.match(line)
|
m = r.match(line)
|
||||||
|
@ -131,7 +131,9 @@ def main():
|
|||||||
logging.info('Try running `fdroid init` in an empty directory.')
|
logging.info('Try running `fdroid init` in an empty directory.')
|
||||||
raise FDroidException('Repository already exists.')
|
raise FDroidException('Repository already exists.')
|
||||||
|
|
||||||
if 'aapt' not in test_config or not os.path.isfile(test_config['aapt']):
|
if common.use_androguard():
|
||||||
|
pass
|
||||||
|
elif 'aapt' not in test_config or not os.path.isfile(test_config['aapt']):
|
||||||
# try to find a working aapt, in all the recent possible paths
|
# try to find a working aapt, in all the recent possible paths
|
||||||
build_tools = os.path.join(test_config['sdk_path'], 'build-tools')
|
build_tools = os.path.join(test_config['sdk_path'], 'build-tools')
|
||||||
aaptdirs = []
|
aaptdirs = []
|
||||||
|
@ -1049,11 +1049,9 @@ def scan_apk(apk_file):
|
|||||||
'antiFeatures': set(),
|
'antiFeatures': set(),
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
if common.use_androguard():
|
||||||
import androguard
|
|
||||||
androguard # silence pyflakes
|
|
||||||
scan_apk_androguard(apk, apk_file)
|
scan_apk_androguard(apk, apk_file)
|
||||||
except ImportError:
|
else:
|
||||||
scan_apk_aapt(apk, apk_file)
|
scan_apk_aapt(apk, apk_file)
|
||||||
|
|
||||||
# Get the signature, or rather the signing key fingerprints
|
# Get the signature, or rather the signing key fingerprints
|
||||||
@ -1251,6 +1249,12 @@ def scan_apk_androguard(apk, apkfile):
|
|||||||
maxSdkVersion
|
maxSdkVersion
|
||||||
)
|
)
|
||||||
apk['uses-permission'].append(permission)
|
apk['uses-permission'].append(permission)
|
||||||
|
for name, maxSdkVersion in apkobject.get_uses_implied_permission_list():
|
||||||
|
permission = UsesPermission(
|
||||||
|
name,
|
||||||
|
maxSdkVersion
|
||||||
|
)
|
||||||
|
apk['uses-permission'].append(permission)
|
||||||
|
|
||||||
for item in xml.findall('uses-permission-sdk-23'):
|
for item in xml.findall('uses-permission-sdk-23'):
|
||||||
name = str(item.attrib['{' + xml.nsmap['android'] + '}name'])
|
name = str(item.attrib['{' + xml.nsmap['android'] + '}name'])
|
||||||
@ -1268,6 +1272,8 @@ def scan_apk_androguard(apk, apkfile):
|
|||||||
and feature != "android.hardware.screen.landscape":
|
and feature != "android.hardware.screen.landscape":
|
||||||
if feature.startswith("android.feature."):
|
if feature.startswith("android.feature."):
|
||||||
feature = feature[16:]
|
feature = feature[16:]
|
||||||
|
required = item.attrib.get('{' + xml.nsmap['android'] + '}required')
|
||||||
|
if required is None or required == 'true':
|
||||||
apk['features'].append(feature)
|
apk['features'].append(feature)
|
||||||
|
|
||||||
|
|
||||||
@ -1316,7 +1322,7 @@ def process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=Fal
|
|||||||
return True, None, False
|
return True, None, False
|
||||||
|
|
||||||
# Check for debuggable apks...
|
# Check for debuggable apks...
|
||||||
if common.isApkAndDebuggable(apkfile):
|
if common.is_apk_and_debuggable(apkfile):
|
||||||
logging.warning('{0} is set to android:debuggable="true"'.format(apkfile))
|
logging.warning('{0} is set to android:debuggable="true"'.format(apkfile))
|
||||||
|
|
||||||
if options.rename_apks:
|
if options.rename_apks:
|
||||||
|
@ -140,7 +140,7 @@ class CommonTest(unittest.TestCase):
|
|||||||
testfiles.append(os.path.join(self.basedir, 'urzip-badsig.apk'))
|
testfiles.append(os.path.join(self.basedir, 'urzip-badsig.apk'))
|
||||||
testfiles.append(os.path.join(self.basedir, 'urzip-badcert.apk'))
|
testfiles.append(os.path.join(self.basedir, 'urzip-badcert.apk'))
|
||||||
for apkfile in testfiles:
|
for apkfile in testfiles:
|
||||||
debuggable = fdroidserver.common.isApkAndDebuggable(apkfile)
|
debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile)
|
||||||
self.assertTrue(debuggable,
|
self.assertTrue(debuggable,
|
||||||
"debuggable APK state was not properly parsed!")
|
"debuggable APK state was not properly parsed!")
|
||||||
# these are set NOT debuggable
|
# these are set NOT debuggable
|
||||||
@ -148,7 +148,7 @@ class CommonTest(unittest.TestCase):
|
|||||||
testfiles.append(os.path.join(self.basedir, 'urzip-release.apk'))
|
testfiles.append(os.path.join(self.basedir, 'urzip-release.apk'))
|
||||||
testfiles.append(os.path.join(self.basedir, 'urzip-release-unsigned.apk'))
|
testfiles.append(os.path.join(self.basedir, 'urzip-release-unsigned.apk'))
|
||||||
for apkfile in testfiles:
|
for apkfile in testfiles:
|
||||||
debuggable = fdroidserver.common.isApkAndDebuggable(apkfile)
|
debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile)
|
||||||
self.assertFalse(debuggable,
|
self.assertFalse(debuggable,
|
||||||
"debuggable APK state was not properly parsed!")
|
"debuggable APK state was not properly parsed!")
|
||||||
|
|
||||||
@ -541,10 +541,40 @@ class CommonTest(unittest.TestCase):
|
|||||||
self._set_build_tools()
|
self._set_build_tools()
|
||||||
config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt')
|
config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt')
|
||||||
|
|
||||||
appid, vercode, vername = fdroidserver.common.get_apk_id_aapt('repo/obb.main.twoversions_1101613.apk')
|
testcases = [
|
||||||
self.assertEqual('obb.main.twoversions', appid)
|
('repo/obb.main.twoversions_1101613.apk', 'obb.main.twoversions', '1101613', '0.1'),
|
||||||
self.assertEqual('1101613', vercode)
|
('OBBMainPatchCurrent.apk', 'obb.mainpatch.current', '1619', '0.1'),
|
||||||
self.assertEqual('0.1', vername)
|
('OBBMainTwoVersions.apk', 'obb.main.twoversions', '1101613', '0.1'),
|
||||||
|
('org.bitbucket.tickytacky.mirrormirror_1.apk', 'org.bitbucket.tickytacky.mirrormirror', '1', '1.0'),
|
||||||
|
('org.bitbucket.tickytacky.mirrormirror_2.apk', 'org.bitbucket.tickytacky.mirrormirror', '2', '1.0.1'),
|
||||||
|
('org.bitbucket.tickytacky.mirrormirror_3.apk', 'org.bitbucket.tickytacky.mirrormirror', '3', '1.0.2'),
|
||||||
|
('org.bitbucket.tickytacky.mirrormirror_4.apk', 'org.bitbucket.tickytacky.mirrormirror', '4', '1.0.3'),
|
||||||
|
('org.dyndns.fules.ck_20.apk', 'org.dyndns.fules.ck', '20', 'v1.6pre2'),
|
||||||
|
('urzip.apk', 'info.guardianproject.urzip', '100', '0.1'),
|
||||||
|
('urzip-badcert.apk', 'info.guardianproject.urzip', '100', '0.1'),
|
||||||
|
('urzip-badsig.apk', 'info.guardianproject.urzip', '100', '0.1'),
|
||||||
|
('urzip-release.apk', 'info.guardianproject.urzip', '100', '0.1'),
|
||||||
|
('urzip-release-unsigned.apk', 'info.guardianproject.urzip', '100', '0.1'),
|
||||||
|
('urzip-πÇÇπÇÇ现代汉语通用字-български-عربي1234.apk', 'info.guardianproject.urzip', '100', '0.1'),
|
||||||
|
('repo/com.politedroid_3.apk', 'com.politedroid', '3', '1.2'),
|
||||||
|
('repo/com.politedroid_4.apk', 'com.politedroid', '4', '1.3'),
|
||||||
|
('repo/com.politedroid_5.apk', 'com.politedroid', '5', '1.4'),
|
||||||
|
('repo/com.politedroid_6.apk', 'com.politedroid', '6', '1.5'),
|
||||||
|
('repo/duplicate.permisssions_9999999.apk', 'duplicate.permisssions', '9999999', '0.3-7-gb817ac8'),
|
||||||
|
('repo/info.zwanenburg.caffeinetile_4.apk', 'info.zwanenburg.caffeinetile', '4', '1.3'),
|
||||||
|
('repo/obb.main.oldversion_1444412523.apk', 'obb.main.oldversion', '1444412523', '0.1'),
|
||||||
|
('repo/obb.mainpatch.current_1619_another-release-key.apk', 'obb.mainpatch.current', '1619', '0.1'),
|
||||||
|
('repo/obb.mainpatch.current_1619.apk', 'obb.mainpatch.current', '1619', '0.1'),
|
||||||
|
('repo/obb.main.twoversions_1101613.apk', 'obb.main.twoversions', '1101613', '0.1'),
|
||||||
|
('repo/obb.main.twoversions_1101615.apk', 'obb.main.twoversions', '1101615', '0.1'),
|
||||||
|
('repo/obb.main.twoversions_1101617.apk', 'obb.main.twoversions', '1101617', '0.1'),
|
||||||
|
('repo/urzip-; Рахма́нинов, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢尔盖·.apk', 'info.guardianproject.urzip', '100', '0.1'),
|
||||||
|
]
|
||||||
|
for apkfilename, appid, versionCode, versionName in testcases:
|
||||||
|
a, vc, vn = fdroidserver.common.get_apk_id_aapt(apkfilename)
|
||||||
|
self.assertEqual(appid, a)
|
||||||
|
self.assertEqual(versionCode, vc)
|
||||||
|
self.assertEqual(versionName, vn)
|
||||||
|
|
||||||
with self.assertRaises(FDroidException):
|
with self.assertRaises(FDroidException):
|
||||||
fdroidserver.common.get_apk_id_aapt('nope')
|
fdroidserver.common.get_apk_id_aapt('nope')
|
||||||
|
@ -125,7 +125,11 @@ cd $WORKSPACE/tests/getsig
|
|||||||
./make.sh
|
./make.sh
|
||||||
|
|
||||||
cd $WORKSPACE/tests
|
cd $WORKSPACE/tests
|
||||||
for testcase in $WORKSPACE/tests/*.TestCase; do
|
for testcase in $WORKSPACE/tests/i*.TestCase; do
|
||||||
|
if [ $testcase == $WORKSPACE/tests/install.TestCase ]; then
|
||||||
|
echo "skipping install.TestCase, its too troublesome in CI builds"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
$testcase
|
$testcase
|
||||||
done
|
done
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user