123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- #!/bin/bash
- #
- # A script to verify that a locally compiled APK matches the released APK.
- # _____ _
- # |_ _| |_ _ _ ___ ___ _ __ __ _
- # | | | ' \| '_/ -_) -_) ' \/ _` |_
- # |_| |_||_|_| \___\___|_|_|_\__,_(_)
- #
- # Threema for Android
- # Copyright (c) 2020 Threema GmbH
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero General Public License, version 3,
- # as published by the Free Software Foundation.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
- set -euo pipefail
- GREEN="\033[0;32m"
- RED="\033[0;31m"
- YELLOW="\033[1;33m"
- RESET="\033[0m"
- function print_usage() {
- echo "Usage: $0 -n <version-name> -v <variant> -p <published-apk> [-l <local-apk>]"
- echo ""
- echo "Options:"
- echo " -n <version-name> The version name. Example: '4.43k'"
- echo " -v <variant> Variant to verify: Either googleplay or threemashop"
- echo " -p <published-apk> Path to the APK file extracted from the phone"
- echo " -l <local-apk> Optional: Path to the locally built APK"
- echo " -h,--help Print this help and exit"
- }
- function log() {
- echo -en "$1"
- echo -n "$2 $3"
- echo -e "$RESET"
- }
- function log_major() { log "$GREEN" "==>" "$1"; }
- function log_minor() { log "$GREEN" "--> " "$1"; }
- function log_warning() { log "$YELLOW" "==>" "$1"; }
- function log_error() { log "$RED" "!!!" "Error: $1"; }
- function fail() {
- log_error "$1"
- exit 1
- }
- # Re-implementation of realpath function (hello macOS)
- function realpath() {
- OURPWD=$PWD
- cd "$(dirname "$1")"
- LINK=$(readlink "$(basename "$1")")
- while [ "$LINK" ]; do
- cd "$(dirname "$LINK")"
- LINK=$(readlink "$(basename "$1")")
- done
- REALPATH="$PWD/$(basename "$1")"
- cd "$OURPWD"
- echo "$REALPATH"
- }
- # Determine script directory
- DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
- # If no arguments are passed, print usage
- if [ "$#" -lt 1 ]; then print_usage; exit 1; fi
- # Parse arguments
- name=""
- variant=""
- published_apk=""
- local_apk=""
- while [[ "$#" -gt 0 ]]; do
- case $1 in
- -n) name="$2"; shift ;;
- -v) variant="$2"; shift ;;
- -p) published_apk="$2"; shift ;;
- -l) local_apk="$2"; shift ;;
- -h|--help) print_usage; exit 0 ;;
- *) echo "Unknown parameter passed: $1"; print_usage; exit 1 ;;
- esac
- shift
- done
- # Process arguments
- if [[ "$name" == "" || "$name" == .* ]]; then
- log_error 'Please set a valid version name with "-n <name>".'
- fail 'Example: "-n 4.43k"'
- fi
- if [[ "$published_apk" == "" ]]; then
- log_error 'Please set a valid published APK path with "-p <path>".'
- fail 'Example: "-p threema-extracted.apk"'
- fi
- published_apk=$(realpath "$published_apk")
- if [[ "$variant" == "" ]]; then
- log_error 'Please set a valid build variant with "-v <variant>".'
- fail 'Example: "-v googleplay" or "-v threemashop"'
- fi
- case "$variant" in
- googleplay) variant_name="store_google" ;;
- threemashop) variant_name="store_threema" ;;
- *) fail "Invalid build variant: $variant" ;;
- esac
- # Validate target directory
- targetdir=$(realpath "$DIR/../reproduce")
- if [[ -d "$targetdir" ]]; then
- fail "The directory $targetdir already exists. Please remove it first."
- fi
- mkdir -p "$targetdir"/{published,local}
- # Unpack published APK
- if [[ ! -f "$published_apk" ]]; then
- fail "The published APK $published_apk could not be found."
- fi
- log_major "Unpacking published APK"
- unzip -q -d "$targetdir/published/" "$published_apk"
- # Determine local APK path
- if [[ "$local_apk" == "" ]]; then
- log_major "Determine local APK path"
- lib_count="$(find "$targetdir/published/lib/" -mindepth 1 -maxdepth 1 -type d | wc -l | xargs)"
- log_minor "Found $lib_count libs"
- case "$lib_count" in
- 1) architecture="$(ls "$targetdir/published/lib/")" ;;
- 4) architecture="universal" ;;
- *) fail "Could not determine architecture of published APK"
- esac
- log_minor "Architecture: $architecture"
- if [ -f "$DIR/../release/$name/$variant/app-$variant_name-$architecture-release-unsigned.apk" ]; then
- local_apk="$(realpath "$DIR/../release/$name/$variant/app-$variant_name-$architecture-release-unsigned.apk")"
- else
- local_apk="$(realpath "$DIR/../release/$name/$variant/app-$variant_name-$architecture-release.apk")"
- fi
- fi
- if [[ ! -f "$local_apk" ]]; then
- fail "The local APK $local_apk could not be found."
- fi
- log_major "Comparing the following APKs:"
- log_minor "Published: $published_apk"
- log_minor "Local: $local_apk"
- # Unpack local APK
- log_major "Unpacking local APK"
- unzip -q -d "$targetdir/local/" "$local_apk"
- # Remove meta information (containing things like the signature)
- log_major "Removing variable files:"
- for path in META-INF/ resources.arsc; do
- for target in local published; do
- log_minor "rm -r $target/$path"
- rm -r "${targetdir:?}/${target:?}/${path:?}"
- done
- done
- # Diff!
- log_major "Comparing releases"
- diff -r "$targetdir/local/" "$targetdir/published/" && success=1 || success=0
- if [ $success -eq 1 ]; then
- log_major "Success! The APKs match."
- else
- log_warning "APK could not be verified."
- log_warning "Don't panic! First, make sure that you have compiled the correct version!"
- log_warning "If you cannot figure out why the verification failed,"
- log_warning "send us an e-mail to opensource@threema.ch containing the log above."
- exit 2
- fi
|