diff --git a/scripts/build-debianpackage b/scripts/build-debianpackage index f3657794..5de77057 100755 --- a/scripts/build-debianpackage +++ b/scripts/build-debianpackage @@ -37,6 +37,7 @@ if [[ -z "${PKG_NAME:-}" ]]; then fi +# Look up most recent release from GitHub repo function find_latest_version() { repo_url="https://github.com/freedomofpress/${PKG_NAME}/releases" curl -s "$repo_url" \ @@ -58,15 +59,45 @@ fi # Copy over the debian directory (including new changelog) from repo cp -r "$CUR_DIR/$PKG_NAME/" "$TOP_BUILDDIR/" +# Ensures that a given git tag is signed with the prod release key +# If "rc" is in the tag name, this will fail. +function verify_git_tag() { + local d + local t + d="$1" + t="$2" + prod_fingerprint="22245C81E3BAEB4138B36061310F561200F4AD77" + git -C "$build_dir" tag --verify "$PKG_VERSION" 2>&1 \ + | grep -q -F "using RSA key $prod_fingerprint" +} + +# Dynamically generate a tarball, from the Python source code, +# that is byte-for-byte reproducible. Use timestamps from the git tag. function build_source_tarball() { repo_url="https://github.com/freedomofpress/${PKG_NAME}" build_dir="/tmp/${PKG_NAME}" rm -rf "$build_dir" git clone "$repo_url" "$build_dir" - git -C "$build_dir" tag --verify "$PKG_VERSION" 1>&2 - git -C "$build_dir" checkout "$PKG_VERSION" 1>&2 + + # Verify tag, using only the prod key + verify_git_tag "$build_dir" "$PKG_VERSION" || exit 1 + + # Tag is verified, proceed with checkout + git -C "$build_dir" checkout "$PKG_VERSION" 1>&2 || exit 1 (cd "$build_dir" && python setup.py sdist 1>&2) - find "${build_dir}/dist/" | grep -P '\.tar.gz$' | head -n1 + + # Initial tarball will contain timestamps from NOW, let's repack + # with timestamps from the signed tag. + raw_tarball="$(find "${build_dir}/dist/" | grep -P '\.tar.gz$' | head -n1)" + tag_time="$(git -C "$build_dir" log --format="%ai" --no-patch -n1 "$PKG_VERSION")" + (cd "$build_dir" && tar -xzf "dist/$(basename $raw_tarball)" 1>&2) + tarball_basename="$(basename "$raw_tarball")" + # Repack with tar only, so env vars are respected + (cd "$build_dir" && tar -cf "${tarball_basename%.gz}" --mode=go=rX,u+rw,a-s --mtime="$tag_time" --sort=name --owner=root:0 --group=root:0 "${tarball_basename%.tar.gz}" 1>&2) + # Then gzip it separately, so we can pass args + (cd "$build_dir" && gzip --no-name "${tarball_basename%.gz}" 1>&2) + (cd "$build_dir" && mv "$tarball_basename" dist/ 1>&2) + echo "$raw_tarball" } # If the package is contained in the list, it should be a python package. In