[pacman-dev] [PATCH v3 1/2] makepkg: Add support for verifying pgp signatures

Dan McGee dpmcgee at gmail.com
Mon Jul 18 21:59:59 EDT 2011


On Wed, Jul 6, 2011 at 6:02 AM, Wieland Hoffmann
<themineo at googlemail.com> 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.
> ---

This is really lacking some documentation, unless I missed something?

We need to mention in man PKGBUILD the special treatment of .sig or
.asc entries (which I think is how this works?)

Additionally, this has a rather silly requirement IMO of adding and
needing checksums of signature files to the checksums arrays. Do we
really want this?

>  doc/makepkg.8.txt     |    3 ++
>  scripts/makepkg.sh.in |   92 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 94 insertions(+), 1 deletions(-)
>
> diff --git a/doc/makepkg.8.txt b/doc/makepkg.8.txt
> index e11e9b3..bc1ffc1 100644
> --- a/doc/makepkg.8.txt
> +++ b/doc/makepkg.8.txt
> @@ -87,6 +87,9 @@ Options
>  *--skipinteg*::
>        Do not perform any integrity checks, just print a warning instead.
>
> +*\--skippgpcheck*::
> +       Do not verify PGP signatures of the source files.
> +
>  *-h, \--help*::
>        Output syntax and command line options.
>
> diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
> index 1b132a9..20ba431 100644
> --- a/scripts/makepkg.sh.in
> +++ b/scripts/makepkg.sh.in
> @@ -57,6 +57,7 @@ FORCE=0
>  INFAKEROOT=0
>  GENINTEG=0
>  SKIPINTEG=0
> +SKIPPGPCHECK=0
>  INSTALL=0
>  NOBUILD=0
>  NODEPS=0
> @@ -327,6 +328,15 @@ in_array() {
>        return 1 # Not Found
>  }
>
> +source_has_signatures(){
> +       for file in "${source[@]}"; do
> +               if [[ $file =~ .*(sig|asc) ]]; then
> +                       return 0
> +               fi
> +       done
> +       return 1
> +}
> +
>  get_downloadclient() {
>        # $1 = URL with valid protocol prefix
>        local url=$1
> @@ -674,6 +684,74 @@ check_checksums() {
>        fi
>  }
>
> +check_pgpsigs() {
> +       (( SKIPPGPCHECK )) && return 0
> +       (( ! ${#source[@]} )) && return 0
> +       [[ ! source_has_signatures ]] && return 0
> +
> +       msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
> +
> +       local file
> +       local warning=0
> +       local errors=0
> +       local statusfile=$(mktemp)
> +
> +       for file in "${source[@]}"; do
> +               file="$(get_filename "$file")"
> +               if [[ ! $file =~ .*(sig|asc) ]]; then
> +                       continue
> +               fi
> +
> +               echo -n "    ${file%.*} ... " >&2
> +
> +               if ! file="$(get_filepath "$file")"; then
> +                       echo "$(gettext "SIGNATURE NOT FOUND")" >&2
> +                       errors=1
> +                       continue
> +               fi
> +
> +               if ! sourcefile="$(get_filepath "${file%.*}")"; then
> +                       echo "$(gettext "SOURCE FILE NOT FOUND")" >&2
> +                       errors=1
> +                       continue
> +               fi
> +
> +               if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" "$sourcefile" 2> /dev/null; then
> +                       if grep "NO_PUBKEY" "$statusfile" > /dev/null; then
> +                               echo "$(gettext "Warning: Unknown public key") $(awk '/NO_PUBKEY/ {print $3}' $statusfile)" >&2
> +                               warnings=1
> +                       else
> +                               echo "$(gettext "FAILED")" >&2
> +                               errors=1
> +                       fi
> +               else
> +                       if grep "REVKEYSIG" "$statusfile" > /dev/null; then
> +                               errors=1
> +                               echo "$(gettext "Passed")" "-" "$(gettext "Warning: the key has been revoked.")" >&2
> +                       elif grep "EXPSIG" "$statusfile" > /dev/null; then
> +                               warnings=1
> +                               echo "$(gettext "Passed")" "-" "$(gettext "Warning: the signature has expired.")" >&2
> +                       elif grep "EXPKEYSIG" "$statusfile" > /dev/null; then
> +                               warnings=1
> +                               echo "$(gettext "Passed")" "-" "$(gettext  "Warning: the key has expired.")" >&2
> +                       else
> +                               echo $(gettext "Passed") >&2
> +                       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 "$(gettext "Warnings have occurred while verifying the signatures. Please make sure you really trust them.")"
> +       fi
> +}
> +
>  extract_sources() {
>        msg "$(gettext "Extracting Sources...")"
>        local netfile
> @@ -1478,6 +1556,14 @@ check_software() {
>                fi
>        fi
>
> +       # gpg - source verification
> +       if (( ! SKIPPGPCHECK )) && [[ source_has_signatures ]]; then
> +               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
> @@ -1715,6 +1801,7 @@ usage() {
>        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")"
> +       echo "$(gettext "  --skippgpcheck   Do not verify source files with pgp signatures")"
>        echo "$(gettext "  --source         Generate a source-only tarball without downloaded sources")"
>        echo
>        printf "$(gettext "These options can be passed to %s:")\n" "pacman"
> @@ -1749,7 +1836,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 +1878,7 @@ while true; do
>                --nosign)         SIGNPKG='n' ;;
>                -o|--nobuild)     NOBUILD=1 ;;
>                -p)               shift; BUILDFILE=$1 ;;
> +               --skippgpcheck)   SKIPPGPCHECK=1;;
>                --pkg)            shift; PKGLIST=($1) ;;
>                -r|--rmdeps)      RMDEPS=1 ;;
>                -R|--repackage)   REPKG=1 ;;
> @@ -2122,6 +2210,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
> @@ -2200,6 +2289,7 @@ else
>        download_sources
>        if (( ! SKIPINTEG )); then
>                check_checksums
> +               check_pgpsigs
>        else
>                warning "$(gettext "Skipping integrity checks.")"
>        fi
> --
> 1.7.6
>
>
>


More information about the pacman-dev mailing list