From abb352de51bc964c06007fce43ed6f6caea87c15 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Mon, 4 Apr 2016 17:05:50 +0200 Subject: g10: Support armored keyrings in gpgv. * doc/gpgv.texi: Document the feature. * g10/Makefile.am (gpgv2_SOURCES): Add dearmor.c. * g10/dearmor.c (dearmor_file): Add sink argument. * g10/gpg.c (main): Adapt accordingly. * g10/gpgv.c (make_temp_dir): New function. (main): De-armor keyrings. * g10/main.h (dearmor_file): Adapt prototype. GnuPG-bug-id: 2290 Signed-off-by: Justus Winter --- g10/gpgv.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 126 insertions(+), 4 deletions(-) (limited to 'g10/gpgv.c') diff --git a/g10/gpgv.c b/g10/gpgv.c index 19a2ff6c7..de6529b04 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -25,9 +25,7 @@ #include #include #include -#ifdef HAVE_DOSISH_SYSTEM -#include /* for setmode() */ -#endif +#include #ifdef HAVE_LIBREADLINE #define GNUPG_LIBREADLINE_H_INCLUDED #include @@ -135,6 +133,66 @@ my_strusage( int level ) } +static char * +make_temp_dir (void) +{ + char *result; + char *tmp; +#if defined (_WIN32) + int err; + + tmp = xmalloc (MAX_PATH+2); + err = GetTempPath (MAX_PATH + 1, tmp); + if (err == 0 || err > MAX_PATH + 1) + strcpy (tmp, "c:\\windows\\temp"); + else + { + int len = strlen (tmp); + + /* GetTempPath may return with \ on the end */ + while (len > 0 && tmp[len-1] == '\\') + { + tmp[len-1] = '\0'; + len--; + } + } +#else /* More unixish systems */ + tmp = getenv ("TMPDIR"); + if (tmp == NULL) + { + tmp = getenv ("TMP"); + if (tmp == NULL) + { +#ifdef __riscos__ + tmp = ".GnuPG"; + mkdir (tmp, 0700); /* Error checks occur later on */ +#else + tmp = "/tmp"; +#endif + } + } +#endif + + result = xasprintf ("%s" DIRSEP_S "gpg-XXXXXX", tmp); + +#if defined (_WIN32) + xfree(tmp); +#endif + + if (result == NULL) + return NULL; + + if (! gnupg_mkdtemp (result)) + { + log_error (_("can't create directory '%s': %s\n"), + result, strerror (errno)); + xfree (result); + return NULL; + } + + return result; +} + int main( int argc, char **argv ) @@ -143,6 +201,7 @@ main( int argc, char **argv ) int rc=0; strlist_t sl; strlist_t nrings = NULL; + strlist_t tmprings = NULL; unsigned configlineno; ctrl_t ctrl; @@ -216,8 +275,63 @@ main( int argc, char **argv ) (KEYDB_RESOURCE_FLAG_READONLY |KEYDB_RESOURCE_FLAG_GPGVDEF)); for (sl = nrings; sl; sl = sl->next) - keydb_add_resource (sl->d, KEYDB_RESOURCE_FLAG_READONLY); + { + char *name = sl->d; + if (strlen (name) >= 4 + && strcmp (&name[strlen (name) - 4], ".asc") == 0) + { + /* The file is an armored keyring. Dearmor it. */ + char *tmpdir = NULL, *tmpname = NULL; + int fd = -1, success; + tmpdir = make_temp_dir (); + if (tmpdir == NULL) + goto cleanup; + + tmpname = xasprintf ("%s" DIRSEP_S "key", tmpdir); + if (tmpname == NULL) + goto cleanup; + + if (! add_to_strlist_try (&tmprings, tmpname)) + goto cleanup; + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + fd = open (tmpname, O_WRONLY|O_CREAT|O_BINARY, S_IRUSR); + if (fd == -1) + goto cleanup; + + rc = dearmor_file (name, fd); + close (fd); + fd = -2; + if (rc) + goto cleanup; + + keydb_add_resource (tmpname, KEYDB_RESOURCE_FLAG_READONLY); + + cleanup: + success = tmpdir && tmpname && fd != -1; + if (fd >= 0) + close (fd); + if (tmpname) + { + if (! success) + unlink (tmpname); + xfree (tmpname); + } + if (tmpdir) + { + if (! success) + rmdir (tmpdir); + xfree (tmpdir); + } + if (! success) + g10_exit (1); + } + else + keydb_add_resource (name, KEYDB_RESOURCE_FLAG_READONLY); + } FREE_STRLIST (nrings); ctrl = xcalloc (1, sizeof *ctrl); @@ -227,6 +341,14 @@ main( int argc, char **argv ) xfree (ctrl); + for (sl = tmprings; sl; sl = sl->next) + { + unlink (sl->d); + sl->d[strlen (sl->d) - 4] = 0; + rmdir (sl->d); + } + FREE_STRLIST (tmprings); + /* cleanup */ g10_exit (0); return 8; /*NOTREACHED*/ -- cgit v1.2.3