Files
curl-impersonate/Makefile.in
T
lwthiker 54693023a3 Impersonate Firefox 109
Firefox impersonation was not updated in a long while. Add impersonation
for Firefox 109. The TLS signature is identical to previous versions,
with the usual changes to the HTTP headers.

Update NSS to the latest version as well, even though it is not
strictly necessary for the impersonation.
2023-01-28 18:37:40 +02:00

437 lines
15 KiB
Makefile

# Makefile to build curl-impersonate
# Some Makefile tricks were taken from https://tech.davis-hansson.com/p/make/
SHELL := bash
.ONESHELL:
.SHELLFLAGS := -euc
.DELETE_ON_ERROR:
# MAKEFLAGS += --warn-undefined-variables
# MAKEFLAGS += --no-builtin-rules
BROTLI_VERSION := 1.0.9
# In case this is changed, update build-and-test-make.yml as well
NSS_VERSION := nss-3.87
NSS_URL := https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_87_RTM/src/nss-3.87-with-nspr-4.35.tar.gz
# In case this is changed, update build-and-test-make.yml as well
BORING_SSL_COMMIT := 3a667d10e94186fd503966f5638e134fe9fb4080
NGHTTP2_VERSION := nghttp2-1.46.0
NGHTTP2_URL := https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2
CURL_VERSION := curl-7.84.0
brotli_install_dir := $(abspath brotli-$(BROTLI_VERSION)/out/installed)
brotli_static_libs := $(brotli_install_dir)/lib/libbrotlicommon-static.a $(brotli_install_dir)/lib/libbrotlidec-static.a
nss_install_dir := $(abspath $(NSS_VERSION)/dist/Release)
nss_static_libs := $(nss_install_dir)/lib/libnss_static.a
boringssl_install_dir := $(abspath boringssl/build)
boringssl_static_libs := $(boringssl_install_dir)/lib/libssl.a $(boringssl_install_dir)/lib/libcrypto.a
nghttp2_install_dir := $(abspath $(NGHTTP2_VERSION)/installed)
nghttp2_static_libs := $(nghttp2_install_dir)/lib/libnghttp2.a
# Dependencies needed to compile the Firefox version
firefox_libs := $(brotli_static_libs) $(nss_static_libs) $(nghttp2_static_libs)
# Dependencies needed to compile the Chrome version
chrome_libs := $(brotli_static_libs) $(boringssl_static_libs) $(nghttp2_static_libs)
# The following variables will be set by the configure script.
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @abs_srcdir@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
build = @build@
# Whether to link curl-impersonate with libcurl-impersonate statically.
static_build = @static_build@
# Whether the user provided a specific find for zlib
with_zlib = @with_zlib@
# Path to be passed to curl's --with-ca-bundle configure option.
with_ca_bundle = @with_ca_bundle@
# Path to be passed to curl's --with-ca-path configure option.
with_ca_path = @with_ca_path@
# Path to be passed to curl's --with-libnssckbi configure option (an option
# added for curl-impersonate).
with_libnssckbi = @with_libnssckbi@
CC = @CC@
CXX = @CXX@
STRIP = @STRIP@
# Auto-generate Makefile help.
# Borrowed from https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
help: ## Show this help message
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.PHONY: help
.DEFAULT_GOAL := help
firefox-build: $(CURL_VERSION)/.firefox ## Build the Firefox version of curl-impersonate
cd $(CURL_VERSION)
# Don't pass this Makefile's MAKEFLAGS
$(MAKE) MAKEFLAGS=
.PHONY: firefox-build
firefox-checkbuild: ## Run basic checks on the built binary
ifeq ($(host),$(build))
cd $(CURL_VERSION)
# Make sure all needed features were compiled in
./src/curl-impersonate-ff -V | grep -q zlib
./src/curl-impersonate-ff -V | grep -q brotli
./src/curl-impersonate-ff -V | grep -q nghttp2
./src/curl-impersonate-ff -V | grep -q NSS
$(info Build OK)
else
$(info Cross compiling, skipping checkbuild)
endif
.PHONY: firefox-checkbuild
firefox-install: ## Install the Firefox version of curl-impersonate after build
cd $(CURL_VERSION)
$(MAKE) install-exec MAKEFLAGS=
# Wrapper scripts for the Firefox version (e.g. 'curl_ff98')
install $(srcdir)/firefox/curl_ff* @bindir@
.PHONY: firefox-install
firefox-install-strip: ## Like 'firefox-install', but strip binaries for smaller size
cd $(CURL_VERSION)
$(MAKE) install-exec MAKEFLAGS=
# We could have used 'install-strip' but then the docs would be installed as well.
# Instead strip manually.
$(STRIP) @bindir@/curl-impersonate-ff
# Wrapper scripts for the Firefox version (e.g. 'curl_ff98')
install $(srcdir)/firefox/curl_ff* @bindir@
.PHONY: firefox-install-strip
firefox-uninstall: ## Uninstall the Firefox version of curl-impersonate after 'make install'
cd $(CURL_VERSION)
$(MAKE) uninstall MAKEFLAGS=
rm -Rf @bindir@/curl_ff*
.PHONY: firefox-uninstall
firefox-clean: ## Clean build artifacts of the Firefox version. Use after re-running './configure'
cd $(CURL_VERSION)
$(MAKE) clean MAKEFLAGS=
rm -f .firefox
.PHONY: firefox-clean
chrome-build: $(CURL_VERSION)/.chrome ## Build the Chrome version of curl-impersonate
cd $(CURL_VERSION)
# Don't pass this Makefile's MAKEFLAGS
$(MAKE) MAKEFLAGS=
.PHONY: chrome-build
chrome-checkbuild: ## Run basic checks on the built binary
ifeq ($(host),$(build))
cd $(CURL_VERSION)
# Make sure all needed features were compiled in
./src/curl-impersonate-chrome -V | grep -q zlib
./src/curl-impersonate-chrome -V | grep -q brotli
./src/curl-impersonate-chrome -V | grep -q nghttp2
./src/curl-impersonate-chrome -V | grep -q BoringSSL
$(info Build OK)
else
$(info Cross compiling, skipping checkbuild)
endif
.PHONY: chrome-checkbuild
chrome-install: ## Install the Chrome version of curl-impersonate after build
cd $(CURL_VERSION)
$(MAKE) install-exec MAKEFLAGS=
# Wrapper scripts for the Chrome version (e.g. 'curl_chrome99')
install $(srcdir)/chrome/curl_chrome* $(srcdir)/chrome/curl_edge* $(srcdir)/chrome/curl_safari* @bindir@
.PHONY: chrome-install
chrome-install-strip: ## Like 'chrome-install', but strip binaries for smaller size
cd $(CURL_VERSION)
$(MAKE) install-exec MAKEFLAGS=
# We could have used 'install-strip' but then the docs would be installed as well.
# Instead strip manually.
$(STRIP) @bindir@/curl-impersonate-chrome
# Wrapper scripts for the Chrome version (e.g. 'curl_chrome99')
install $(srcdir)/chrome/curl_chrome* $(srcdir)/chrome/curl_edge* $(srcdir)/chrome/curl_safari* @bindir@
.PHONY: chrome-install-strip
chrome-uninstall: ## Uninstall the Chrome version of curl-impersonate after 'make install'
cd $(CURL_VERSION)
$(MAKE) uninstall MAKEFLAGS=
rm -Rf @bindir@/curl_chrome* @bindir@/curl_edge* @bindir@/curl_safari*
.PHONY: chrome-uninstall
chrome-clean: ## Clean build artifacts of the Chrome version. Use after re-running './configure'
cd $(CURL_VERSION)
$(MAKE) clean MAKEFLAGS=
rm -f .chrome
.PHONY: chrome-clean
clean: ## Remove all build artifacts, including dependencies
rm -Rf brotli-$(BROTLI_VERSION).tar.gz brotli-$(BROTLI_VERSION)
rm -Rf $(NSS_VERSION).tar.gz $(NSS_VERSION)
rm -Rf boringssl.zip boringssl
rm -Rf $(NGHTTP2_VERSION).tar.bz2 $(NGHTTP2_VERSION)
rm -Rf $(CURL_VERSION).tar.xz $(CURL_VERSION)
brotli-$(BROTLI_VERSION).tar.gz:
curl -L "https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz" \
-o "brotli-${BROTLI_VERSION}.tar.gz"
$(brotli_static_libs): brotli-$(BROTLI_VERSION).tar.gz
tar xf brotli-$(BROTLI_VERSION).tar.gz
cd brotli-$(BROTLI_VERSION)
mkdir -p out
cd out
# Convert autoconf style os name to CMake style os name.
case $(host_os) in \
linux*) \
system_name=Linux \
;; \
darwin*) \
system_name=Darwin \
;; \
*) \
system_name=$(host_os) \
;; \
esac
@cmake@ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=./installed \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_CXX_COMPILER=$(CXX) \
-DCMAKE_C_COMPILER=$(CC) \
-DCMAKE_SYSTEM_NAME=$$system_name \
-DCMAKE_SYSTEM_PROCESSOR=$(host_cpu) \
..
@cmake@ --build . --config Release --target install
$(NSS_VERSION).tar.gz:
curl -L -o $(NSS_VERSION).tar.gz $(NSS_URL)
$(nss_static_libs): $(NSS_VERSION).tar.gz
tar xf $(NSS_VERSION).tar.gz
ifeq ($(host),$(build))
# Native build, use NSS' build script.
cd $(NSS_VERSION)/nss
./build.sh -o --disable-tests --static --python=python3
else
# We are cross compiling.
# Cross compiling NSS is not supported by its build script and is poorly
# documented. We need to compile NSPR manually and only then compile nss.
case $(host_cpu) in \
*64*) \
use_64="1"; \
nspr_configure_flags="--enable-64bit"; \
;; \
*) \
use_64="0"; \
;; \
esac
# Cross-compile nspr separately
cd $(NSS_VERSION)/nspr
./configure --prefix=$(nss_install_dir) \
--disable-debug --enable-optimize \
--target=$(host_alias) \
$$nspr_configure_flags
$(MAKE) MAKEFLAGS=
$(MAKE) install MAKEFLAGS=
# Now we can run ./build.sh with the already built nspr
cd ../nss
CC=$(CC) CXX=$(CXX) CCC=$(CXX) \
./build.sh -o --disable-tests --static --python=python3 \
--with-nspr=$(nss_install_dir)/include/nspr:$(nss_install_dir)/lib \
--target=$(host_cpu) \
-Duse_system_zlib=0 \
-Dsign_libs=0
endif
# Hack for macOS: Remove dynamic libraries to force the linker to use the
# static ones when linking curl.
rm -Rf $(nss_install_dir)/lib/*.dylib
boringssl.zip:
curl -L https://github.com/google/boringssl/archive/$(BORING_SSL_COMMIT).zip \
-o boringssl.zip
# Patch boringssl and use a dummy '.patched' file to mark it patched
boringssl/.patched: $(srcdir)/chrome/patches/boringssl-*.patch
unzip -q -o boringssl.zip
mv boringssl-$(BORING_SSL_COMMIT) boringssl
cd boringssl/
for p in $^; do patch -p1 < $$p; done
touch .patched
$(boringssl_static_libs): boringssl.zip boringssl/.patched
mkdir -p $(boringssl_install_dir)
cd $(boringssl_install_dir)
# Convert autoconf style os name to CMake style os name.
case $(host_os) in \
linux*) \
system_name=Linux \
;; \
darwin*) \
system_name=Darwin \
;; \
*) \
system_name=Linux \
;; \
esac
# The extra CMAKE_C_FLAGS are needed because otherwise boringssl fails to
# compile in release mode on some systems with gcc 12 (e.g. Fedora).
# In addition, guard these options with -Wno-unknown-warning-option to
# prevent clang from failing on them.
@cmake@ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POSITION_INDEPENDENT_CODE=on \
-DCMAKE_C_FLAGS="-Wno-unknown-warning-option -Wno-stringop-overflow -Wno-array-bounds" \
-DCMAKE_CXX_COMPILER=$(CXX) \
-DCMAKE_C_COMPILER=$(CC) \
-DCMAKE_SYSTEM_NAME=$$system_name \
-DCMAKE_SYSTEM_PROCESSOR=$(host_cpu) \
-GNinja \
..
@ninja@
# Fix the directory structure so that curl can compile against it.
# See https://everything.curl.dev/source/build/tls/boringssl
mkdir -p lib
ln -sf ../crypto/libcrypto.a lib/libcrypto.a
ln -sf ../ssl/libssl.a lib/libssl.a
cp -Rf ../include .
$(NGHTTP2_VERSION).tar.bz2:
curl -L $(NGHTTP2_URL) -o $(NGHTTP2_VERSION).tar.bz2
$(nghttp2_static_libs): $(NGHTTP2_VERSION).tar.bz2
tar -xf $(NGHTTP2_VERSION).tar.bz2
cd $(NGHTTP2_VERSION)
# Set up the configure flags to nghttp2.
# If the user provided the --host flag to our configure script
# (for cross compilation), then pass it on to nghttp2.
{ \
config_flags="--prefix=$(nghttp2_install_dir)"; \
config_flags="$$config_flags --with-pic --enable-lib-only"; \
config_flags="$$config_flags --disable-shared --disable-python-bindings"; \
if test -n "$(host_alias)"; then \
config_flags="$$config_flags --host=$(host_alias)"; \
fi; \
}
./configure $$config_flags
$(MAKE) MAKEFLAGS=
$(MAKE) install MAKEFLAGS=
$(CURL_VERSION).tar.xz:
curl -L "https://curl.se/download/$(CURL_VERSION).tar.xz" \
-o "$(CURL_VERSION).tar.xz"
# Apply the "Firefox version" patches and mark using a dummy file
$(CURL_VERSION)/.patched-ff: $(srcdir)/firefox/patches/curl-*.patch
rm -Rf $(CURL_VERSION)
tar -xf $(CURL_VERSION).tar.xz
cd $(CURL_VERSION)
for p in $^; do patch -p1 < $$p; done
# Re-generate the configure script
autoreconf -fi
touch .patched-ff
rm -f .patched-chrome
# Apply the "Chorme version" patches and mark using a dummy file
$(CURL_VERSION)/.patched-chrome: $(srcdir)/chrome/patches/curl-*.patch
rm -Rf $(CURL_VERSION)
tar -xf $(CURL_VERSION).tar.xz
cd $(CURL_VERSION)
for p in $^; do patch -p1 < $$p; done
# Re-generate the configure script
autoreconf -fi
touch .patched-chrome
rm -f .patched-ff
# This is a small hack that flags that curl was patched and configured in the "firefox" version
$(CURL_VERSION)/.firefox: $(firefox_libs) $(CURL_VERSION).tar.xz $(CURL_VERSION)/.patched-ff
cd $(CURL_VERSION)
# Set up the configure flags to curl.
# If the user provided the --host flag to our configure script
# (for cross compilation), then pass it on to curl.
{ \
config_flags="--prefix=@prefix@"; \
config_flags+=" --with-nghttp2=$(nghttp2_install_dir)"; \
config_flags+=" --with-brotli=$(brotli_install_dir)"; \
config_flags+=" --with-nss=$(nss_install_dir) --with-nss-deprecated"; \
config_flags+=" USE_CURL_SSLKEYLOGFILE=true"; \
if test "$(static_build)" = "yes"; then \
config_flags+=" --enable-static --disable-shared"; \
fi; \
if test -n "$(host_alias)"; then \
config_flags+=" --host=$(host_alias)"; \
fi; \
if test -n "$(with_zlib)"; then \
config_flags+=" --with-zlib=$(with_zlib)"; \
else \
config_flags+=" --with-zlib"; \
fi; \
if test -n "$(with_libnssckbi)"; then \
config_flags+=" --with-libnssckbi=$(with_libnssckbi)"; \
fi; \
add_cflags="-I$(nss_install_dir)/../public/nss"; \
add_cflags+=" -I$(nss_install_dir)/include/nspr"; \
}
echo "Configuring curl with: $$config_flags"
./configure $$config_flags CFLAGS="$$add_cflags"
# Remove possible leftovers from a previous compilation
$(MAKE) clean MAKEFLAGS=
touch .firefox
# Remove the Chrome flag if it exists
rm -f .chrome
# This is a small hack that flags that curl was patched and configured in the "chrome" version
$(CURL_VERSION)/.chrome: $(chrome_libs) $(CURL_VERSION).tar.xz $(CURL_VERSION)/.patched-chrome
cd $(CURL_VERSION)
# Set up the configure flags to curl.
# If the user provided the --host flag to our configure script
# (for cross compilation), then pass it on to curl.
{ \
config_flags="--prefix=@prefix@"; \
config_flags="$$config_flags --with-nghttp2=$(nghttp2_install_dir)"; \
config_flags="$$config_flags --with-brotli=$(brotli_install_dir)"; \
config_flags="$$config_flags --with-openssl=$(boringssl_install_dir)"; \
config_flags="$$config_flags USE_CURL_SSLKEYLOGFILE=true"; \
if test "$(static_build)" = "yes"; then \
config_flags="$$config_flags --enable-static --disable-shared";
fi; \
if test -n "$(host_alias)"; then \
config_flags="$$config_flags --host=$(host_alias)"; \
fi; \
if test -n "$(with_zlib)"; then \
config_flags="$$config_flags --with-zlib=$(with_zlib)"; \
else \
config_flags+=" --with-zlib"; \
fi; \
if test -n "$(with_ca_bundle)"; then \
config_flags="$$config_flags --with-ca-bundle=$(with_ca_bundle)"; \
fi; \
if test -n "$(with_ca_path)"; then \
config_flags="$$config_flags --with-ca-path=$(with_ca_path)"; \
fi; \
add_libs="-pthread"; \
add_cflags="-I$(boringssl_install_dir)"; \
}
echo "Configuring curl with: $$config_flags"
./configure $$config_flags CFLAGS="$$add_cflags" LIBS="$$add_libs"
# Remove possible leftovers from a previous compilation
$(MAKE) clean MAKEFLAGS=
touch .chrome
# Remove the Firefox flag if it exists
rm -f .firefox