Skip to content

Commit 2ae68fc

Browse files
jasamplergitster
authored andcommitted
Make verify-tag a builtin.
This replaces "git-verify-tag.sh" with "builtin-verify-tag.c". Testing relies on the "git tag -v" tests calling this command. A temporary file is needed when calling to gpg, because git is already creating detached signatures (gpg option -b) to sign tags (instead of leaving gpg to add the signature to the file by itself), and those signatures need to be supplied in a separate file to be verified by gpg. The program uses git_mkstemp to create that temporary file needed by gpg, instead of the previously used "$GIT_DIR/.tmp-vtag", in order to allow the command to be used in read-only repositories, and also prevent other instances of git to read or remove the same file. Signal SIGPIPE is ignored because the program sometimes was terminated because that signal when writing the input for gpg. The command now can receive many tag names to be verified. Documentation is also updated here to reflect this new behaviour. Signed-off-by: Carlos Rica <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e317cfa commit 2ae68fc

File tree

6 files changed

+115
-3
lines changed

6 files changed

+115
-3
lines changed

Documentation/git-verify-tag.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ git-verify-tag(1)
33

44
NAME
55
----
6-
git-verify-tag - Check the GPG signature of tag
6+
git-verify-tag - Check the GPG signature of tags
77

88
SYNOPSIS
99
--------
10-
'git-verify-tag' <tag>
10+
'git-verify-tag' <tag>...
1111

1212
DESCRIPTION
1313
-----------

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ SCRIPT_SH = \
206206
git-pull.sh git-rebase.sh git-rebase--interactive.sh \
207207
git-repack.sh git-request-pull.sh git-reset.sh \
208208
git-sh-setup.sh \
209-
git-verify-tag.sh \
210209
git-am.sh \
211210
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
212211
git-merge-resolve.sh git-merge-ours.sh \
@@ -368,6 +367,7 @@ BUILTIN_OBJS = \
368367
builtin-update-ref.o \
369368
builtin-upload-archive.o \
370369
builtin-verify-pack.o \
370+
builtin-verify-tag.o \
371371
builtin-write-tree.o \
372372
builtin-show-ref.o \
373373
builtin-pack-refs.o

builtin-verify-tag.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Builtin "git verify-tag"
3+
*
4+
* Copyright (c) 2007 Carlos Rica <[email protected]>
5+
*
6+
* Based on git-verify-tag.sh
7+
*/
8+
#include "cache.h"
9+
#include "builtin.h"
10+
#include "tag.h"
11+
#include "run-command.h"
12+
#include <signal.h>
13+
14+
static const char builtin_verify_tag_usage[] =
15+
"git-verify-tag [-v|--verbose] <tag>...";
16+
17+
#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
18+
19+
static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
20+
{
21+
struct child_process gpg;
22+
const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
23+
char path[PATH_MAX], *eol;
24+
size_t len;
25+
int fd, ret;
26+
27+
fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
28+
if (fd < 0)
29+
return error("could not create temporary file '%s': %s",
30+
path, strerror(errno));
31+
if (write_in_full(fd, buf, size) < 0)
32+
return error("failed writing temporary file '%s': %s",
33+
path, strerror(errno));
34+
close(fd);
35+
36+
/* find the length without signature */
37+
len = 0;
38+
while (len < size && prefixcmp(buf + len, PGP_SIGNATURE "\n")) {
39+
eol = memchr(buf + len, '\n', size - len);
40+
len += eol ? eol - (buf + len) + 1 : size - len;
41+
}
42+
if (verbose)
43+
write_in_full(1, buf, len);
44+
45+
memset(&gpg, 0, sizeof(gpg));
46+
gpg.argv = args_gpg;
47+
gpg.in = -1;
48+
gpg.out = 1;
49+
args_gpg[2] = path;
50+
if (start_command(&gpg))
51+
return error("could not run gpg.");
52+
53+
write_in_full(gpg.in, buf, len);
54+
close(gpg.in);
55+
gpg.close_in = 0;
56+
ret = finish_command(&gpg);
57+
58+
unlink(path);
59+
60+
return ret;
61+
}
62+
63+
static int verify_tag(const char *name, int verbose)
64+
{
65+
enum object_type type;
66+
unsigned char sha1[20];
67+
char *buf;
68+
unsigned long size;
69+
int ret;
70+
71+
if (get_sha1(name, sha1))
72+
return error("tag '%s' not found.", name);
73+
74+
type = sha1_object_info(sha1, NULL);
75+
if (type != OBJ_TAG)
76+
return error("%s: cannot verify a non-tag object of type %s.",
77+
name, typename(type));
78+
79+
buf = read_sha1_file(sha1, &type, &size);
80+
if (!buf)
81+
return error("%s: unable to read file.", name);
82+
83+
ret = run_gpg_verify(buf, size, verbose);
84+
85+
free(buf);
86+
return ret;
87+
}
88+
89+
int cmd_verify_tag(int argc, const char **argv, const char *prefix)
90+
{
91+
int i = 1, verbose = 0, had_error = 0;
92+
93+
git_config(git_default_config);
94+
95+
if (argc == 1)
96+
usage(builtin_verify_tag_usage);
97+
98+
if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) {
99+
verbose = 1;
100+
i++;
101+
}
102+
103+
/* sometimes the program was terminated because this signal
104+
* was received in the process of writing the gpg input: */
105+
signal(SIGPIPE, SIG_IGN);
106+
while (i < argc)
107+
if (verify_tag(argv[i++], verbose))
108+
had_error = 1;
109+
return had_error;
110+
}

builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ extern int cmd_update_index(int argc, const char **argv, const char *prefix);
7777
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
7878
extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
7979
extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
80+
extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);
8081
extern int cmd_version(int argc, const char **argv, const char *prefix);
8182
extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
8283
extern int cmd_write_tree(int argc, const char **argv, const char *prefix);
File renamed without changes.

git.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ static void handle_internal_command(int argc, const char **argv)
369369
{ "update-index", cmd_update_index, RUN_SETUP },
370370
{ "update-ref", cmd_update_ref, RUN_SETUP },
371371
{ "upload-archive", cmd_upload_archive },
372+
{ "verify-tag", cmd_verify_tag, RUN_SETUP },
372373
{ "version", cmd_version },
373374
{ "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER },
374375
{ "write-tree", cmd_write_tree, RUN_SETUP },

0 commit comments

Comments
 (0)