Only use `git verify-tag` when verifying annotated tags (#26414)

* Only use `git verify-tag` when verifying annotated tags

The command `git verify-tag` only applies to annotated tags. When
verifying lightweight tags, which are more similar to non-moving
branches, one has to use `git verify-commit` instead.

Using ':' as a separator is appropriate since that is one of the
characters not allowed in a Git reference name.

See also https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html

* Improve testing of the Git module's gpg verification
pull/26842/head
Andreas Olsson 7 years ago committed by jctanner
parent 779d05aec4
commit 593297d7a2

@ -590,15 +590,17 @@ def get_branches(git_path, module, dest):
return branches return branches
def get_tags(git_path, module, dest): def get_annotated_tags(git_path, module, dest):
tags = [] tags = []
cmd = '%s tag' % (git_path,) cmd = [git_path, 'for-each-ref', 'refs/tags/', '--format', '%(objecttype):%(refname:short)']
(rc, out, err) = module.run_command(cmd, cwd=dest) (rc, out, err) = module.run_command(cmd, cwd=dest)
if rc != 0: if rc != 0:
module.fail_json(msg="Could not determine tag data - received %s" % out, stdout=out, stderr=err) module.fail_json(msg="Could not determine tag data - received %s" % out, stdout=out, stderr=err)
for line in to_native(out).split('\n'): for line in to_native(out).split('\n'):
if line.strip(): if line.strip():
tags.append(line.strip()) tagtype, tagname = line.strip().split(':')
if tagtype == 'tag':
tags.append(tagname)
return tags return tags
@ -887,7 +889,7 @@ def switch_version(git_path, module, dest, remote, version, verify_commit, depth
def verify_commit_sign(git_path, module, dest, version): def verify_commit_sign(git_path, module, dest, version):
if version in get_tags(git_path, module, dest): if version in get_annotated_tags(git_path, module, dest):
git_sub = "verify-tag" git_sub = "verify-tag"
else: else:
git_sub = "verify-commit" git_sub = "verify-commit"

@ -0,0 +1,187 @@
---
# Test for verification of GnuPG signatures
- name: Create GnuPG verification workdir
tempfile:
state: directory
register: git_gpg_workdir
- name: Define variables based on workdir
set_fact:
git_gpg_keyfile: "{{ git_gpg_workdir.path }}/testkey.asc"
git_gpg_source: "{{ git_gpg_workdir.path }}/source"
git_gpg_dest: "{{ git_gpg_workdir.path }}/dest"
git_gpg_gpghome: "{{ git_gpg_workdir.path }}/gpg"
- name: Temporary store GnuPG test key
copy:
content: "{{ git_gpg_testkey }}"
dest: "{{ git_gpg_keyfile }}"
- name: Create temporary GNUPGHOME directory
file:
path: "{{ git_gpg_gpghome }}"
state: directory
mode: 0700
- name: Import GnuPG test key
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
command: gpg --import {{ git_gpg_keyfile }}
- name: Create local GnuPG signed repository directory
file:
path: "{{ git_gpg_source }}"
state: directory
- name: Generate local GnuPG signed repository
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
shell: |
set -e
git init
touch an_empty_file
git add an_empty_file
git commit --no-gpg-sign --message "Commit, and don't sign"
git tag lightweight_tag/unsigned_commit HEAD
git commit --allow-empty --gpg-sign --message "Commit, and sign"
git tag lightweight_tag/signed_commit HEAD
git tag --annotate --message "This is not a signed tag" unsigned_annotated_tag HEAD
git commit --allow-empty --gpg-sign --message "Commit, and sign"
git tag --sign --message "This is a signed tag" signed_annotated_tag HEAD
git checkout -b some_branch/signed_tip master
git commit --allow-empty --gpg-sign --message "Commit, and sign"
git checkout -b another_branch/unsigned_tip master
git commit --allow-empty --no-gpg-sign --message "Commit, and don't sign"
git checkout master
args:
chdir: "{{ git_gpg_source }}"
- name: Get hash of an unsigned commit
command: git show-ref --hash --verify refs/tags/lightweight_tag/unsigned_commit
args:
chdir: "{{ git_gpg_source }}"
register: git_gpg_unsigned_commit
- name: Get hash of a signed commit
command: git show-ref --hash --verify refs/tags/lightweight_tag/signed_commit
args:
chdir: "{{ git_gpg_source }}"
register: git_gpg_signed_commit
- name: Clone repo and verify signed HEAD
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
verify_commit: yes
- name: Clone repo and verify a signed lightweight tag
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: lightweight_tag/signed_commit
verify_commit: yes
- name: Clone repo and verify an unsigned lightweight tag (should fail)
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: lightweight_tag/unsigned_commit
verify_commit: yes
register: git_verify
ignore_errors: yes
- name: Check that unsigned lightweight tag verification failed
assert:
that:
- git_verify|failed
- git_verify.msg|match("Failed to verify GPG signature of commit/tag.+")
- name: Clone repo and verify a signed commit
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: "{{ git_gpg_signed_commit.stdout }}"
verify_commit: yes
- name: Clone repo and verify an unsigned commit
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: "{{ git_gpg_unsigned_commit.stdout }}"
verify_commit: yes
register: git_verify
ignore_errors: yes
- name: Check that unsigned commit verification failed
assert:
that:
- git_verify|failed
- git_verify.msg|match("Failed to verify GPG signature of commit/tag.+")
- name: Clone repo and verify a signed annotated tag
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: signed_annotated_tag
verify_commit: yes
- name: Clone repo and verify an unsigned annotated tag (should fail)
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: unsigned_annotated_tag
verify_commit: yes
register: git_verify
ignore_errors: yes
- name: Check that unsigned annotated tag verification failed
assert:
that:
- git_verify|failed
- git_verify.msg|match("Failed to verify GPG signature of commit/tag.+")
- name: Clone repo and verify a signed branch
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: some_branch/signed_tip
verify_commit: yes
- name: Clone repo and verify an unsigned branch (should fail)
environment:
- GNUPGHOME: "{{ git_gpg_gpghome }}"
git:
repo: "{{ git_gpg_source }}"
dest: "{{ git_gpg_dest }}"
version: another_branch/unsigned_tip
verify_commit: yes
register: git_verify
ignore_errors: yes
- name: Check that unsigned branch verification failed
assert:
that:
- git_verify|failed
- git_verify.msg|match("Failed to verify GPG signature of commit/tag.+")
- name: Remove GnuPG verification workdir
file:
path: "{{ git_gpg_workdir.path }}"
state: absent

@ -27,7 +27,11 @@
- include: change-repo-url.yml - include: change-repo-url.yml
- include: depth.yml - include: depth.yml
- include: checkout-new-tag.yml - include: checkout-new-tag.yml
- include: tag-verification.yml - include: gpg-verification.yml
when: >
not gpg_version.stderr and
gpg_version.stdout and
git_version.stdout | version_compare("2.1.0", '>=')
- include: localmods.yml - include: localmods.yml
- include: reset-origin.yml - include: reset-origin.yml
- include: ambiguous-ref.yml - include: ambiguous-ref.yml

@ -1,57 +0,0 @@
---
# Test for tag verification
# clone a repo checkout signed tag, verify tag
- name: Import Jamie Evans GPG key
command: gpg --keyserver keyserver.ubuntu.com --recv-key 61107C8E
when: >
not gpg_version.stderr and
gpg_version.stdout and
(git_version.stdout | version_compare("2.1.0", '>=') or
gpg_version.stdout | version_compare("1.4.16", '>='))
- name: Copy ownertrust
copy: "content='2D55902D66FEEBCEA4447C93E79A36DA61107C8E:6:\n' dest=/tmp/ownertrust-git.txt"
when: >
not gpg_version.stderr and
gpg_version.stdout and
(git_version.stdout | version_compare("2.1.0", '>=') or
gpg_version.stdout | version_compare("1.4.16", '>='))
- name: Import ownertrust
command: gpg --import-ownertrust /tmp/ownertrust-git.txt
when: >
not gpg_version.stderr and
gpg_version.stdout and
(git_version.stdout | version_compare("2.1.0", '>=') or
gpg_version.stdout | version_compare("1.4.16", '>='))
- name: Clone signed repo and verify tag
git: repo={{ repo_verify }} dest={{ checkout_dir }} version=v0.0 verify_commit=yes
when: >
not gpg_version.stderr and
gpg_version.stdout and
(git_version.stdout | version_compare("2.1.0", '>=') or
gpg_version.stdout | version_compare("1.4.16", '>='))
- name: Remove Jamie Evans GPG key
command: gpg --batch --yes --delete-key 61107C8E
when: >
not gpg_version.stderr and
gpg_version.stdout and
(git_version.stdout | version_compare("2.1.0", '>=') or
gpg_version.stdout | version_compare("1.4.16", '>='))
- name: Clean up files
file: path="{{ item }}" state=absent
with_items:
- "{{ checkout_dir }}"
- /tmp/ownertrust-git.txt
when: >
not gpg_version.stderr and
gpg_version.stdout and
(git_version.stdout | version_compare("2.1.0", '>=') or
gpg_version.stdout | version_compare("1.4.16", '>='))
- name: clear checkout_dir
file: state=absent path={{ checkout_dir }}

@ -12,7 +12,6 @@ repo_submodule1_newer: 'https://github.com/abadger/test_submodules_subm1_newer.g
repo_submodule2: 'https://github.com/abadger/test_submodules_subm2.git' repo_submodule2: 'https://github.com/abadger/test_submodules_subm2.git'
repo_update_url_1: 'https://github.com/ansible-test-robinro/git-test-old' repo_update_url_1: 'https://github.com/ansible-test-robinro/git-test-old'
repo_update_url_2: 'https://github.com/ansible-test-robinro/git-test-new' repo_update_url_2: 'https://github.com/ansible-test-robinro/git-test-new'
repo_verify: 'https://github.com/pixelrebel/ansible-git-test.git'
known_host_files: known_host_files:
- "{{ lookup('env','HOME') }}/.ssh/known_hosts" - "{{ lookup('env','HOME') }}/.ssh/known_hosts"
- '/etc/ssh/ssh_known_hosts' - '/etc/ssh/ssh_known_hosts'
@ -20,3 +19,53 @@ git_version_supporting_depth: 1.9.1
git_version_supporting_ls_remote: 1.7.5 git_version_supporting_ls_remote: 1.7.5
# path to a SSH private key for use with github.com (tests skipped if undefined) # path to a SSH private key for use with github.com (tests skipped if undefined)
# github_ssh_private_key: "{{ lookup('env', 'HOME') }}/.ssh/id_rsa" # github_ssh_private_key: "{{ lookup('env', 'HOME') }}/.ssh/id_rsa"
git_gpg_testkey: |
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQOYBFlkmX0BCACtE81Xj/351nnvwnAWMf8ZUP9B1YOPe9ohqNsCQY1DxODVJc9y
ljCoh9fTdoHXuaUMUFistozxCMP81RuZxfbfsGePnl8OAOgWT5Sln6yEG45oClJ0
RmJJZdDT1lF3VaVwK9NQ5E1oqmk1IOjISi7iFa9TmMn1h7ISP/p+/xtMxQhzUXt8
APAEhRdc9FfwxaxCHKZBiM7ND+pAm6vpom07ZUgxSppsrXZAxDncTwAeCumDpeOL
LAcSBsw02swOIHFfqHNrkELLr4KJqws+zeAk6R2nq0k16AVdNX+Rb7T3OKmuLawx
HXe8rKpaw0RC+JCogZK4tz0KDNuZPLW2Y5JJABEBAAEAB/4zkKpFk79p35YNskLd
wgCMRN7/+MKNDavUCnBRsEELt0z7BBxVudx+YZaSSITvxj4fuJJqxqqgJ2no2n8y
JdJjG7YHCnqse+WpvAUAAV4PL/ySD704Kj4fOwfoDTrRUIGNNWlseNB9RgQ5UXg5
MCzeq/JD+En3bnnFySzzCENUcAQfu2FVYgKEiKaKL5Djs6p5w/jTm+Let3EsIczb
ykJ8D4/G/tSrNdp/g10DDy+VclWMhMFqmFesedvytE8jzCVxPKOoRkFTGrX76gIK
eMVxHIYxdCfSTHLjBykMGO9gxfk9lf18roNYs0VV2suyi4fVFxEozSAxwWlwKrXn
0arvBADPsm5NjlZ5uR06YKbpUUwPTYcwLbasic0qHuUWgNsTVv8dd2il/jbha77m
StU7qRJ1jwbFEFxx7HnTmeGfPbdyKe2qyLJUyD/rpQSC5YirisUchtG8nZsHlnzn
k10SIeB480tkgkdMQx1Eif40aiuQb09/TxaaXAEFKttZhEO4RwQA1VQ8a0IrMBI2
i4WqaIDNDl3x61JvvFD74v43I0AHKmZUPwcgAd6q2IvCDaKH0hIuBKu6BGq6DPvx
Oc/4r3iRn/xccconxRop2A9ffa00B/eQXrBq+uLBQfyiFL9UfkU8eTAAgbDKRxjY
ScaevoBbbYxkpgJUCL6VnoSdXlbNOO8EAL2ypsVkDmXNgR8ZT8cKSUft47di5T+9
mhT1qmD62B+D86892y2QAohmUDadYRK9m9WD91Y7gOMeNhYj9qbxyPprPYUL0aPt
L8KS1H73C5WQMOsl2RyIw81asss30LWghsFIJ1gz8gVEjXhV+YC6W9XQ42iabmRR
A67f5sqK1scuO0q0KUFuc2libGUgVGVzdCBSdW5uZXIgPG5vcmVwbHlAZXhhbXBs
ZS5jb20+iQE3BBMBCAAhBQJZZJl9AhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheA
AAoJEK0vcLBcXpbYi/kH/R0xk42MFpGd4pndTAsVIjRk/VhmhFc1v6sBeR40GXlt
hyEeOQQnIeHKLhsVT6YnfFZa8b4JwgTD6NeIiibOAlLgaKOWNwZu8toixMPVAzfQ
cRei+/gFXNil0FmBwWreVBDppuIn6XiSEPik0C7eCcw4lD+A+BbL3WGkp+OSQPho
hodIU02hgkrgs/6YJPats8Rgzw9hICsa2j0MjnG6P2z9atMz6tw2SiE5iBl7mZ2Z
zG/HiplleMhf/G8OZOskrWkKiLbpSPfQSKdOFkw1C6yqOlQ+HmuCZ56oyxtpItET
R11uAKt+ABdi4DX3FQQ+A+bGJ1+aKrcorZ8Z8s0XhPo=
=tV71
-----END PGP PRIVATE KEY BLOCK-----
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFlkmX0BCACtE81Xj/351nnvwnAWMf8ZUP9B1YOPe9ohqNsCQY1DxODVJc9y
ljCoh9fTdoHXuaUMUFistozxCMP81RuZxfbfsGePnl8OAOgWT5Sln6yEG45oClJ0
RmJJZdDT1lF3VaVwK9NQ5E1oqmk1IOjISi7iFa9TmMn1h7ISP/p+/xtMxQhzUXt8
APAEhRdc9FfwxaxCHKZBiM7ND+pAm6vpom07ZUgxSppsrXZAxDncTwAeCumDpeOL
LAcSBsw02swOIHFfqHNrkELLr4KJqws+zeAk6R2nq0k16AVdNX+Rb7T3OKmuLawx
HXe8rKpaw0RC+JCogZK4tz0KDNuZPLW2Y5JJABEBAAG0KUFuc2libGUgVGVzdCBS
dW5uZXIgPG5vcmVwbHlAZXhhbXBsZS5jb20+iQE3BBMBCAAhBQJZZJl9AhsDBQsJ
CAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEK0vcLBcXpbYi/kH/R0xk42MFpGd4pnd
TAsVIjRk/VhmhFc1v6sBeR40GXlthyEeOQQnIeHKLhsVT6YnfFZa8b4JwgTD6NeI
iibOAlLgaKOWNwZu8toixMPVAzfQcRei+/gFXNil0FmBwWreVBDppuIn6XiSEPik
0C7eCcw4lD+A+BbL3WGkp+OSQPhohodIU02hgkrgs/6YJPats8Rgzw9hICsa2j0M
jnG6P2z9atMz6tw2SiE5iBl7mZ2ZzG/HiplleMhf/G8OZOskrWkKiLbpSPfQSKdO
Fkw1C6yqOlQ+HmuCZ56oyxtpItETR11uAKt+ABdi4DX3FQQ+A+bGJ1+aKrcorZ8Z
8s0XhPo=
=mUYY
-----END PGP PUBLIC KEY BLOCK-----

Loading…
Cancel
Save