This file is indexed.

/usr/lib/python3/dist-packages/fdroidserver/signatures.py is in fdroidserver 1.0.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#!/usr/bin/env python3
#
# Copyright (C) 2017, Michael Poehn <michael.poehn@fsfe.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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/>.

from argparse import ArgumentParser

import re
import os
import sys
import logging

from . import _
from . import common
from . import net
from .exception import FDroidException


def extract_signature(apkpath):

    if not os.path.exists(apkpath):
        raise FDroidException("file APK does not exists '{}'".format(apkpath))
    if not common.verify_apk_signature(apkpath):
        raise FDroidException("no valid signature in '{}'".format(apkpath))
    logging.debug('signature okay: %s', apkpath)

    appid, vercode, _ignored = common.get_apk_id_aapt(apkpath)
    sigdir = common.metadata_get_sigdir(appid, vercode)
    if not os.path.exists(sigdir):
        os.makedirs(sigdir)
    common.apk_extract_signatures(apkpath, sigdir)

    return sigdir


def extract(config, options):

    # Create tmp dir if missing…
    tmp_dir = 'tmp'
    if not os.path.exists(tmp_dir):
        os.mkdir(tmp_dir)

    if not options.APK or len(options.APK) <= 0:
        logging.critical(_('no APK supplied'))
        sys.exit(1)

    # iterate over supplied APKs downlaod and extract them…
    httpre = re.compile('https?:\/\/')
    for apk in options.APK:
        try:
            if os.path.isfile(apk):
                sigdir = extract_signature(apk)
                logging.info(_("Fetched signatures for '{apkfilename}' -> '{sigdir}'")
                             .format(apkfilename=apk, sigdir=sigdir))
            elif httpre.match(apk):
                if apk.startswith('https') or options.no_check_https:
                    try:
                        tmp_apk = os.path.join(tmp_dir, 'signed.apk')
                        net.download_file(apk, tmp_apk)
                        sigdir = extract_signature(tmp_apk)
                        logging.info(_("Fetched signatures for '{apkfilename}' -> '{sigdir}'")
                                     .format(apkfilename=apk, sigdir=sigdir))
                    finally:
                        if tmp_apk and os.path.exists(tmp_apk):
                            os.remove(tmp_apk)
                else:
                    logging.warn(_('refuse downloading via insecure HTTP connection (use HTTPS or specify --no-https-check): {apkfilename}').format(apkfilename=apk))
        except FDroidException as e:
            logging.warning(_("Failed fetching signatures for '{apkfilename}': {error}")
                            .format(apkfilename=apk, error=e))
            if e.detail:
                logging.debug(e.detail)


def main():

    global config, options

    # Parse command line...
    parser = ArgumentParser(usage="%(prog)s [options] APK [APK...]")
    common.setup_global_opts(parser)
    parser.add_argument("APK", nargs='*',
                        help=_("signed APK, either a file-path or HTTPS URL."))
    parser.add_argument("--no-check-https", action="store_true", default=False)
    options = parser.parse_args()

    # Read config.py...
    config = common.read_config(options)

    extract(config, options)