summaryrefslogtreecommitdiff
path: root/mktag.c
diff options
context:
space:
mode:
Diffstat (limited to 'mktag.c')
-rw-r--r--mktag.c133
1 files changed, 0 insertions, 133 deletions
diff --git a/mktag.c b/mktag.c
deleted file mode 100644
index fc6a9bf5f3..0000000000
--- a/mktag.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include "cache.h"
-
-/*
- * A signature file has a very simple fixed format: three lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>",
- * followed by some free-form signature that git itself doesn't
- * care about, but that can be verified with gpg or similar.
- *
- * The first three lines are guaranteed to be at least 63 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
- * shortest possible type-line, and "tag .\n" at 6 bytes is the
- * shortest single-character-tag line.
- *
- * We also artificially limit the size of the full object to 8kB.
- * Just because I'm a lazy bastard, and if you can't fit a signature
- * in that size, you're doing something wrong.
- */
-
-// Some random size
-#define MAXSIZE (8192)
-
-/*
- * We refuse to tag something we can't verify. Just because.
- */
-static int verify_object(unsigned char *sha1, const char *expected_type)
-{
- int ret = -1;
- char type[100];
- unsigned long size;
- void *buffer = read_sha1_file(sha1, type, &size);
-
- if (buffer) {
- if (!strcmp(type, expected_type))
- ret = check_sha1_signature(sha1, buffer, size, type);
- free(buffer);
- }
- return ret;
-}
-
-static int verify_tag(char *buffer, unsigned long size)
-{
- int typelen;
- char type[20];
- unsigned char sha1[20];
- const char *object, *type_line, *tag_line, *tagger_line;
-
- if (size < 64 || size > MAXSIZE-1)
- return -1;
- buffer[size] = 0;
-
- /* Verify object line */
- object = buffer;
- if (memcmp(object, "object ", 7))
- return -1;
- if (get_sha1_hex(object + 7, sha1))
- return -1;
-
- /* Verify type line */
- type_line = object + 48;
- if (memcmp(type_line - 1, "\ntype ", 6))
- return -1;
-
- /* Verify tag-line */
- tag_line = strchr(type_line, '\n');
- if (!tag_line)
- return -1;
- tag_line++;
- if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
- return -1;
-
- /* Get the actual type */
- typelen = tag_line - type_line - strlen("type \n");
- if (typelen >= sizeof(type))
- return -1;
- memcpy(type, type_line+5, typelen);
- type[typelen] = 0;
-
- /* Verify that the object matches */
- if (get_sha1_hex(object + 7, sha1))
- return -1;
- if (verify_object(sha1, type))
- return -1;
-
- /* Verify the tag-name: we don't allow control characters or spaces in it */
- tag_line += 4;
- for (;;) {
- unsigned char c = *tag_line++;
- if (c == '\n')
- break;
- if (c > ' ')
- continue;
- return -1;
- }
-
- /* Verify the tagger line */
- tagger_line = tag_line;
-
- if (memcmp(tagger_line, "tagger", 6) || (tagger_line[6] == '\n'))
- return -1;
-
- /* The actual stuff afterwards we don't care about.. */
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- unsigned long size;
- char buffer[MAXSIZE];
- unsigned char result_sha1[20];
-
- if (argc != 1)
- usage("cat <signaturefile> | git-mktag");
-
- setup_git_directory();
-
- // Read the signature
- size = 0;
- for (;;) {
- int ret = xread(0, buffer + size, MAXSIZE - size);
- if (ret <= 0)
- break;
- size += ret;
- }
-
- // Verify it for some basic sanity: it needs to start with "object <sha1>\ntype\ntagger "
- if (verify_tag(buffer, size) < 0)
- die("invalid tag signature file");
-
- if (write_sha1_file(buffer, size, "tag", result_sha1) < 0)
- die("unable to write tag file");
- printf("%s\n", sha1_to_hex(result_sha1));
- return 0;
-}