X-Git-Url: https://git.decadent.org.uk/gitweb/?p=dak.git;a=blobdiff_plain;f=scripts%2Fdebian%2Fbuildd-add-keys;h=619a514f07458d432b418700574784f4774bdf8e;hp=2ba4bac176283804b6a8aae23d75d8434b200c0d;hb=dd80b169287a128cd9e3b833852fbf68106385b5;hpb=1e635a1eca99ce9535cf43229a447aa2b5de0b4c diff --git a/scripts/debian/buildd-add-keys b/scripts/debian/buildd-add-keys index 2ba4bac1..619a514f 100755 --- a/scripts/debian/buildd-add-keys +++ b/scripts/debian/buildd-add-keys @@ -1,7 +1,7 @@ #!/bin/bash # No way I try to deal with a crippled sh just for POSIX foo. -# Copyright (C) 2011 Joerg Jaspert +# Copyright (C) 2011,2012 Joerg Jaspert # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -43,20 +43,20 @@ function cleanup() { trap - ERR EXIT TERM HUP INT QUIT for TEMPFILE in GPGSTATUS GPGLOGS GPGOUTF TEMPKEYDATA; do - TFILE=${TEMPFILE:=$TEMPFILE} - DELF=${!TFILE:-""} + DELF=${!TEMPFILE:-""} if [ -n "${DELF}" ] && [ -f "${DELF}" ]; then rm -f "${DELF}" fi done exit $ERRVAL } -trap cleanup ERR EXIT TERM HUP INT QUIT base="${base}/scripts/builddkeyrings" INCOMING="${base}/incoming" ERRORS="${base}/errors" ADMINS="${base}/adminkeys.gpg" +ARCHADMINS="${base}/archadminkeys" +STAMPFILE="${base}/updatedkeyring" # Default options for our gpg calls DEFGPGOPT="--no-default-keyring --batch --no-tty --no-options --exit-on-status-write-error --no-greeting" @@ -66,11 +66,22 @@ if ! [ -d "${INCOMING}" ]; then exit 1 fi +cd "${INCOMING}" +KEYS=$(find . -maxdepth 1 -mindepth 1 -type f -name \*.key | sed -e "s,./,," | xargs) +if [ -z "${KEYS}" ]; then + exit 0 +fi + +trap cleanup ERR EXIT TERM HUP INT QUIT + +# Tell prepare-dir that there is an update and it can run +touch "${STAMPFILE}" + # Whenever something goes wrong, its put in there. mkdir -p "${ERRORS}" # We process all new files in our incoming directory -for file in $(ls -1 ${INCOMING}/*.key); do +for file in ${KEYS}; do file=${file##*/} # First we want to see if we recognize the filename. The buildd people have # to follow a certain schema: @@ -120,8 +131,12 @@ for file in $(ls -1 ${INCOMING}/*.key); do exec 4> "${GPGSTATUS}" exec 5> "${GPGLOGS}" + KEYRINGS="--keyring ${ADMINS}" + if [ -f "${ARCHADMINS}/${ARCH}.gpg" ]; then + KEYRINGS="${KEYRINGS} --keyring ${ARCHADMINS}/${ARCH}.gpg" + fi # So lets run gpg, status/logger into the two files, to "decrypt" the keyfile - if ! gpg ${DEFGPGOPT} --keyring "${ADMINS}" --status-fd 4 --logger-fd 5 --decrypt "${INCOMING}/${file}" > "${GPGOUTF}"; then + if ! gpg ${DEFGPGOPT} ${KEYRINGS} --status-fd 4 --logger-fd 5 --decrypt "${INCOMING}/${file}" > "${GPGOUTF}"; then ret=$? log "gpg returned with ${ret}, not adding key from file ${file}" DATE=$(date -Is) @@ -130,7 +145,7 @@ for file in $(ls -1 ${INCOMING}/*.key); do mv "${GPGLOGS}" "${ERRORS}/gpgerror.${file}.gpglogs.${DATE}" rm -f "${GPGOUTF}" continue - fi + fi # gpg broke # Read in the status output GPGSTAT=$(cat "${GPGSTATUS}") @@ -156,65 +171,102 @@ for file in $(ls -1 ${INCOMING}/*.key); do # - keysize 4096 or larger # - RSA key, no encryption capability # - UID matching "buildd autosigning key BUILDDNAME - # - expire within a 120 days + # - expire within a 360 days # - maximum 2 keys per architecture and buildd TEMPKEYDATA=$(mktemp -p "${TMPDIR}" BDKEYS.XXXXXX) - gpg ${DEFGPGOPT} --with-colons "${GPGOUTF}" > "${TEMPKEYDATA}" + # We also need to ensure this works, otherwise manually mangled files can break us here + if ! gpg ${DEFGPGOPT} --with-colons "${GPGOUTF}" > "${TEMPKEYDATA}"; then + log "For some reason we could validate the sig but failed on getting key details" + DATE=$(date -Is) + mv "${INCOMING}/${file}" "${ERRORS}/badsig.${file}.${DATE}" + mv "${GPGSTATUS}" "${ERRORS}/badsig.${file}.gpgstatus.${DATE}" + mv "${GPGLOGS}" "${ERRORS}/badsig.${file}.gpglogs.${DATE}" + rm -f "${GPGOUTF}" + rm -f "${TMPKEYDATA}" + continue + fi # Read in the TEMPKEYDATAFILE, but avoid using a subshell like a # while read line otherwise would do exec 4<> "${TEMPKEYDATA}" - error="" + KEYUID="" + #pub:-:4096:1:FAB983612A6554FA:2011-03-24:2011-07-22::-:buildd autosigning key poulenc : + + # Of course this sucky gpg crapshit of an "interface" does give you different things depending on how people + # created their keys. And of course the buildd people created the test keys differently to what they now do + # which just means extra work for nothing. So as they now do other steps, the thing we get back suddenly looks like + + #pub:-:4096:1:99595DC7865BEAD2:2011-03-26:2011-07-24::-: + #uid:::::::::buildd autosigning key corelli : + + # Besides fiddling out the data we need to check later, this regex also check: + # - the keytype (:1:, 1 there means RSA) + # - the UID + # - that the key does have an expiration date (or it wont match, the second date + # field would be empty + regex="^pub:-:([0-9]{4}):1:([0-9A-F]{16}):([0-9]{4}-[0-9]{2}-[0-9]{2}):([0-9]{4}-[0-9]{2}-[0-9]{2})::-:(buildd autosigning key ${BUILDD} ):$" + regex2="^pub:-:([0-9]{4}):1:([0-9A-F]{16}):([0-9]{4}-[0-9]{2}-[0-9]{2}):([0-9]{4}-[0-9]{2}-[0-9]{2})::-:$" + regex3="^uid:::::::::(buildd autosigning key ${BUILDD} ):$" while read line <&4; do - #pub:-:4096:1:FAB983612A6554FA:2011-03-24:2011-07-22::-:buildd autosigning key poulenc : - - # Besides fiddling out the data we need to check later, this regex also check: - # - the keytype (:1:, 1 there means RSA) - # - the UID - # - that the key does have an expiration date (or it wont match, the second date - # field would be empty - regex="^pub:-:([0-9]{4}):1:([0-9A-F]{16}):([0-9]{4}-[0-9]{2}-[0-9]{2}):([0-9]{4}-[0-9]{2}-[0-9]{2})::-:buildd autosigning key ${BUILDD} :$" if [[ $line =~ $regex ]]; then KEYSIZE=${BASH_REMATCH[1]} KEYID=${BASH_REMATCH[2]} KEYCREATE=${BASH_REMATCH[3]} KEYEXPIRE=${BASH_REMATCH[4]} - - # We do want 4096 or anything above - if [ ${KEYSIZE} -lt 4096 ]; then - log "Keysize ${KEYSIZE} too small" - error="${error} Keysize ${KEYSIZE} too small" - continue - fi - - # We want a maximum lifetime of 120 days, so check that. - # Easiest to compare in epoch, so lets see, 120 days midnight from now, - # compared with their set expiration date at midnight - # maxdate should turn out higher. just in case we make it 121 for this check - maxdate=$(date -d '121 day 00:00:00' +%s) - theirexpire=$(date -d "${KEYEXPIRE} 00:00:00" +%s) - if [ ${theirexpire} -gt ${maxdate} ]; then - log "Key expiry ${KEYEXPIRE} wrong" - error="${error} Key expiry ${KEYEXPIRE} wrong" - continue - fi - else - log "Unknown line $line, sod off" - error="${error} Unknown line $line, sod off" - continue - fi + KEYUID=${BASH_REMATCH[5]} + elif [[ $line =~ $regex2 ]]; then + KEYSIZE=${BASH_REMATCH[1]} + KEYID=${BASH_REMATCH[2]} + KEYCREATE=${BASH_REMATCH[3]} + KEYEXPIRE=${BASH_REMATCH[4]} + elif [[ $line =~ $regex3 ]]; then + KEYUID=${BASH_REMATCH[1]} + else + log "Didn't recognize the key. Go kiss gpg" + DATE=$(date -Is) + mv "${INCOMING}/${file}" "${ERRORS}/badkey.${file}.${DATE}" + mv "${GPGSTATUS}" "${ERRORS}/badkey.${file}.gpgstatus.${DATE}" + mv "${GPGLOGS}" "${ERRORS}/badkey.${file}.gpglogs.${DATE}" + rm -f "${GPGOUTF}" + continue + fi done - if [ -n "${error}" ]; then - log ${error} + if [ -z "${KEYUID}" ]; then + log "Did not recognize the UID format" DATE=$(date -Is) - mv "${INCOMING}/${file}" "${ERRORS}/badkey.${file}.${DATE}" - mv "${GPGSTATUS}" "${ERRORS}/badkey.${file}.gpgstatus.${DATE}" - mv "${GPGLOGS}" "${ERRORS}/badkey.${file}.gpglogs.${DATE}" - echo "${error}" >> "${ERRORS}/badkey.${file}.error.${DATE}" + mv "${INCOMING}/${file}" "${ERRORS}/keyuid.${file}.${DATE}" + mv "${GPGSTATUS}" "${ERRORS}/keyuid.${file}.gpgstatus.${DATE}" + mv "${GPGLOGS}" "${ERRORS}/keyuid.${file}.gpglogs.${DATE}" rm -f "${GPGOUTF}" - continue + continue + fi + # We do want 4096 or anything above + if [ ${KEYSIZE} -lt 4096 ]; then + log "Keysize ${KEYSIZE} too small" + DATE=$(date -Is) + mv "${INCOMING}/${file}" "${ERRORS}/keysize.${file}.${DATE}" + mv "${GPGSTATUS}" "${ERRORS}/keysize.${file}.gpgstatus.${DATE}" + mv "${GPGLOGS}" "${ERRORS}/keysize.${file}.gpglogs.${DATE}" + rm -f "${GPGOUTF}" + continue + fi + + # We want a maximum lifetime of 365 days, so check that. + # Easiest to compare in epoch, so lets see, 365 days midnight from now, + # compared with their set expiration date at midnight + # maxdate should turn out higher. just in case we make it 366 for this check + maxdate=$(date -d '366 day 00:00:00' +%s) + theirexpire=$(date -d "${KEYEXPIRE} 00:00:00" +%s) + if [ ${theirexpire} -gt ${maxdate} ]; then + log "Key expiry ${KEYEXPIRE} wrong" + DATE=$(date -Is) + mv "${INCOMING}/${file}" "${ERRORS}/keyexpire.${file}.${DATE}" + mv "${GPGSTATUS}" "${ERRORS}/keyexpire.${file}.gpgstatus.${DATE}" + mv "${GPGLOGS}" "${ERRORS}/keyexpire.${file}.gpglogs.${DATE}" + rm -f "${GPGOUTF}" + continue fi # And now lets check how many keys this buildd already has. 2 is the maximum, so key @@ -234,7 +286,9 @@ for file in $(ls -1 ${INCOMING}/*.key); do # Right. At this point everything should be in order, which means we should put the key into # the keyring - log "Accepting key ${KEYID} for ${ARCH} buildd ${BUILDD}, expire ${KEYEXPIRE}" + KEYSUBMITTER=$(cat "${GPGSTATUS}"|grep GOODSIG) + KEYSUBMITTER=${KEYSUBMITTER##*GOODSIG} + log "${KEYSUBMITTER} added key ${KEYID} for ${ARCH} buildd ${BUILDD}, expire ${KEYEXPIRE}" gpg ${DEFGPGOPT} --status-fd 4 --logger-fd 5 --keyring "${ARCHKEYRING}" --import "${GPGOUTF}" 2>/dev/null mv "${INCOMING}/${file}" "${base}/${ARCH}"