--- emerge-webrsync 2006-04-15 22:09:54.000000000 +0300 +++ emerge-webrsync 2006-04-16 02:23:43.000000000 +0300 @@ -5,6 +5,12 @@ # Author: Karl Trygve Kalleberg # Rewritten from the old, Perl-based emerge-webrsync script +# +# gpg key import +# KEY_ID=0x7DDAD20D +# gpg --homedir /etc/portage/gnupg --keyserver subkeys.pgp.net --recv-keys $KEY_ID +# gpg --homedir /etc/portage/gnupg --edit-key $KEY_ID trust + # If PORTAGE_NICENESS is overriden via the env then it will # still pass through the portageq call and override properly. PORTAGE_NICENESS="$(/usr/lib/portage/bin/portageq envvar PORTAGE_NICENESS)" @@ -21,6 +27,13 @@ USERLAND="$(/usr/lib/portage/bin/portage DISTDIR="$(/usr/lib/portage/bin/portageq envvar PORTAGE_TMPDIR)/emerge-webrsync" PORTAGE_INST_UID="$(/usr/lib/portage/bin/portageq envvar PORTAGE_INST_UID)" PORTAGE_INST_GID="$(/usr/lib/portage/bin/portageq envvar PORTAGE_INST_GID)" +WEBSYNC_VERIFY_SIGNATURE="$(/usr/lib/portage/bin/portageq envvar WEBSYNC_VERIFY_SIGNATURE)" +PORTAGE_GPG_HOME="$(/usr/lib/portage/bin/portageq envvar PORTAGE_GPG_HOME)" + +if [ -z "$WEBSYNC_VERIFY_SIGNATURE" ]; then + WEBSYNC_VERIFY_SIGNATURE=0 +fi + if [ ! -d $DISTDIR ] ; then mkdir -p $DISTDIR fi @@ -50,6 +63,33 @@ else md5_com='true' fi +if [ $WEBSYNC_VERIFY_SIGNATURE != 0 ]; then + if type -p gpg > /dev/null; then + gpg_com='gpg --homedir "${PORTAGE_GPG_HOME}" --verify "${FILE}.gpgsig" "${FILE}"' + else + echo "Cannot find gpg" + exit 1 + fi +else + gpg_com='true' +fi + +if [ -f /usr/portage/metadata/timestamp.x ]; then + portage_current_timestamp=$(cut -f 1 -d " " /usr/portage/metadata/timestamp.x) +else + portage_current_timestamp=0 +fi + +check_snapshot_timestamp() { + local snapshot_timestamp=$(tar --to-stdout -xf "${FILE}" portage/metadata/timestamp.x | cut -f 1 -d " ") + + if [ $portage_current_timestamp -lt $snapshot_timestamp ]; then + return 0 + else + return 1 + fi +} + sync_local() { echo Syncing local tree... if type -p tarsync &> /dev/null; then @@ -57,14 +97,13 @@ sync_local() { echo "tarsync failed; tarball is corrupt?" exit 1; fi - rm "${FILE}" else - if ! tar jxf $FILE; then + if ! tar jxf "${FILE}"; then echo "Tar failed to extract the image. Please review the output." - echo "Executed command: tar jxf $FILE" + echo "Executed command: tar jxf ${FILE}" exit 1 fi - rm -f $FILE + rm -f "${FILE}" # Make sure user and group file ownership is ${PORTAGE_INST_UID}:${PORTAGE_INST_GID} chown -R ${PORTAGE_INST_UID:-0}:${PORTAGE_INST_GID:-0} portage cd portage @@ -72,9 +111,11 @@ sync_local() { --exclude='/distfiles' --exclude='/packages' \ --exclude='/local' . ${PORTDIR%%/} cd .. - echo "cleaning up" - rm -rf portage fi + + echo "cleaning up" + rm -fr portage "${FILE}*" + if hasq metadata-transfer ${FEATURES} ; then echo "transferring metadata/cache" emerge --metadata @@ -93,10 +134,19 @@ while (( $attempts < 40 )) ; do day=$(date -r $daysbefore +"%d") month=$(date -r $daysbefore +"%m") year=$(date -r $daysbefore +"%Y") + + seconds=$daysbefore else day=$(date -d "-$attempts day" +"%d") month=$(date -d "-$attempts day" +"%m") year=$(date -d "-$attempts day" +"%Y") + + seconds=$(date -d "$year-$month-$day" +"%s") + fi + + if [ $seconds -lt $portage_current_timestamp ]; then + echo " --- Portage content is newer than available snapshots" + exit 1 fi FILE_ORIG="portage-${year}${month}${day}.tar.bz2" @@ -123,25 +173,43 @@ while (( $attempts < 40 )) ; do echo " --- No md5sum present on the mirror. (Not yet available.)" continue elif [ -s "${FILE}" ]; then - if eval "$md5_com"; then - echo " === snapshot $FILE is correct, using it" + if eval "$md5_com" && eval "$gpg_com" && check_snapshot_timestamp; then + echo " === snapshot ${FILE} is correct, using it" sync_local echo echo " === Snapshot has been sync'd" echo exit 0 else - rm $FILE + rm "${FILE}" fi fi for i in $GENTOO_MIRRORS ; do - URI="${i}/snapshots/$FILE" - rm -f "$FILE" - if (eval "$FETCHCOMMAND $wgetops") && [ -s "$FILE" ]; then + URI="${i}/snapshots/${FILE}" + rm -f "${FILE}" + if (eval "$FETCHCOMMAND $wgetops") && [ -s "${FILE}" ]; then + URI="${i}/snapshots/${FILE}.gpgsig" + rm -f "${FILE}.gpgsig" + + if [ $WEBSYNC_VERIFY_SIGNATURE != 0 ]; then + if ! (eval "$FETCHCOMMAND $wgetops") || ! [ -s "${FILE}.gpgsig" ]; then + echo "Cannot download signature for ${FILE}" + continue + fi + fi + if ! eval "$md5_com"; then - echo "md5 failed on $FILE" - rm ${FILE} + echo "md5 failed on ${FILE}" + rm "${FILE}" + continue + elif ! eval "$gpg_com"; then + echo "Signature validation failed on ${FILE}" + rm "${FILE}" + continue + elif ! check_snapshot_timestamp; then + echo "Timestamp is invalid on ${FILE}" + rm "${FILE}" continue else sync_local