diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..9f5890c636 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,264 @@ +name: Build +on: + push: + branches: [master] + paths-ignore: [README.md] + release: + types: [published] +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +jobs: + precache-toolchains-linux: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: | + src/third_party/llvm-build/Release+Asserts/ + src/chrome/build/pgo_profiles/ + src/gn/ + src/chrome/android/profiles/ + key: toolchain-linux-${{ hashFiles('CHROMIUM_VERSION') }} + - run: ./get-clang.sh + working-directory: src + precache-toolchains-win: + defaults: + run: + shell: bash + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: | + src/third_party/llvm-build/Release+Asserts/ + src/chrome/build/pgo_profiles/ + src/gn/ + ~/.cargo/bin/ + key: toolchain-win-${{ hashFiles('CHROMIUM_VERSION') }} + - run: ./get-clang.sh + working-directory: src + precache-toolchains-mac: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: | + src/third_party/llvm-build/Release+Asserts/ + src/chrome/build/pgo_profiles/ + src/gn/ + src/tools/clang/dsymutil/ + key: toolchain-mac-${{ hashFiles('CHROMIUM_VERSION') }} + - run: ./get-clang.sh + working-directory: src + linux: + needs: precache-toolchains-linux + runs-on: ubuntu-18.04 + strategy: + fail-fast: false + matrix: + arch: [x64, x86, arm64, arm] + env: + EXTRA_FLAGS: 'target_cpu="${{ matrix.arch }}"' + BUNDLE: 'naiveproxy-${{ github.event.release.tag_name }}-${{ github.job }}-${{ matrix.arch }}' + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: ~/.ccache + key: ccache-${{ github.job }}-${{ matrix.arch }}-${{ hashFiles('CHROMIUM_VERSION') }} + - uses: actions/cache@v2 + with: + path: src/out/sysroot-build/ + key: sysroot-${{ github.job }}-${{ matrix.arch }}-${{ hashFiles('CHROMIUM_VERSION') }} + - uses: actions/cache@v2 + with: + path: | + src/third_party/llvm-build/Release+Asserts/ + src/chrome/build/pgo_profiles/ + src/gn/ + src/chrome/android/profiles/ + key: toolchain-linux-${{ hashFiles('CHROMIUM_VERSION') }} + - run: sudo apt update + - run: sudo apt install ninja-build pkg-config libnss3-dev qemu-user ccache + # libc6-i386 interferes with x86 build + - run: sudo apt remove libc6-i386 + - run: ./get-clang.sh + working-directory: src + - run: ccache -s + - run: ./build.sh + working-directory: src + - run: ccache -s + - run: ./tests/basic.sh src/out/Release/naive + - run: mkdir ${{ env.BUNDLE }} && cp src/out/Release/naive src/config.json LICENSE USAGE.txt ${{ env.BUNDLE }} + - run: tar cJf ${{ env.BUNDLE }}.tar.xz ${{ env.BUNDLE }} + - uses: actions/upload-release-asset@v1 + if: ${{ github.event_name == 'release' }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ env.BUNDLE }}.tar.xz + asset_name: ${{ env.BUNDLE }}.tar.xz + asset_content_type: application/octet-stream + win: + needs: precache-toolchains-win + runs-on: windows-latest + defaults: + run: + shell: bash + strategy: + fail-fast: false + matrix: + arch: [x64, x86, arm64] + env: + EXTRA_FLAGS: 'target_cpu="${{ matrix.arch }}"' + BUNDLE: 'naiveproxy-${{ github.event.release.tag_name }}-${{ github.job }}-${{ matrix.arch }}' + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: ~/AppData/Local/Mozilla/sccache + key: ccache-${{ github.job }}-${{ matrix.arch }}-${{ hashFiles('CHROMIUM_VERSION') }} + - uses: actions/cache@v2 + with: + path: | + src/third_party/llvm-build/Release+Asserts/ + src/chrome/build/pgo_profiles/ + src/gn/ + ~/.cargo/bin/ + key: toolchain-win-${{ hashFiles('CHROMIUM_VERSION') }} + - run: cinst ninja + - run: ./get-clang.sh + working-directory: src + - run: ~/.cargo/bin/sccache -s + - run: ./build.sh + working-directory: src + - run: ~/.cargo/bin/sccache -s + - run: ./tests/basic.sh src/out/Release/naive + if: ${{ matrix.arch != 'arm64' }} + - run: mkdir ${{ env.BUNDLE }} && cp src/out/Release/naive.exe src/config.json LICENSE USAGE.txt ${{ env.BUNDLE }} + - run: 7z a ${{ env.BUNDLE }}.zip ${{ env.BUNDLE }} + - uses: actions/upload-release-asset@v1 + if: ${{ github.event_name == 'release' }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ env.BUNDLE }}.zip + asset_name: ${{ env.BUNDLE }}.zip + asset_content_type: application/octet-stream + mac: + needs: precache-toolchains-mac + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + arch: [x64, arm64] + env: + EXTRA_FLAGS: 'target_cpu="${{ matrix.arch }}"' + BUNDLE: 'naiveproxy-${{ github.event.release.tag_name }}-${{ github.job }}-${{ matrix.arch }}' + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: ~/Library/Caches/ccache + key: ccache-${{ github.job }}-${{ matrix.arch }}-${{ hashFiles('CHROMIUM_VERSION') }} + - uses: actions/cache@v2 + with: + path: | + src/third_party/llvm-build/Release+Asserts/ + src/chrome/build/pgo_profiles/ + src/gn/ + src/tools/clang/dsymutil/ + key: toolchain-mac-${{ hashFiles('CHROMIUM_VERSION') }} + - run: brew install ninja ccache + - run: ./get-clang.sh + working-directory: src + - run: ccache -s + - run: ./build.sh + working-directory: src + - run: ccache -s + - run: ./tests/basic.sh src/out/Release/naive + if: ${{ matrix.arch != 'arm64' }} + - run: mkdir ${{ env.BUNDLE }} && cp src/out/Release/naive src/config.json LICENSE USAGE.txt ${{ env.BUNDLE }} + - run: tar cJf ${{ env.BUNDLE }}.tar.xz ${{ env.BUNDLE }} + - uses: actions/upload-release-asset@v1 + if: ${{ github.event_name == 'release' }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ env.BUNDLE }}.tar.xz + asset_name: ${{ env.BUNDLE }}.tar.xz + asset_content_type: application/octet-stream + openwrt: + needs: precache-toolchains-linux + runs-on: ubuntu-18.04 + strategy: + fail-fast: false + matrix: + include: + - arch: mipsel_24kc + target_cpu: mipsel + extra: 'mips_arch_variant="r2" mips_float_abi="soft" mips_tune="24kc" use_lld=false use_gold=false' + openwrt: 'target=ramips subtarget=rt305x abi=musl' + - arch: x86_64 + target_cpu: x64 + openwrt: 'target=x86 subtarget=64 abi=musl' + - arch: x86 + target_cpu: x86 + openwrt: 'target=x86 subtarget=generic abi=musl' + - arch: aarch64 + target_cpu: arm64 + openwrt: 'target=armvirt subtarget=64 abi=musl' + - arch: arm_cortex-a15_neon-vfpv4 + target_cpu: arm + extra: 'arm_version=0 arm_cpu="cortex-a15" arm_fpu="neon-vfpv4" arm_float_abi="hard"' + openwrt: 'target=ipq806x subtarget=generic abi=musl_eabi' + - arch: arm_cortex-a9 + target_cpu: arm + extra: 'arm_version=0 arm_cpu="cortex-a9" arm_float_abi="soft" arm_use_neon=false' + openwrt: 'target=bcm53xx subtarget=generic abi=musl_eabi' + env: + EXTRA_FLAGS: | + target_cpu="${{ matrix.target_cpu }}" + ${{ matrix.extra }} + use_allocator="none" use_allocator_shim=false + custom_toolchain="//build/toolchain/linux:clang_${{ matrix.target_cpu }}_openwrt" + OPENWRT_FLAGS: 'arch=${{ matrix.arch }} release=19.07.7 gcc_ver=7.5.0 ${{ matrix.openwrt }}' + BUNDLE: 'naiveproxy-${{ github.event.release.tag_name }}-${{ github.job }}-${{ matrix.arch }}' + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: ~/.ccache + key: ccache-${{ github.job }}-${{ matrix.arch }}-${{ hashFiles('CHROMIUM_VERSION') }} + - uses: actions/cache@v2 + with: + path: src/out/sysroot-build/ + key: openwrt-${{ github.job }}-${{ matrix.arch }}-19.07.7 + - uses: actions/cache@v2 + with: + path: | + src/third_party/llvm-build/Release+Asserts/ + src/chrome/build/pgo_profiles/ + src/gn/ + src/chrome/android/profiles/ + key: toolchain-linux-${{ hashFiles('CHROMIUM_VERSION') }} + - run: sudo apt update + - run: sudo apt install ninja-build pkg-config libnss3-dev qemu-user ccache + # libc6-i386 interferes with x86 build + - run: sudo apt remove libc6-i386 + - run: ./get-clang.sh + working-directory: src + - run: ccache -s + - run: ./build.sh + working-directory: src + - run: ccache -s + - run: ./tests/basic.sh src/out/Release/naive + - run: mkdir ${{ env.BUNDLE }} && cp src/out/Release/naive src/config.json LICENSE USAGE.txt ${{ env.BUNDLE }} + - run: tar cJf ${{ env.BUNDLE }}.tar.xz ${{ env.BUNDLE }} + - uses: actions/upload-release-asset@v1 + if: ${{ github.event_name == 'release' }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ env.BUNDLE }}.tar.xz + asset_name: ${{ env.BUNDLE }}.tar.xz + asset_content_type: application/octet-stream diff --git a/tests/basic.sh b/tests/basic.sh new file mode 100755 index 0000000000..9d03ca4864 --- /dev/null +++ b/tests/basic.sh @@ -0,0 +1,134 @@ +#!/bin/sh + +[ "$1" ] || exit 1 +naive="$1" +if [ "$(uname)" = Linux ]; then + . src/get-sysroot.sh + sysroot=$(get_sysroot) + eval "$EXTRA_FLAGS" + case "$target_cpu" in + arm64) naive="qemu-aarch64 -L src/$sysroot $naive";; + arm) naive="qemu-arm -L src/$sysroot $naive";; + x64) naive="qemu-x86_64 -L src/$sysroot $naive";; + x86) naive="qemu-i386 -L src/$sysroot $naive";; + mipsel) naive="qemu-mipsel -L src/$sysroot $naive";; + esac +fi + +set -ex + +MSYS_NO_PATHCONV=1 openssl req -new -x509 -keyout server.pem -out server.pem -days 1 -nodes -subj '/C=XX' +cat >server.py <hello.txt +python3=$(which python3 2>/dev/null || which python 2>/dev/null) +$python3 server.py & +trap "rm -f server.py server.pem hello.txt; kill $!" EXIT + +alias curl='curl -v --retry-connrefused --retry-delay 1 --retry 5' +curl -k https://127.0.0.1:60443/hello.txt + +test_proxy() { + curl --proxy "$1" -k https://127.0.0.1:60443/hello.txt | grep 'Hello' +} + +test_naive() { + test_name="$1" + proxy="$2" + echo "TEST '$test_name':" + shift 2 + if ( + trap 'kill $pid' EXIT + pid= + for arg in "$@"; do + $naive $arg & pid="$pid $!" + sleep 3 + done + test_proxy "$proxy" + ); then + echo "TEST '$test_name': PASS" + true + else + echo "TEST '$test_name': FAIL" + false + fi +} + +test_naive 'Default config' socks5h://127.0.0.1:1080 '--log' + +echo '{"listen":"socks://127.0.0.1:60101","log":""}' >config.json +test_naive 'Default config file' socks5h://127.0.0.1:60101 '' +rm -f config.json + +echo '{"listen":"socks://127.0.0.1:60201","log":""}' >/tmp/config.json +test_naive 'Config file' socks5h://127.0.0.1:60201 '/tmp/config.json' +rm -f /tmp/config.json + +test_naive 'Trivial - listen scheme only' socks5h://127.0.0.1:1080 \ + '--log --listen=socks://' + +test_naive 'Trivial - listen no host' socks5h://127.0.0.1:60301 \ + '--log --listen=socks://:60301' + +test_naive 'Trivial - listen no port' socks5h://127.0.0.1:1080 \ + '--log --listen=socks://127.0.0.1' + +test_naive 'Trivial - auth' socks5h://user:pass@127.0.0.1:60311 \ + '--log --listen=socks://user:pass@127.0.0.1:60311' + +test_naive 'Trivial - auth with special chars' socks5h://user:^@127.0.0.1:60312 \ + '--log --listen=socks://user:^@127.0.0.1:60312' + +test_naive 'Trivial - auth with special chars' socks5h://^:^@127.0.0.1:60313 \ + '--log --listen=socks://^:^@127.0.0.1:60313' + +test_naive 'Trivial - auth with empty pass' socks5h://user:@127.0.0.1:60314 \ + '--log --listen=socks://user:@127.0.0.1:60314' + +test_naive 'SOCKS-SOCKS' socks5h://127.0.0.1:60401 \ + '--log --listen=socks://:60401 --proxy=socks://127.0.0.1:60402' \ + '--log --listen=socks://:60402' + +test_naive 'SOCKS-SOCKS - proxy no port' socks5h://127.0.0.1:60501 \ + '--log --listen=socks://:60501 --proxy=socks://127.0.0.1' \ + '--log --listen=socks://:1080' + +test_naive 'SOCKS-HTTP' socks5h://127.0.0.1:60601 \ + '--log --listen=socks://:60601 --proxy=http://127.0.0.1:60602' \ + '--log --listen=http://:60602' + +test_naive 'HTTP-HTTP' http://127.0.0.1:60701 \ + '--log --listen=http://:60701 --proxy=http://127.0.0.1:60702' \ + '--log --listen=http://:60702' + +test_naive 'HTTP-SOCKS' http://127.0.0.1:60801 \ + '--log --listen=http://:60801 --proxy=socks://127.0.0.1:60802' \ + '--log --listen=socks://:60802' + +test_naive 'SOCKS-HTTP padded' socks5h://127.0.0.1:60901 \ + '--log --listen=socks://:60901 --proxy=http://127.0.0.1:60902 --padding' \ + '--log --listen=http://:60902 --padding' + +test_naive 'SOCKS-SOCKS-SOCKS' socks5h://127.0.0.1:61001 \ + '--log --listen=socks://:61001 --proxy=socks://127.0.0.1:61002' \ + '--log --listen=socks://:61002 --proxy=socks://127.0.0.1:61003' \ + '--log --listen=socks://:61003' + +test_naive 'SOCKS-HTTP-SOCKS' socks5h://127.0.0.1:61101 \ + '--log --listen=socks://:61101 --proxy=http://127.0.0.1:61102' \ + '--log --listen=http://:61102 --proxy=socks://127.0.0.1:61103' \ + '--log --listen=socks://:61103' + +test_naive 'HTTP-SOCKS-HTTP' http://127.0.0.1:61201 \ + '--log --listen=http://:61201 --proxy=socks://127.0.0.1:61202' \ + '--log --listen=socks://:61202 --proxy=http://127.0.0.1:61203' \ + '--log --listen=http://:61203' + +test_naive 'HTTP-HTTP-HTTP' http://127.0.0.1:61301 \ + '--log --listen=http://:61301 --proxy=http://127.0.0.1:61302' \ + '--log --listen=http://:61302 --proxy=http://127.0.0.1:61303' \ + '--log --listen=http://:61303'