Skip to content
Snippets Groups Projects
Verified Commit 23e1d973 authored by Torsten Grote's avatar Torsten Grote
Browse files

First version that only builds obfs4proxy for Android and Linux

parents
No related branches found
No related tags found
No related merge requests found
/.idea
/__pycache__
/toolchain
/jni
/android-ndk
/android-ndk.zip
/obfs4proxy_*.zip
/obfs4
\ No newline at end of file
#!/usr/bin/env python3
from glob import glob
import os
from shutil import move, rmtree
from subprocess import check_call
from utils import get_build_versions, ex, get_sha256, fail, zip_file
NDK_DIR = 'android-ndk'
REPO_DIR = 'obfs4'
SOURCE = 'obfs4/obfs4proxy/*'
def main():
# Get the latest versions for building
versions = get_build_versions(None)
# Setup Android NDK
setup_android_ndk(versions)
# Clone or reset the git repository
prepare_repo(versions)
# Install dependencies (of git HEAD)
ex(['go', 'get', '-d', versions['obfs4']['got-get']])
# Build for various Android versions
build_android()
# Build for 64-bit Linux
build_linux()
def setup_android_ndk(versions):
if os.path.isdir(NDK_DIR):
# check that we are using the correct NDK
from configparser import ConfigParser
config = ConfigParser()
with open(os.path.join(NDK_DIR, 'source.properties'), 'rt') as f:
config.read_string('[default]\n' + str(f.read()))
revision = config.get('default', 'Pkg.Revision')
if revision != versions['ndk']['revision']:
print("Existing Android NDK has unexpected revision (%s). Deleting..." % revision)
rmtree(NDK_DIR)
if not os.path.isdir(NDK_DIR):
# download Android NDK
print("Downloading Android NDK...")
check_call(['wget', '-c', '--no-verbose', versions['ndk']['url'], '-O', 'android-ndk.zip'])
# check sha256 hash on downloaded file
is_hash = get_sha256('android-ndk.zip')
if is_hash != versions['ndk']['sha256']:
fail("Android NDK checksum does not match, should be %s" % is_hash)
# install the NDK
print("Unpacking Android NDK...")
ndk_dir_tmp = NDK_DIR + '-tmp'
check_call(['unzip', '-q', 'android-ndk.zip', '-d', ndk_dir_tmp])
content = os.listdir(ndk_dir_tmp)
if len(content) == 1 and content[0].startswith('android-ndk-r'):
move(os.path.join(ndk_dir_tmp, content[0]), NDK_DIR)
os.rmdir(ndk_dir_tmp)
else:
fail("Could not extract NDK: %s" % str(content))
os.putenv('ANDROID_NDK_HOME', os.path.abspath(NDK_DIR))
def prepare_repo(versions):
if os.path.isdir(REPO_DIR):
# get latest commits and tags from remote
check_call(['git', 'fetch', 'origin'], cwd=REPO_DIR)
else:
# clone repo
url = versions['obfs4']['url']
check_call(['git', 'clone', url, REPO_DIR])
# checkout tag
check_call(['git', 'checkout', '-f', versions['obfs4']['tag']], cwd=REPO_DIR)
# undo all changes
check_call(['git', 'reset', '--hard'], cwd=REPO_DIR)
# clean all untracked files and directories (-d) from repo
check_call(['git', 'clean', '-dffx'], cwd=REPO_DIR)
def build_android():
env = os.environ.copy()
env['GOARCH'] = "arm"
env['GOARM'] = "7"
build_android_arch(env, "arm-linux-androideabi", ndk_arch="arm", pie=False)
env = os.environ.copy()
env['GOARCH'] = "arm"
env['GOARM'] = "7"
build_android_arch(env, "arm-linux-androideabi", ndk_arch="arm", pie=True)
env = os.environ.copy()
env['GOARCH'] = "386"
build_android_arch(env, "i686-linux-android", ndk_arch="x86", pie=False)
env = os.environ.copy()
env['GOARCH'] = "386"
build_android_arch(env, "i686-linux-android", ndk_arch="x86", pie=True)
def build_android_arch(env, tool, ndk_arch, pie):
toolchain = os.path.join("toolchain", ndk_arch)
if not os.path.isdir(toolchain):
toolchain_maker = os.path.join(NDK_DIR, "build", "tools", "make-standalone-toolchain.sh")
ex([toolchain_maker, "--arch=%s" % ndk_arch, "--install-dir=%s" % toolchain])
env['CC'] = "%s/bin/%s-clang" % (os.path.abspath(toolchain), tool)
env['CGO_ENABLED'] = "1"
env['GOOS'] = "android"
build_mode = "pie" if pie else "exe"
ex(['go', 'build', '-buildmode=%s' % build_mode, '-o', 'obfs4proxy'] + glob(SOURCE), env=env)
ex(['%s/bin/%s-strip' % (toolchain, tool), '-D', 'obfs4proxy'])
pie_suffix = '_pie' if pie else ''
zip_file('obfs4proxy', 'obfs4proxy_%s%s.zip' % (ndk_arch, pie_suffix))
os.remove('obfs4proxy')
def build_linux():
ex(['go', 'build', '-o', 'obfs4proxy'] + glob(SOURCE))
ex(['strip', '-D', 'obfs4proxy'])
zip_file('obfs4proxy', 'obfs4proxy_linux-x86_64.zip')
os.remove('obfs4proxy')
def get_source_files():
files = []
for file_name in glob(SOURCE):
print(file_name)
return files
if __name__ == "__main__":
main()
utils.py 0 → 100644
import hashlib
import json
import sys
from collections import OrderedDict
from subprocess import check_call
REPO_DIR = 'tor-android'
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
def get_build_versions(tag):
# 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
tag = next(iter(versions))
return versions[tag]
def ex(args, env=None):
print("+ %s" % " ".join(args))
check_call(args, env=env)
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()
def zip_file(file_name, zip_name):
ex(['touch', '--no-dereference', '-t', '197001010000.00', file_name])
ex(['zip', '-X', zip_name, file_name])
{
"0.0.7": {
"obfs4": {
"url": "https://git.torproject.org/pluggable-transports/obfs4.git",
"got-get": "git.torproject.org/pluggable-transports/obfs4.git/obfs4proxy",
"tag": "obfs4proxy-0.0.7"
},
"ndk": {
"url": "https://dl.google.com/android/repository/android-ndk-r18-linux-x86_64.zip",
"revision": "18.0.5002713",
"sha256": "c413dd014edc37f822d0dc88fabc05b64232d07d5c6e9345224e47073fdf140b"
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment