A git repository is marked as signed if it contains the query "signed"
as defined by https://tools.ietf.org/html/rfc3986

Adds two utility functions in util/source.sh.in to extract fragments and
queries, and modifies source/git.sh.in to use them.

Signed-off-by: Eli Schwartz <[email protected]>
---

Stupid copy-paste-of-the-previous-line typo.

In get_filename() it would be much much much more helpful if I didn't
*reset* the filename back to "${netfile%%\?*}".

That's all for now...

 .../libmakepkg/integrity/verify_signature.sh.in    | 56 ++++++++++++++++++----
 scripts/libmakepkg/source/git.sh.in                | 11 ++---
 scripts/libmakepkg/util/source.sh.in               | 27 +++++++++++
 3 files changed, 76 insertions(+), 18 deletions(-)

diff --git a/scripts/libmakepkg/integrity/verify_signature.sh.in 
b/scripts/libmakepkg/integrity/verify_signature.sh.in
index 6df62727..634958f9 100644
--- a/scripts/libmakepkg/integrity/verify_signature.sh.in
+++ b/scripts/libmakepkg/integrity/verify_signature.sh.in
@@ -32,11 +32,12 @@ check_pgpsigs() {
 
        msg "$(gettext "Verifying source file signatures with %s...")" "gpg"
 
-       local file ext decompress found pubkey success status fingerprint 
trusted
+       local netfile file ext decompress found pubkey success status 
fingerprint trusted
        local warning=0
        local errors=0
        local statusfile=$(mktemp)
        local all_sources
+       local proto dir fragment query fragtype fragval
 
        case $1 in
                all)
@@ -46,15 +47,38 @@ check_pgpsigs() {
                        get_all_sources_for_arch 'all_sources'
                        ;;
        esac
-       for file in "${all_sources[@]}"; do
-               file="$(get_filename "$file")"
-               if [[ $file != *.@(sig?(n)|asc) ]]; then
+       for netfile in "${all_sources[@]}"; do
+               file="$(get_filename "$netfile")"
+               proto="$(get_protocol "$netfile")"
+               dir=$(get_filepath "$netfile")
+               fragment=$(get_uri_fragment "$netfile")
+               query=$(get_uri_query "$netfile")
+
+               if [[ $proto = git* && $query = signed ]]; then
+                       case ${fragment%%=*} in
+                               tag)
+                                       fragtype=tag
+                                       fragval=${fragment##*=}
+                                       ;;
+                               commit|branch)
+                                       fragtype=commit
+                                       fragval=${fragment##*=}
+                                       ;;
+                               '')
+                                       fragtype=commit
+                                       fragval=HEAD
+                       esac
+               elif [[ $file != *.@(sig?(n)|asc) ]]; then
                        continue
                fi
 
-               printf "    %s ... " "${file%.*}" >&2
+               if [[ $proto = git* ]]; then
+                       printf "    %s git repo ... " "${file%.*}" >&2
+               else
+                       printf "    %s ... " "${file%.*}" >&2
+               fi
 
-               if ! file="$(get_filepath "$file")"; then
+               if ! file="$(get_filepath "$netfile")"; then
                        printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
                        errors=1
                        continue
@@ -67,7 +91,7 @@ check_pgpsigs() {
                                break;
                        fi
                done
-               if (( ! found )); then
+               if [[ $proto != git* ]] && (( ! found )); then
                        printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2
                        errors=1
                        continue
@@ -83,7 +107,16 @@ check_pgpsigs() {
                        "")  decompress="cat" ;;
                esac
 
-               $decompress < "$sourcefile" | gpg --quiet --batch --status-file 
"$statusfile" --verify "$file" - 2> /dev/null
+               if [[ $proto = git* ]]; then
+                       git -C "$dir" verify-$fragtype --raw "$fragval" > 
"$statusfile" 2>&1
+                       if ! grep -qs NEWSIG "$statusfile"; then
+                               printf '%s\n' "$(gettext "SIGNATURE NOT 
FOUND")" >&2
+                               errors=1
+                               continue
+                       fi
+               else
+                       $decompress < "$sourcefile" | gpg --quiet --batch 
--status-file "$statusfile" --verify "$file" - 2> /dev/null
+               fi
                # these variables are assigned values in parse_gpg_statusfile
                success=0
                status=
@@ -204,11 +237,14 @@ parse_gpg_statusfile() {
 }
 
 source_has_signatures() {
-       local file all_sources
+       local file all_sources proto
 
        get_all_sources_for_arch 'all_sources'
        for file in "${all_sources[@]}"; do
-               if [[ ${file%%::*} = *.@(sig?(n)|asc) ]]; then
+               proto="$(get_protocol "$file")"
+               query=$(get_uri_query "$netfile")
+
+               if [[ ${file%%::*} = *.@(sig?(n)|asc) || ( $proto = git* && 
$query = signed ) ]]; then
                        return 0
                fi
        done
diff --git a/scripts/libmakepkg/source/git.sh.in 
b/scripts/libmakepkg/source/git.sh.in
index cc27663d..3d370dbd 100644
--- a/scripts/libmakepkg/source/git.sh.in
+++ b/scripts/libmakepkg/source/git.sh.in
@@ -39,6 +39,7 @@ download_git() {
        local url=$(get_url "$netfile")
        url=${url#git+}
        url=${url%%#*}
+       url=${url%%\?*}
 
        if [[ ! -d "$dir" ]] || dir_is_empty "$dir" ; then
                msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "git"
@@ -66,14 +67,8 @@ download_git() {
 extract_git() {
        local netfile=$1
 
-       local fragment=${netfile#*#}
-       if [[ $fragment = "$netfile" ]]; then
-               unset fragment
-       fi
-
-       local repo=${netfile##*/}
-       repo=${repo%%#*}
-       repo=${repo%%.git*}
+       local fragment=$(get_uri_fragment "$netfile")
+       local repo=$(get_filename "$netfile")
 
        local dir=$(get_filepath "$netfile")
        [[ -z "$dir" ]] && dir="$SRCDEST/$(get_filename "$netfile")"
diff --git a/scripts/libmakepkg/util/source.sh.in 
b/scripts/libmakepkg/util/source.sh.in
index 9d4ba4a6..485ebe3a 100644
--- a/scripts/libmakepkg/util/source.sh.in
+++ b/scripts/libmakepkg/util/source.sh.in
@@ -65,6 +65,7 @@ get_filename() {
        case $proto in
                bzr*|git*|hg*|svn*)
                        filename=${netfile%%#*}
+                       filename=${filename%%\?*}
                        filename=${filename%/}
                        filename=${filename##*/}
                        if [[ $proto = bzr* ]]; then
@@ -111,6 +112,32 @@ get_filepath() {
        printf "%s\n" "$file"
 }
 
+# extract the VCS revision/branch specifier from a source entry
+get_uri_fragment() {
+       local netfile=$1
+
+       local fragment=${netfile#*#}
+       if [[ $fragment = "$netfile" ]]; then
+               unset fragment
+       fi
+       fragment=${fragment%\?*}
+
+       printf "%s\n" "$fragment"
+}
+
+# extract the "signed" status of a source entry - defined as a trailing URI 
data component
+get_uri_query() {
+       local netfile=$1
+
+       local query=${netfile#*\?}
+       if [[ $query = "$netfile" ]]; then
+               unset query
+       fi
+       query=${query%#*}
+
+       printf "%s\n" "$query"
+}
+
 get_downloadclient() {
        local proto=$1
 
-- 
2.11.0

Reply via email to