summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e317cfa)
raw | patch | inline | side by side (parent: e317cfa)
author | Carlos Rica <jasampler@gmail.com> | |
Fri, 27 Jul 2007 04:07:34 +0000 (06:07 +0200) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Fri, 27 Jul 2007 05:51:27 +0000 (22:51 -0700) |
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 <jasampler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <jasampler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-verify-tag.txt | patch | blob | history | |
Makefile | patch | blob | history | |
builtin-verify-tag.c | [new file with mode: 0644] | patch | blob |
builtin.h | patch | blob | history | |
contrib/examples/git-verify-tag.sh | [new file with mode: 0755] | patch | blob |
git-verify-tag.sh | [deleted file] | patch | blob | history |
git.c | patch | blob | history |
index 48d17fd9c44acc3192987d818f3505c56d2eddb4..ac7fb19154bf7744cce6ab189ae2a424fd06f74b 100644 (file)
NAME
----
-git-verify-tag - Check the GPG signature of tag
+git-verify-tag - Check the GPG signature of tags
SYNOPSIS
--------
-'git-verify-tag' <tag>
+'git-verify-tag' <tag>...
DESCRIPTION
-----------
diff --git a/Makefile b/Makefile
index 8db664624594ad2b5d029d551ff48d86b1d3e989..98670bbd716ba55aff15ae2b4f7afea61c04df7c 100644 (file)
--- a/Makefile
+++ b/Makefile
git-pull.sh git-rebase.sh git-rebase--interactive.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
git-sh-setup.sh \
- git-verify-tag.sh \
git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
git-merge-resolve.sh git-merge-ours.sh \
builtin-update-ref.o \
builtin-upload-archive.o \
builtin-verify-pack.o \
+ builtin-verify-tag.o \
builtin-write-tree.o \
builtin-show-ref.o \
builtin-pack-refs.o
diff --git a/builtin-verify-tag.c b/builtin-verify-tag.c
--- /dev/null
+++ b/builtin-verify-tag.c
@@ -0,0 +1,110 @@
+/*
+ * Builtin "git verify-tag"
+ *
+ * Copyright (c) 2007 Carlos Rica <jasampler@gmail.com>
+ *
+ * Based on git-verify-tag.sh
+ */
+#include "cache.h"
+#include "builtin.h"
+#include "tag.h"
+#include "run-command.h"
+#include <signal.h>
+
+static const char builtin_verify_tag_usage[] =
+ "git-verify-tag [-v|--verbose] <tag>...";
+
+#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
+
+static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
+{
+ struct child_process gpg;
+ const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
+ char path[PATH_MAX], *eol;
+ size_t len;
+ int fd, ret;
+
+ fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
+ if (fd < 0)
+ return error("could not create temporary file '%s': %s",
+ path, strerror(errno));
+ if (write_in_full(fd, buf, size) < 0)
+ return error("failed writing temporary file '%s': %s",
+ path, strerror(errno));
+ close(fd);
+
+ /* find the length without signature */
+ len = 0;
+ while (len < size && prefixcmp(buf + len, PGP_SIGNATURE "\n")) {
+ eol = memchr(buf + len, '\n', size - len);
+ len += eol ? eol - (buf + len) + 1 : size - len;
+ }
+ if (verbose)
+ write_in_full(1, buf, len);
+
+ memset(&gpg, 0, sizeof(gpg));
+ gpg.argv = args_gpg;
+ gpg.in = -1;
+ gpg.out = 1;
+ args_gpg[2] = path;
+ if (start_command(&gpg))
+ return error("could not run gpg.");
+
+ write_in_full(gpg.in, buf, len);
+ close(gpg.in);
+ gpg.close_in = 0;
+ ret = finish_command(&gpg);
+
+ unlink(path);
+
+ return ret;
+}
+
+static int verify_tag(const char *name, int verbose)
+{
+ enum object_type type;
+ unsigned char sha1[20];
+ char *buf;
+ unsigned long size;
+ int ret;
+
+ if (get_sha1(name, sha1))
+ return error("tag '%s' not found.", name);
+
+ type = sha1_object_info(sha1, NULL);
+ if (type != OBJ_TAG)
+ return error("%s: cannot verify a non-tag object of type %s.",
+ name, typename(type));
+
+ buf = read_sha1_file(sha1, &type, &size);
+ if (!buf)
+ return error("%s: unable to read file.", name);
+
+ ret = run_gpg_verify(buf, size, verbose);
+
+ free(buf);
+ return ret;
+}
+
+int cmd_verify_tag(int argc, const char **argv, const char *prefix)
+{
+ int i = 1, verbose = 0, had_error = 0;
+
+ git_config(git_default_config);
+
+ if (argc == 1)
+ usage(builtin_verify_tag_usage);
+
+ if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) {
+ verbose = 1;
+ i++;
+ }
+
+ /* sometimes the program was terminated because this signal
+ * was received in the process of writing the gpg input: */
+ signal(SIGPIPE, SIG_IGN);
+ while (i < argc)
+ if (verify_tag(argv[i++], verbose))
+ had_error = 1;
+ return had_error;
+}
diff --git a/builtin.h b/builtin.h
index ac7417f7c55f2ee45ee9c2b669acf41357e85552..bb720004afeb632005a5622ecb9cd25f95f5caa5 100644 (file)
--- a/builtin.h
+++ b/builtin.h
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
+extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);
extern int cmd_version(int argc, const char **argv, const char *prefix);
extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
extern int cmd_write_tree(int argc, const char **argv, const char *prefix);
diff --git a/contrib/examples/git-verify-tag.sh b/contrib/examples/git-verify-tag.sh
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+USAGE='<tag>'
+SUBDIRECTORY_OK='Yes'
+. git-sh-setup
+
+verbose=
+while case $# in 0) break;; esac
+do
+ case "$1" in
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t ;;
+ *)
+ break ;;
+ esac
+ shift
+done
+
+if [ "$#" != "1" ]
+then
+ usage
+fi
+
+type="$(git cat-file -t "$1" 2>/dev/null)" ||
+ die "$1: no such object."
+
+test "$type" = tag ||
+ die "$1: cannot verify a non-tag object of type $type."
+
+case "$verbose" in
+t)
+ git cat-file -p "$1" |
+ sed -n -e '/^-----BEGIN PGP SIGNATURE-----/q' -e p
+ ;;
+esac
+
+trap 'rm -f "$GIT_DIR/.tmp-vtag"' 0
+
+git cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1
+sed -n -e '
+ /^-----BEGIN PGP SIGNATURE-----$/q
+ p
+' <"$GIT_DIR/.tmp-vtag" |
+gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1
+rm -f "$GIT_DIR/.tmp-vtag"
diff --git a/git-verify-tag.sh b/git-verify-tag.sh
--- a/git-verify-tag.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-
-USAGE='<tag>'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-verbose=
-while case $# in 0) break;; esac
-do
- case "$1" in
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t ;;
- *)
- break ;;
- esac
- shift
-done
-
-if [ "$#" != "1" ]
-then
- usage
-fi
-
-type="$(git cat-file -t "$1" 2>/dev/null)" ||
- die "$1: no such object."
-
-test "$type" = tag ||
- die "$1: cannot verify a non-tag object of type $type."
-
-case "$verbose" in
-t)
- git cat-file -p "$1" |
- sed -n -e '/^-----BEGIN PGP SIGNATURE-----/q' -e p
- ;;
-esac
-
-trap 'rm -f "$GIT_DIR/.tmp-vtag"' 0
-
-git cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1
-sed -n -e '
- /^-----BEGIN PGP SIGNATURE-----$/q
- p
-' <"$GIT_DIR/.tmp-vtag" |
-gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1
-rm -f "$GIT_DIR/.tmp-vtag"
index eb9e5ca97258ad04fee0b63d01151cee1845cb7e..230e50611f5946c416882734af5b1b838c3ef50c 100644 (file)
--- a/git.c
+++ b/git.c
{ "update-index", cmd_update_index, RUN_SETUP },
{ "update-ref", cmd_update_ref, RUN_SETUP },
{ "upload-archive", cmd_upload_archive },
+ { "verify-tag", cmd_verify_tag, RUN_SETUP },
{ "version", cmd_version },
{ "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER },
{ "write-tree", cmd_write_tree, RUN_SETUP },