utils.py 2.81 KB
Newer Older
1 2
import hashlib
import json
3
import os
4 5
import sys
from collections import OrderedDict
6 7
from subprocess import check_call, check_output

8 9 10 11 12
# WARNING: changing those affects reproducibility
GO_ROOT = '/tmp/go'
GO_PATH = '/tmp/go-path'

NDK_DIR = 'android-ndk'
13 14 15 16 17 18 19 20


def get_version():
    if len(sys.argv) > 2:
        fail("Usage: %s [version tag]" % sys.argv[0])
    return sys.argv[1] if len(sys.argv) > 1 else None


21 22 23 24 25 26 27 28 29
def get_version_and_tool():
    if len(sys.argv) < 2 or len(sys.argv) > 3:
        fail("Usage: %s tool [version tag]" % sys.argv[0])
    tool = sys.argv[1]
    command_line_version = sys.argv[2] if len(sys.argv) > 2 else None
    return tool, command_line_version


def get_build_versions(tool, tag):
30 31 32 33 34 35
    # load versions and their dependencies
    with open('versions.json', 'r') as f:
        versions = json.load(f, object_pairs_hook=OrderedDict)

    if tag is None:
        # take top-most version
36 37
        tag = next(iter(versions[tool]))
    return tag, versions[tool][tag]
38 39


40 41 42 43 44 45
def check_go_version(versions):
    # Check if proper Go version is installed (trailing space, because 'go1.10' in 'go1.10.1')
    if versions['go']['version'] + ' ' not in check_output(['go', 'version']).decode("UTF-8"):
        fail("You need Go version %s to reproduce this binary" % versions['go']['version'])


Torsten Grote's avatar
Torsten Grote committed
46
def ex(args, env=None, cwd=None):
47
    print("+ %s" % " ".join(args))
Torsten Grote's avatar
Torsten Grote committed
48
    check_call(args, env=env, cwd=cwd)
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63


def fail(msg=""):
    sys.stderr.write("Error: %s\n" % msg)
    sys.exit(1)


def get_sha256(filename, block_size=65536):
    sha256 = hashlib.sha256()
    with open(filename, 'rb') as f:
        for block in iter(lambda: f.read(block_size), b''):
            sha256.update(block)
    return sha256.hexdigest()


64 65 66 67 68 69 70
def reset_time(file_name):
    check_call(['touch', '--no-dereference', '-t', '197001010000.00', file_name])


def zip_files(files, zip_name):
    for file_name in files:
        reset_time(file_name)
71 72
        # use deterministic permissions to prevent differences in zip files
        os.chmod(file_name, 0o755)
73 74
        sha256hash = get_sha256(file_name)
        print("Hash before zipping %s: %s" % (file_name, sha256hash))
75 76 77 78
    ex(['zip', '-D', '-X', zip_name] + files)


def get_obfs4_version(versions):
Torsten Grote's avatar
Torsten Grote committed
79
    version = versions['revision']
80 81 82
    if '-' in version:
        return version.split('-')[1]
    return version
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99


def get_file_suffix(versions, android=False):
    version = get_obfs4_version(versions)
    return "%s-%s" % ("android", version) if android else version


def get_final_file_name(versions, android=False):
    return 'obfs4proxy-%s.zip' % get_file_suffix(versions, android)


def get_sources_file_name(versions, android=False):
    return 'obfs4proxy-%s-sources.jar' % get_file_suffix(versions, android)


def get_pom_file_name(versions, android=False):
    return 'obfs4proxy-%s.pom' % get_file_suffix(versions, android)