fdroidserver.update module

class fdroidserver.update.UsesPermission(name, maxSdkVersion)

Bases: tuple

Attributes:
maxSdkVersion

Alias for field number 1

name

Alias for field number 0

Methods

count(value, /)

Return number of occurrences of value.

index(value[, start, stop])

Return first index of value.

maxSdkVersion

Alias for field number 1

name

Alias for field number 0

class fdroidserver.update.UsesPermissionSdk23(name, maxSdkVersion)

Bases: tuple

Attributes:
maxSdkVersion

Alias for field number 1

name

Alias for field number 0

Methods

count(value, /)

Return number of occurrences of value.

index(value[, start, stop])

Return first index of value.

maxSdkVersion

Alias for field number 1

name

Alias for field number 0

fdroidserver.update.add_apks_to_per_app_repos(repodir, apks)
fdroidserver.update.apply_info_from_latest_apk(apps, apks)

No summary.

Some information from the apks needs to be applied up to the application level.

When doing this, we use the info from the most recent version’s apk. We deal with figuring out when the app was added and last updated at the same time.

fdroidserver.update.archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversions)
fdroidserver.update.copy_ios_screenshots_to_repo(screenshots, package_name)
fdroidserver.update.copy_triple_t_store_metadata(apps)

Include store metadata from the app’s source repo.

The Triple-T Gradle Play Publisher is a plugin that has a standard file layout for all of the metadata and graphics that the Google Play Store accepts. Since F-Droid has the git repo, it can just pluck those files directly. This method reads any text files into the app dict, then copies any graphics into the fdroid repo directory structure.

This needs to be run before insert_localized_app_metadata() so that the graphics files that are copied into the fdroid repo get properly indexed.

https://github.com/Triple-T/gradle-play-publisher/blob/1.2.2/README.md#uploading-images https://github.com/Triple-T/gradle-play-publisher/blob/1.2.2/README.md#play-store-metadata https://github.com/Triple-T/gradle-play-publisher/blob/2.1.0/README.md#publishing-listings

fdroidserver.update.create_metadata_from_template(apk)

Create a new metadata file using internal or external template.

Generate warnings for apk’s with no metadata (or create skeleton metadata files, if requested on the command line). Though the template file is YAML, this uses neither pyyaml nor ruamel.yaml since those impose things on the metadata file made from the template: field sort order, empty field value, formatting, etc.

fdroidserver.update.delete_disabled_builds(apps, apkcache, repodirs)

Delete disabled build outputs.

Parameters:
apps

list of all applications, as per metadata.read_metadata

apkcache

current apk cache information

repodirs

the repo directories to process

fdroidserver.update.disabled_algorithms_allowed()
fdroidserver.update.discover_ios_screenshots(fastlane_dir)

Traverse git checkouts in build dir, search for fastlane-screenshots and put findings into a dict.

fdroidserver.update.dpi_to_px(density)
fdroidserver.update.extract_apk_icons(icon_filename, apk, apkzip, repo_dir)

Extract PNG icons from an APK with the supported pixel densities.

Extracts icons from the given APK zip in various densities, saves them into given repo directory and stores their names in the APK metadata dictionary. If the icon is an XML icon, then this tries to find PNG icon that can replace it.

Parameters:
icon_filename

A string representing the icon’s file name

apk

A populated dictionary containing APK metadata. Needs to have ‘icons_src’ key

apkzip

An opened zipfile.ZipFile of the APK file

repo_dir

The directory of the APK’s repository

Returns:
A list of icon densities that are missing
fdroidserver.update.fill_missing_icon_densities(empty_densities, icon_filename, apk, repo_dir)

Resize existing PNG icons for densities missing in the APK to ensure all densities are available.

Parameters:
empty_densities: A list of icon densities that are missing
icon_filename: A string representing the icon’s file name
apk: A populated dictionary containing APK metadata. Needs to have ‘icons’ key
repo_dir: The directory of the APK’s repository
fdroidserver.update.get_all_icon_dirs(repodir)
fdroidserver.update.get_apks_without_allowed_signatures(app, apk)

Check the APK or package has been signed by one of the allowed signing certificates.

The fingerprint of the signing certificate is the standard X.509 SHA-256 fingerprint as a hex string. It can be fetched from an APK using:

apksigner verify –print-certs my.apk | grep SHA-256

Parameters:
app

The app which declares the AllowedSigningKey

apk

The APK to check

fdroidserver.update.get_apps_with_packages(apps, apks)

Return a deepcopy of that subset apps that actually has any associated packages. Skips disabled apps.

fdroidserver.update.get_cache()

Get the cached dict of the APK index.

Gather information about all the apk files in the repo directory, using cached data if possible. Some of the index operations take a long time, like calculating the SHA-256 and verifying the APK signature.

The cache is invalidated if the metadata version is different, or the ‘allow_disabled_algorithms’ config/option is different. In those cases, there is no easy way to know what has changed from the cache, so just rerun the whole thing.

Returns:
apkcache
fdroidserver.update.get_cache_file()
fdroidserver.update.get_cache_mtime()
fdroidserver.update.get_icon_bytes(apkzip, iconsrc)

ZIP has no official encoding, UTF-* and CP437 are defacto.

fdroidserver.update.get_icon_dir(repodir, density)
fdroidserver.update.get_icon_dirs(repodir)
fdroidserver.update.getsig(apkpath)

Get the unique ID for the signing certificate of an APK.

This uses a strange algorithm that was devised at the very beginning of F-Droid. Since it is only used for checking signature compatibility, it does not matter much that it uses MD5.

To get the same MD5 has that fdroidclient gets, we encode the .RSA certificate in a specific format and pass it hex-encoded to the md5 digest algorithm. This is not the same as the standard X.509 certificate fingerprint.

Parameters:
apkpath

path to the apk

Returns:
A string containing the md5 of the signature of the apk or None
if an error occurred.
fdroidserver.update.has_known_vulnerability(filename)

Check for known vulnerabilities in the APK.

Checks OpenSSL .so files in the APK to see if they are a known vulnerable version. Google also enforces this: https://support.google.com/faqs/answer/6376725?hl=en

Checks whether there are more than one classes.dex or AndroidManifest.xml files, which is invalid and an essential part of the “Master Key” attack. http://www.saurik.com/id/17

Janus is similar to Master Key but is perhaps easier to scan for. https://www.guardsquare.com/en/blog/new-android-vulnerability-allows-attackers-modify-apps-without-affecting-their-signatures

fdroidserver.update.ingest_screenshots_from_repo_dir(apps)

Include donation links from FUNDING.yml in app’s source repo.

GitHub made a standard file format for declaring donation links. This parses that format from upstream repos to include in metadata here. GitHub supports mostly proprietary services, so this logic adds proprietary services only as Donate: links.

FUNDING.yml can be either in the root of the project, or in the “.github” subdir.

https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository#about-funding-files

fdroidserver.update.insert_localized_app_metadata(apps)

Scan standard locations for graphics and localized text.

Scans for localized description files, changelogs, store graphics, and screenshots and adds them to the app metadata. Each app’s source repo root checked out at /build/<packageName> is scanned at the following standard locations for these files…

metadata/<locale>/ fastlane/metadata/android/<locale>/ src/<buildFlavor>/fastlane/metadata/android/<locale>/

…as well as the /metadata/<packageName>/<locale> directory.

If it finds them, they will be added to the dict of all packages, with the versions in the /metadata/ folder taking precedence over the what is in the app’s source repo.

The <locale> is the locale of the files supplied in that directory, using the IETF RFC5646 format (e.g. en, en-US, ast, etc).

For each <locale> directory, this script searches for the following files in the directory structure as supplied by fastlane. See https://github.com/fastlane/fastlane/blob/2.28.7/supply/README.md#images-and-screenshots

See also our documentation page: https://f-droid.org/en/docs/All_About_Descriptions_Graphics_and_Screenshots/#in-the-apps-build-metadata-in-an-fdroiddata-collection

fdroidserver.update.insert_localized_ios_app_metadata(apps_with_packages)
fdroidserver.update.insert_missing_app_names_from_apks(apps, apks)

Use app name from APK if it is not set in the metadata.

Name -> localized -> from APK

The name from the APK is set as the default name for the app if there is no other default set, e.g. app[‘Name’] or app[‘localized’][DEFAULT_LOCALE][‘name’]. The default is defined in the F-Droid ecosystem as the locale of last resort, as in the one that should always be present. en-US is used since it is the locale of the source strings.

This should only be used for index v0 and v1. Later versions of the index should be sorted by Application ID, since it is guaranteed to always be there. Before, the index was stored by the app name (aka <application android:label=””>) to save the website from having to sort the entries. That is no longer relevant since the website switched from Wordpress to Jekyll.

fdroidserver.update.insert_obbs(repodir, apps, apks)

Scan the .obb files in a given repo directory and adds them to the relevant APK instances.

OBB files have versionCodes like APK files, and they are loosely associated. If there is an OBB file present, then any APK with the same or higher versionCode will use that OBB file. There are two OBB types: main and patch, each APK can only have only have one of each.

https://developer.android.com/google/play/expansion-files.html

Parameters:
repodir

repo directory to scan

apps

list of current, valid apps

apks

current information on all APKs

fdroidserver.update.main()
fdroidserver.update.move_apk_between_sections(from_dir, to_dir, apk)

Move an APK from repo to archive or vice versa.

fdroidserver.update.parse_ios_screenshot_name(path)

Infer type and categorization info from screenshot file name.

This is not really an exact algorithm, it’s based on filenames observed in the wild.

fdroidserver.update.parse_ipa(ipa_path, file_size, sha256)
fdroidserver.update.prepare_apps(apps, apks, repodir)

Encapsulate all necessary preparation steps before we can build an index out of apps and apks.

Parameters:
apps

All apps as read from metadata

apks

list of apks that belong into repo, this gets modified in place

repodir

the target repository directory, metadata files will be copied here

Returns:
the relevant subset of apps (as a deepcopy)
fdroidserver.update.process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=False, allow_disabled_algorithms=False, archive_bad_sig=False, apps=None, cache_timestamp=0)

Process the apk with the given filename in the given repo directory.

This also extracts the icons.

Parameters:
apkcache

current apk cache information

apkfilename

the filename of the apk to scan

repodir

repo directory to scan

knownapks

known apks info

use_date_from_apk

use date from APK (instead of current date) for newly added APKs

allow_disabled_algorithms

allow APKs with valid signatures that include disabled algorithms in the signature (e.g. MD5)

archive_bad_sig

move APKs with a bad signature to the archive

cache_timestamp

the timestamp of the cache file

Returns:
(skip, apk, cachechanged) where skip is a boolean indicating whether to skip this apk,

apk is the scanned apk information, and cachechanged is True if the apkcache got changed.

fdroidserver.update.process_apks(apkcache, repodir, knownapks, use_date_from_apk=False, apps=None, cache_timestamp=0)

Process the apks in the given repo directory.

This also extracts the icons.

Parameters:
apkcache

current apk cache information

repodir

repo directory to scan

knownapks

b known apks info

use_date_from_apk

use date from APK (instead of current date) for newly added APKs

cache_timestamp

the timestamp of the cache file

Returns:
(apks, cachechanged) where apks is a list of apk information,

and cachechanged is True if the apkcache got changed.

fdroidserver.update.px_to_dpi(px)
fdroidserver.update.read_added_date_from_all_apks(apps, apks)

No summary.

Added dates come from the repo/index-v2.json file but are read when scanning apks and thus need to be applied form apk level to app level for _all_ apps and not only from non-archived ones

TODO: read the added dates directly from index-v2.json instead of

going through apks that way it also works for for repos that don’t keep an archive of apks.

fdroidserver.update.resize_all_icons(repodirs)

Resize all icons that exceed the max size.

Parameters:
repodirs

the repo directories to process

fdroidserver.update.resize_icon(iconpath, density)
fdroidserver.update.sanitize_funding_yml_entry(entry)

FUNDING.yml comes from upstream repos, entries must be sanitized.

fdroidserver.update.sanitize_funding_yml_name(name)

Sanitize usernames that come from FUNDING.yml.

fdroidserver.update.scan_apk(apk_file, require_signature=True)

Scan an APK file and returns dictionary with metadata of the APK.

Attention: This does not verify that the APK signature is correct.

Parameters:
apk_file

The (ideally absolute) path to the APK file

require_signature

Raise an exception is there is no valid signature. Default to True.

Returns:
A dict containing APK metadata
Raises:
BuildException
fdroidserver.update.scan_apk_androguard(apk, apkfile)
fdroidserver.update.scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False)

Scan a repo for all files with an extension except APK/OBB/IPA.

This allows putting all kinds of files into repostories. E.g. Media Files, Zip archives, …

Parameters:
apkcache

current cached info about all repo files

repodir

repo directory to scan

knownapks

list of all known files, as per metadata.read_metadata

use_date_from_file

use date from file (instead of current date) for newly added files

fdroidserver.update.scan_repo_for_ipas(apkcache, repodir, knownapks)

Scan for IPA files in a given repo directory.

Parameters:
apkcache

cache dictionary containting cached file infos from previous runs

repodir

repo directory to scan

knownapks

list of all known files, as per metadata.read_metadata

Returns:
ipas

list of file infos for ipa files in ./repo folder

cachechanged

ture if new ipa files were found and added to apkcache

fdroidserver.update.status_update_json(apps, apks)

Output a JSON file with metadata about this fdroid update run.

Parameters:
apps

fully populated list of all applications

apks

all to be published apks

fdroidserver.update.translate_per_build_anti_features(apps, apks)

Grab the anti-features list from the build metadata.

For most Anti-Features, they are really most applicable per-APK, not for an app. An app can fix a vulnerability, add/remove tracking, etc. This reads the ‘antifeatures’ list from the Build entries in the fdroiddata metadata file, then transforms it into the ‘antiFeatures’ list of unique items for the index.

The field key is all lower case in the metadata file to match the rest of the Build fields. It is ‘antiFeatures’ camel case in the implementation, index, and fdroidclient since it is translated from the build ‘antifeatures’ field, not directly included.

fdroidserver.update.version_string_to_int(version)

Convert sermver version designation to version code.

Approximately convert a [Major].[Minor].[Patch] version string consisting of numeric characters (0-9) and periods to a number. The exponents are chosen such that it still fits in the 64bit JSON/Android range.

fdroidserver.update.write_cache(apkcache)