On 04/07/11 22:13, Wieland Hoffmann wrote:
Many projects provide signature files along with the source code
archives. It's good to check these, too, when verifying the integrity
of source code archives.
Not everybody is using gpg so the verification can be disabled with
--skippgpcheck.

Additionally, only a warning is displayed when the key that signed the
source file is unknown. Expired keys and signatures aren't considered an
error, too.
---

Looking good.   Some general comments:

I saw that --skipinteg implies --skippgpcheck. I noticed this when I copied a "bad" signature into my source directory and I did not update the md5sums so used --skipinteg. I was quite surprised when the signatures did not get checked. Should these be separated more?

I still wonder if --skippgpcheck is too long, but I can not think of a better name. Suggestions from anyone?


  doc/makepkg.8.txt     |    3 ++
  scripts/makepkg.sh.in |   72 ++++++++++++++++++++++++++++++++++++++++++++++++-
  2 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/doc/makepkg.8.txt b/doc/makepkg.8.txt
index e11e9b3..255fbca 100644
--- a/doc/makepkg.8.txt
+++ b/doc/makepkg.8.txt
@@ -169,6 +169,9 @@ Options
        in linkman:makepkg.conf[5]. If not specified in either location, the
        default key from the keyring will be used.

+*\--skippgpcheck*::
+       Verify PGP signatures of the source files if provided in the build 
script.
+
  *\--noconfirm*::
        (Passed to pacman) Prevent pacman from waiting for user input before
        proceeding with operations.
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 1b132a9..0b7bed6 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -57,6 +57,7 @@ FORCE=0
  INFAKEROOT=0
  GENINTEG=0
  SKIPINTEG=0
+NOPGPSIGS=0

I'd prefer renaming this to SKIPPGPCHECK=0 to keep the name like the flag like with SKIPINTEG.

  INSTALL=0
  NOBUILD=0
  NODEPS=0
@@ -674,6 +675,63 @@ check_checksums() {
        fi
  }

+check_pgpsigs() {
+       (( NOPGPSIGS ))&&  return 0
+       (( ! ${#source[@]} ))&&  return 0

We need a helper function here "source_has_signatures" that will allow us to exit if the source array has not signatures in it. that way we will not get the following message and then no checks. Is will also be useful elsewhere (see below).

+       msg "$(gettext "Verifying source file signatures with gpg...")"

msg "$(gettext "Verifying source file signatures with %s...")" "gpg"

or just delete the "with gpg" part?

+
+       local file
+       local errors=0

We should keep track of the number of non-error warnings too so a "==> WARNING:" message could be outputed.

+       local statusfile=$(mktemp)
+
+       for file in "${source[@]}"; do
+               local valid
+               local found=1
+
+               file="$(get_filename "$file")"
+               if [[ $file =~ .*(sig|asc) ]]; then

Lets reduce the nested ifs here with something like:

if [[ ! $file =~ .*(sig|asc) ]]; then
        continue
fi

+                       echo -n "    $file ... ">&2

I'd use ${file%.*} to output the name of the file being checked rather than the signature.

+                       if ! file="$(get_filepath "$file")"; then
+                               echo "$(gettext "NOT FOUND")">&2
+                               errors=1
+                               found=0
+                       fi

We should check the source file is also present.


+                       if (( found )); then

Lets get rid of this and just do a "continue" instead of setting found=0 above. I'm patching the check_checksums() function to do that too...

+                               if ! gpg --quiet --batch --status-file "$statusfile" 
--verify "$file" 2>  /dev/null; then
+                                       if grep "NO_PUBKEY" "$statusfile">  
/dev/null; then
+                                               echo "">&2

I think we should stick to plain output here and have a big warning at the end (as mentioned above). See below for further comments.

+                                               warning "$(gettext "Unknown public key") 
$(awk '/NO_PUBKEY/ {print $3}' $statusfile)">&2
+                                       else
+                                               echo "$(gettext "Verification 
failed")">&2
+                                               errors=1
+                                       fi
+                               else
+                                       if grep "REVKEYSIG" "$statusfile">  
/dev/null; then
+                                               errors=1
+                                               echo "$(gettext "Verified, but the key that 
signed it has been revoked.")">&2
+                                       elif grep "EXPSIG" "$statusfile">  
/dev/null; then
+                                               echo "$(gettext "Verified, but the signature is 
expired.")">&2
+                                       elif grep "EXPKEYSIG" "$statusfile">  
/dev/null; then
+                                               echo "$(gettext "Verified, but the key that 
signed it is expired.")">&2
+                                       else
+                                               echo $(gettext "Verified")>&2
+                                       fi
+                               fi

Lets unify the output with the integrity checking as much as possible. So "FAILED" on failure, "Passed" on success.

Now for the in between cases...  maybe like this?

echo "$(gettext "Warning: unknown key '%s'")"  $(awk...)
echo "$(gettext "Passed")" "-" "$(gettext "Warning: key has been revoked.")"
echo "$(gettext "Passed")" "-" "$(gettext "Warning: signature has expired.")"
echo "$(gettext "Passed")" "-" "$(gettext "Warning: key has expired.")"

How does that seem?

+                       fi
+               fi
+       done
+
+       rm -f "$statusfile"
+
+       if (( errors )); then
+               error "$(gettext "One or more PGP signatures could not be 
verified!")"
+               exit 1
+       fi

if (( warnings )); then
        warning "$....
fi

+}
+
  extract_sources() {
        msg "$(gettext "Extracting Sources...")"
        local netfile
@@ -1478,6 +1536,14 @@ check_software() {
                fi
        fi

+       # gpg - source verification
+       if [[ ! NOPGPSIGS ]]; then

Use the helper function mentioned above so we only give this warning if signatures are to be checked AND there are some to check.

+               if ! type -p gpg>/dev/null; then
+                       error "$(gettext "Cannot find the %s binary required for verifying source 
files.")" "gpg"
+                       ret=1
+               fi
+       fi
+
        # openssl - checksum operations
        if (( ! SKIPINTEG )); then
                if ! type -p openssl>/dev/null; then
@@ -1712,6 +1778,7 @@ usage() {
        printf "$(gettext "  --key<key>       Specify a key to use for %s signing instead of the 
default")\n" "gpg"
        printf "$(gettext "  --nocheck        Do not run the %s function in the %s")\n" 
"check()" "$BUILDSCRIPT"
        echo "$(gettext "  --nosign         Do not create a signature for the 
package")"
+       echo "$(gettext "  --skippgpcheck   Disable verification of source files with pgp 
signatures")"
        echo "$(gettext "  --pkg<list>      Only build listed packages from a split 
package")"
        printf "$(gettext "  --sign           Sign the resulting package with %s")\n" 
"gpg"
        echo "$(gettext "  --skipinteg      Do not fail when integrity checks are 
missing")"
@@ -1749,7 +1816,7 @@ ARGLIST=("$@")
  # Parse Command Line Options.
  OPT_SHORT="AcCdefFghiLmop:rRsV"
  OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps"
-OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver"
+OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck"
  OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps"
  OPT_LONG+=",repackage,skipinteg,sign,source,syncdeps,version,config:"
  # Pacman Options
@@ -1791,6 +1858,7 @@ while true; do
                --nosign)         SIGNPKG='n' ;;
                -o|--nobuild)     NOBUILD=1 ;;
                -p)               shift; BUILDFILE=$1 ;;
+               --skippgpcheck)   NOPGPSIGS=1;;
                --pkg)            shift; PKGLIST=($1) ;;
                -r|--rmdeps)      RMDEPS=1 ;;
                -R|--repackage)   REPKG=1 ;;
@@ -2122,6 +2190,7 @@ if (( SOURCEONLY )); then
        if (( ! SKIPINTEG )); then
                # We can only check checksums if we have all files.
                check_checksums
+               check_pgpsigs
        else
                warning "$(gettext "Skipping integrity checks.")"
        fi

See my comment above about splitting the handling --skipinteg and --skippgpcheck up.

@@ -2200,6 +2269,7 @@ else
        download_sources
        if (( ! SKIPINTEG )); then
                check_checksums
+               check_pgpsigs
        else
                warning "$(gettext "Skipping integrity checks.")"
        fi


OK... that does seem a lot of comments, but they should be all quite quick to deal with. I think this version of the patch is exactly how I want this whole thing to be implemented, so we should be good to go after those changes.

Allan

Reply via email to