diff --git a/.gitignore b/.gitignore index e559e6f..d18d444 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # Things we don't care about. .built +./test *~ diff --git a/Makefile b/Makefile index 07e6bc4..a265fc1 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ $(BUILT): prep Dockerfile Makefile TO_CLEAN += $(BUILT) -TEST_DIR := ./signed-repo +TEST_DIR := ./test $(TEST_DIR): rm -rf $@ cp -r "$(TEST_REPO)" $@ diff --git a/prep/Linux-post b/prep/Linux-post index 6080c7a..67db325 100755 --- a/prep/Linux-post +++ b/prep/Linux-post @@ -14,4 +14,5 @@ do_install() # Entry point. This does the deed. do_install 555 container/entry /entry -echo Installed entry script +do_install 555 container/entry-user /entry-user +echo Installed entry scripts diff --git a/prep/container/entry b/prep/container/entry index b11ab4d..f2ffee1 100755 --- a/prep/container/entry +++ b/prep/container/entry @@ -15,71 +15,26 @@ die() SIGN=/sign -WORK=/work -# -# Configure GPG -# - -KEY_FILE=/work/gpg-signing-key -[ -f "${KEY_FILE}" -a -r "${KEY_FILE}" ] \ - || die "${KEY_FILE}: Not found" - -PASSPHRASE_FILE=/work/gpg-signing-key-passphrase -[ -f "${PASSPHRASE_FILE}" -a -r "${PASSPHRASE_FILE}" ] \ - || die "${KEY_FILE}: Not found" - -export GNUPGHOME="${WORK}/dot-gnupg" -mkdir -p "${GNUPGHOME}" -chmod 700 "${GNUPGHOME}" - -gpg --import < "${KEY_FILE}" +# User account to match signing area's owner. This account will do +# the signing. -# Since we're working in a fresh directory, there should be exactly one key. -[ $(gpg --list-keys | awk '$1 == "uid" { print }' | wc -l) -eq 1 ] \ - || die "Too many keys in GPG" +SIGN_USER=signer +SIGN_GROUP=signer +SIGN_AREA_UID=$(stat -c %u "${SIGN}") +SIGN_AREA_GID=$(stat -c %g "${SIGN}") -KEY_NAME=$(gpg --list-keys --with-colons \ - | awk -F: '$1 == "uid" {print $10}') - -if [ -e '/etc/redhat-release' ] +if [ "${SIGN_AREA_GID}" -ne 0 ] then - - # - # Configure RPM - # - - RPMDB="${WORK}/rpmdb" - mkdir -p "${RPMDB}" - chmod 700 "${RPMDB}" - - rpm --dbpath "${RPMDB}" --initdb - rpm --dbpath "${RPMDB}" --import "${KEY_FILE}" - - echo "Signing RPM packages as ${KEY_NAME}:" - - # PORT: xargs -0 -r is GNU-specific. - find "${SIGN}" -name '*.rpm' -print0 \ - | xargs -0 -r rpm \ - --dbpath "${RPMDB}" \ - --define "_gpg_path $${GNUPGHOME}" \ - --define "_gpg_name $${KEY_NAME}" \ - --addsign - - # TODO: Does the repo data need to be rebuilt after the files are changed? - - -elif [ -e '/etc/debian_version' ]; then - - # TODO: Support Debian - die "Debian is not supported yet." - + groupadd -g "${SIGN_AREA_GID}" "${SIGN_GROUP}" +fi +if [ "${SIGN_AREA_UID}" -ne 0 ] +then + useradd -u "${SIGN_AREA_UID}" -g "${SIGN_GROUP}" -m "${SIGN_USER}" else - - die "Unsupported OS" - + # We're already root. Be root. + SIGN_USER=root fi - -# At this point, the container will be destroyed. -exit 0 +# After this, the container will be destroyed. +exec su - "${SIGN_USER}" -c "/entry-user '${SIGN}'" diff --git a/prep/container/entry-user b/prep/container/entry-user new file mode 100644 index 0000000..09aad7f --- /dev/null +++ b/prep/container/entry-user @@ -0,0 +1,99 @@ +#!/bin/sh -e +# +# Do a signing in the directory named by $1 + +die() +{ + echo "$@" 1>&2 + exit 1 +} + + +SIGN=$1 +[ -d "${SIGN}" ] \ + || die "${SIGN}: Not a directory" + +WORK="${SIGN}/DOSS" +[ -d "${WORK}" ] \ + || die "${WORK}: Work directory not found" + + +printf "\n\nSigning\n\n" + +id + +echo +ls -alh / +echo +ls -alh "${SIGN}" +echo +ls -alh "${WORK}" +echo + +exit 99 + + + +# +# Configure GPG +# + +KEY_FILE="${WORK}/gpg-signing-key +[ -f "${KEY_FILE}" -a -r "${KEY_FILE}" ] \ + || die "${KEY_FILE}: Not found" + +PASSPHRASE_FILE=${WORK}/gpg-signing-key-passphrase +[ -f "${PASSPHRASE_FILE}" -a -r "${PASSPHRASE_FILE}" ] \ + || die "${KEY_FILE}: Not found" + +export GNUPGHOME="${WORK}/dot-gnupg" +mkdir -p "${GNUPGHOME}" +chmod 700 "${GNUPGHOME}" + +gpg --import < "${KEY_FILE}" + +# Since we're working in a fresh directory, there should be exactly one key. +[ $(gpg --list-keys | awk '$1 == "uid" { print }' | wc -l) -eq 1 ] \ + || die "Too many keys in GPG" + +KEY_NAME=$(gpg --list-keys --with-colons \ + | awk -F: '$1 == "uid" {print $10}') + +if [ -e '/etc/redhat-release' ] +then + + # + # Configure RPM + # + + RPMDB="${WORK}/rpmdb" + mkdir -p "${RPMDB}" + chmod 700 "${RPMDB}" + + rpm --dbpath "${RPMDB}" --initdb + rpm --dbpath "${RPMDB}" --import "${KEY_FILE}" + + echo "Signing RPM packages as ${KEY_NAME}:" + + # PORT: xargs -0 -r is GNU-specific. + find "${SIGN}" -name '*.rpm' -print0 \ + | xargs -0 -r rpm \ + --dbpath "${RPMDB}" \ + --define "_gpg_path $${GNUPGHOME}" \ + --define "_gpg_name $${KEY_NAME}" \ + --addsign + + # TODO: Does the repo data need to be rebuilt after the files are changed? + + +elif [ -e '/etc/debian_version' ]; then + + # TODO: Support Debian + die "Debian is not supported yet." + +else + + die "Unsupported OS" + +fi + diff --git a/sign b/sign index 004342c..6187f00 100755 --- a/sign +++ b/sign @@ -21,16 +21,6 @@ set -e WHOAMI=$(basename "$0") -WORK=$(mktemp -d) -chmod 700 "${WORK}" - -cleanup() -{ - rm -rf "${WORK}" -} -trap cleanup EXIT - - die() { echo "$@" 1>&2 @@ -118,6 +108,21 @@ echo "${REPO_DIR}" | fgrep -q ':' \ REPO_DIR=$(cd "${REPO_DIR}" && pwd) +# Work directory (created within the repository directory) + +WORK="${REPO_DIR}/DOSS" +mkdir -p "${WORK}" +chmod 700 "${WORK}" + +cleanup() +{ + # TODO: Enable this + echo DISABLED rm -rf "${WORK}" +} +trap cleanup EXIT + + + # GPG Key and Passphrase if echo "$2" | egrep -q -e '^@' @@ -131,8 +136,6 @@ fi echo "${PASSPHRASE}" > "${WORK}/gpg-signing-key-passphrase" -ls -alR $WORK - # Figure out what kind of packages we're signing and which container # to use. @@ -158,7 +161,6 @@ else fi - # Make it happen if [ "$(id -u)" -ne 0 ] @@ -174,8 +176,7 @@ ${ECHO} ${SUDO} docker run \ --tty \ --tmpfs /tmp \ --tmpfs /run \ - --volume "${REPO_DIR}:/repo" \ - --volume "${WORK}:/work" \ + --volume "${REPO_DIR}:/sign:rw" \ --rm \ "${CONTAINER}" \ || STATUS=$?