summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/Makefile.am41
-rw-r--r--tools/Makefile.in59
-rw-r--r--tools/gpg-check-pattern.c2
-rw-r--r--tools/gpg-check-pattern.w32-manifest.in7
-rw-r--r--tools/gpg-connect-agent.w32-manifest.in7
-rw-r--r--tools/gpg-wks-client.c133
-rw-r--r--tools/gpg-wks-client.w32-manifest.in7
-rw-r--r--tools/gpg-wks.h8
-rw-r--r--tools/gpgconf.c303
-rw-r--r--tools/gpgconf.w32-manifest.in7
-rw-r--r--tools/gpgtar-create.c128
-rw-r--r--tools/gpgtar-extract.c69
-rw-r--r--tools/gpgtar-list.c6
-rw-r--r--tools/gpgtar.c76
-rw-r--r--tools/gpgtar.h10
-rw-r--r--tools/gpgtar.w32-manifest.in7
-rw-r--r--tools/wks-util.c226
17 files changed, 854 insertions, 242 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
index acc649c..262876f 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -32,23 +32,20 @@ AM_CPPFLAGS =
include $(top_srcdir)/am/cmacros.am
if HAVE_W32_SYSTEM
-gpgconf_robjs = $(resource_objs) gpgconf-w32info.o
-gpgtar_robjs = $(resource_objs) gpgtar-w32info.o
-gpg_connect_agent_robjs = $(resource_objs) gpg-connect-agent-w32info.o
-gpg_check_pattern_robjs = $(resource_objs) gpg-check-pattern-w32info.o
-gpg_wks_client_robjs = $(resource_objs) gpg-wks-client-w32info.o
-
-gpgconf-w32info.o: gpgconf.w32-manifest
-gpgtar-w32info.o: gpgtar.w32-manifest
-gpg-connect-agent-w32info.o: gpg-connect-agent.w32-manifest
-gpg-check-pattern-w32info.o: gpg-check-pattern.w32-manifest
-gpg-wks-client-w32info.o: gpg-wks-client.w32-manifest
-else
-gpg_connect_agent_robjs =
-gpgconf_robjs =
-gpg_check_pattern_robjs =
-gpgtar_robjs =
-gpg_wks_client_robjs =
+gpgconf_rc_objs = $(resource_objs) gpgconf-w32info.o
+gpgtar_rc_objs = $(resource_objs) gpgtar-w32info.o
+gpg_connect_agent_rc_objs = $(resource_objs) gpg-connect-agent-w32info.o
+gpg_check_pattern_rc_objs = $(resource_objs) gpg-check-pattern-w32info.o
+gpg_wks_client_rc_objs = $(resource_objs) gpg-wks-client-w32info.o
+
+gpg-connect-agent-w32info.o : gpg-connect-agent.w32-manifest \
+ ../common/w32info-rc.h
+gpgconf-w32info.o : gpgconf.w32-manifest ../common/w32info-rc.h
+gpgtar-w32info.o : gpgtar.w32-manifest ../common/w32info-rc.h
+gpg-check-pattern-w32info.o : gpg-check-pattern.w32-manifest \
+ ../common/w32info-rc.h
+gpg-wks-client-w32info.o : gpg-wks-client.w32-manifest \
+ ../common/w32info-rc.h
endif
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
@@ -123,7 +120,7 @@ gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c
gpgconf_LDADD = $(maybe_commonpth_libs) $(opt_libassuan_libs) \
$(LIBINTL) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \
$(LIBICONV) $(W32SOCKLIBS) \
- $(gpgconf_robjs)
+ $(gpgconf_rc_objs)
gpgconf_LDFLAGS = $(extra_bin_ldflags)
gpgconf_w32_SOURCES = $(gpgconf_SOURCES)
@@ -141,14 +138,14 @@ gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \
$(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) \
$(GPG_ERROR_LIBS) \
$(LIBREADLINE) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
- $(gpg_connect_agent_robjs)
+ $(gpg_connect_agent_rc_objs)
gpg_check_pattern_SOURCES = gpg-check-pattern.c
gpg_check_pattern_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(INCICONV)
gpg_check_pattern_LDADD = $(common_libs) $(regexp_libs) $(LIBGCRYPT_LIBS) \
$(GPG_ERROR_LIBS) \
$(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS) \
- $(LIBICONV) $(gpg_check_pattern_robjs)
+ $(LIBICONV) $(gpg_check_pattern_rc_objs)
gpgtar_SOURCES = \
gpgtar.c gpgtar.h \
@@ -158,7 +155,7 @@ gpgtar_SOURCES = \
gpgtar_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
gpgtar_LDADD = $(libcommon) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
$(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS) \
- $(gpgtar_robjs)
+ $(gpgtar_rc_objs)
gpg_wks_server_SOURCES = \
gpg-wks-server.c \
@@ -190,7 +187,7 @@ gpg_wks_client_CFLAGS = $(LIBASSUAN_CFLAGS) $(LIBGCRYPT_CFLAGS) \
gpg_wks_client_LDADD = $(libcommon) \
$(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
$(LIBINTL) $(LIBICONV) $(NETLIBS) \
- $(gpg_wks_client_robjs)
+ $(gpg_wks_client_rc_objs)
# Make sure that all libs are build before we use them. This is
diff --git a/tools/Makefile.in b/tools/Makefile.in
index e1b7da9..e1b3082 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -157,17 +157,16 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \
$(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \
- $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \
- $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \
- $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
- $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \
- $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/nls.m4 \
- $(top_srcdir)/m4/npth.m4 $(top_srcdir)/m4/ntbtls.m4 \
- $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/readline.m4 \
- $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
- $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/ksba.m4 $(top_srcdir)/m4/lcmessage.m4 \
+ $(top_srcdir)/m4/ldap.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libassuan.m4 $(top_srcdir)/m4/libgcrypt.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/npth.m4 \
+ $(top_srcdir)/m4/ntbtls.m4 $(top_srcdir)/m4/pkg.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/socklen.m4 \
+ $(top_srcdir)/m4/sys_socket_h.m4 $(top_srcdir)/m4/tar-ustar.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
@@ -641,16 +640,11 @@ libcommon = ../common/libcommon.a
libcommonpth = ../common/libcommonpth.a
libcommontls = ../common/libcommontls.a
libcommontlsnpth = ../common/libcommontlsnpth.a
-@HAVE_W32_SYSTEM_FALSE@gpgconf_robjs =
-@HAVE_W32_SYSTEM_TRUE@gpgconf_robjs = $(resource_objs) gpgconf-w32info.o
-@HAVE_W32_SYSTEM_FALSE@gpgtar_robjs =
-@HAVE_W32_SYSTEM_TRUE@gpgtar_robjs = $(resource_objs) gpgtar-w32info.o
-@HAVE_W32_SYSTEM_FALSE@gpg_connect_agent_robjs =
-@HAVE_W32_SYSTEM_TRUE@gpg_connect_agent_robjs = $(resource_objs) gpg-connect-agent-w32info.o
-@HAVE_W32_SYSTEM_FALSE@gpg_check_pattern_robjs =
-@HAVE_W32_SYSTEM_TRUE@gpg_check_pattern_robjs = $(resource_objs) gpg-check-pattern-w32info.o
-@HAVE_W32_SYSTEM_FALSE@gpg_wks_client_robjs =
-@HAVE_W32_SYSTEM_TRUE@gpg_wks_client_robjs = $(resource_objs) gpg-wks-client-w32info.o
+@HAVE_W32_SYSTEM_TRUE@gpgconf_rc_objs = $(resource_objs) gpgconf-w32info.o
+@HAVE_W32_SYSTEM_TRUE@gpgtar_rc_objs = $(resource_objs) gpgtar-w32info.o
+@HAVE_W32_SYSTEM_TRUE@gpg_connect_agent_rc_objs = $(resource_objs) gpg-connect-agent-w32info.o
+@HAVE_W32_SYSTEM_TRUE@gpg_check_pattern_rc_objs = $(resource_objs) gpg-check-pattern-w32info.o
+@HAVE_W32_SYSTEM_TRUE@gpg_wks_client_rc_objs = $(resource_objs) gpg-wks-client-w32info.o
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
sbin_SCRIPTS = addgnupghome applygnupgdefaults
@@ -679,7 +673,7 @@ gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c
gpgconf_LDADD = $(maybe_commonpth_libs) $(opt_libassuan_libs) \
$(LIBINTL) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \
$(LIBICONV) $(W32SOCKLIBS) \
- $(gpgconf_robjs)
+ $(gpgconf_rc_objs)
gpgconf_LDFLAGS = $(extra_bin_ldflags)
gpgconf_w32_SOURCES = $(gpgconf_SOURCES)
@@ -694,14 +688,14 @@ gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \
$(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) \
$(GPG_ERROR_LIBS) \
$(LIBREADLINE) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
- $(gpg_connect_agent_robjs)
+ $(gpg_connect_agent_rc_objs)
gpg_check_pattern_SOURCES = gpg-check-pattern.c
gpg_check_pattern_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(INCICONV)
gpg_check_pattern_LDADD = $(common_libs) $(regexp_libs) $(LIBGCRYPT_LIBS) \
$(GPG_ERROR_LIBS) \
$(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS) \
- $(LIBICONV) $(gpg_check_pattern_robjs)
+ $(LIBICONV) $(gpg_check_pattern_rc_objs)
gpgtar_SOURCES = \
gpgtar.c gpgtar.h \
@@ -712,7 +706,7 @@ gpgtar_SOURCES = \
gpgtar_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
gpgtar_LDADD = $(libcommon) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
$(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS) \
- $(gpgtar_robjs)
+ $(gpgtar_rc_objs)
gpg_wks_server_SOURCES = \
gpg-wks-server.c \
@@ -745,7 +739,7 @@ gpg_wks_client_CFLAGS = $(LIBASSUAN_CFLAGS) $(LIBGCRYPT_CFLAGS) \
gpg_wks_client_LDADD = $(libcommon) \
$(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
$(LIBINTL) $(LIBICONV) $(NETLIBS) \
- $(gpg_wks_client_robjs)
+ $(gpg_wks_client_rc_objs)
all: all-am
@@ -1574,11 +1568,14 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS \
@HAVE_W32_SYSTEM_TRUE@.rc.o:
@HAVE_W32_SYSTEM_TRUE@ $(WINDRES) $(DEFAULT_INCLUDES) $(INCLUDES) "$<" "$@"
-@HAVE_W32_SYSTEM_TRUE@gpgconf-w32info.o: gpgconf.w32-manifest
-@HAVE_W32_SYSTEM_TRUE@gpgtar-w32info.o: gpgtar.w32-manifest
-@HAVE_W32_SYSTEM_TRUE@gpg-connect-agent-w32info.o: gpg-connect-agent.w32-manifest
-@HAVE_W32_SYSTEM_TRUE@gpg-check-pattern-w32info.o: gpg-check-pattern.w32-manifest
-@HAVE_W32_SYSTEM_TRUE@gpg-wks-client-w32info.o: gpg-wks-client.w32-manifest
+@HAVE_W32_SYSTEM_TRUE@gpg-connect-agent-w32info.o : gpg-connect-agent.w32-manifest \
+@HAVE_W32_SYSTEM_TRUE@ ../common/w32info-rc.h
+@HAVE_W32_SYSTEM_TRUE@gpgconf-w32info.o : gpgconf.w32-manifest ../common/w32info-rc.h
+@HAVE_W32_SYSTEM_TRUE@gpgtar-w32info.o : gpgtar.w32-manifest ../common/w32info-rc.h
+@HAVE_W32_SYSTEM_TRUE@gpg-check-pattern-w32info.o : gpg-check-pattern.w32-manifest \
+@HAVE_W32_SYSTEM_TRUE@ ../common/w32info-rc.h
+@HAVE_W32_SYSTEM_TRUE@gpg-wks-client-w32info.o : gpg-wks-client.w32-manifest \
+@HAVE_W32_SYSTEM_TRUE@ ../common/w32info-rc.h
# Make sure that all libs are build before we use them. This is
# important for things like make -j2.
diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c
index 77176cc..c2e3b5f 100644
--- a/tools/gpg-check-pattern.c
+++ b/tools/gpg-check-pattern.c
@@ -286,7 +286,7 @@ read_file (const char *fname, size_t *r_length)
buflen = st.st_size;
buf = xmalloc (buflen+1);
- if (es_fread (buf, buflen, 1, fp) != 1)
+ if (buflen && es_fread (buf, buflen, 1, fp) != 1)
{
log_error ("error reading '%s': %s\n", fname, strerror (errno));
es_fclose (fp);
diff --git a/tools/gpg-check-pattern.w32-manifest.in b/tools/gpg-check-pattern.w32-manifest.in
index 2a5f8ec..acb7c91 100644
--- a/tools/gpg-check-pattern.w32-manifest.in
+++ b/tools/gpg-check-pattern.w32-manifest.in
@@ -15,4 +15,11 @@
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/><!-- Vista -->
</application>
</compatibility>
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker"/>
+ </requestedPrivileges>
+ </security>
+</trustInfo>
</assembly>
diff --git a/tools/gpg-connect-agent.w32-manifest.in b/tools/gpg-connect-agent.w32-manifest.in
index aba5420..c222a67 100644
--- a/tools/gpg-connect-agent.w32-manifest.in
+++ b/tools/gpg-connect-agent.w32-manifest.in
@@ -15,4 +15,11 @@
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/><!-- Vista -->
</application>
</compatibility>
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker"/>
+ </requestedPrivileges>
+ </security>
+</trustInfo>
</assembly>
diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index 3aa8f98..6f593ff 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -74,6 +74,8 @@ enum cmd_and_opt_values
oWithColons,
oBlacklist,
oNoAutostart,
+ oAddRevocs,
+ oNoAddRevocs,
oDummy
};
@@ -100,9 +102,9 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aRemoveKey, "remove-key",
"remove a key from a directory"),
ARGPARSE_c (aPrintWKDHash, "print-wkd-hash",
- "Print the WKD identifier for the given user ids"),
+ "print the WKD identifier for the given user ids"),
ARGPARSE_c (aPrintWKDURL, "print-wkd-url",
- "Print the WKD URL for the given user id"),
+ "print the WKD URL for the given user id"),
ARGPARSE_group (301, ("@\nOptions:\n ")),
@@ -117,6 +119,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oWithColons, "with-colons", "@"),
ARGPARSE_s_s (oBlacklist, "blacklist", "@"),
ARGPARSE_s_s (oDirectory, "directory", "@"),
+ ARGPARSE_s_n (oAddRevocs, "add-revocs", "add revocation certificates"),
+ ARGPARSE_s_n (oNoAddRevocs, "no-add-revocs", "do not add revocation certificates"),
ARGPARSE_s_s (oFakeSubmissionAddr, "fake-submission-addr", "@"),
@@ -154,7 +158,7 @@ static gpg_error_t proc_userid_from_stdin (gpg_error_t (*func)(const char *),
const char *text);
static gpg_error_t command_supported (char *userid);
static gpg_error_t command_check (char *userid);
-static gpg_error_t command_send (const char *fingerprint, const char *userid);
+static gpg_error_t command_create (const char *fingerprint, const char *userid);
static gpg_error_t encrypt_response (estream_t *r_output, estream_t input,
const char *addrspec,
const char *fingerprint);
@@ -254,6 +258,12 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
case oBlacklist:
add_blacklist (pargs->r.ret_str);
break;
+ case oAddRevocs:
+ opt.add_revocs = 1;
+ break;
+ case oNoAddRevocs:
+ opt.add_revocs = 0;
+ break;
case aSupported:
case aCreate:
@@ -296,6 +306,8 @@ main (int argc, char **argv)
assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
setup_libassuan_logging (&opt.debug, NULL);
+ opt.add_revocs = 1; /* Default add revocation certs. */
+
/* Parse the command line. */
pargs.argc = &argc;
pargs.argv = &argv;
@@ -372,7 +384,7 @@ main (int argc, char **argv)
case aCreate:
if (argc != 2)
wrong_args ("--create FINGERPRINT USER-ID");
- err = command_send (argv[0], argv[1]);
+ err = command_create (argv[0], argv[1]);
if (err)
log_error ("creating request failed: %s\n", gpg_strerror (err));
break;
@@ -1090,6 +1102,9 @@ command_check (char *userid)
log_info (" created: %s\n", asctimestamp (sl->created));
if (sl->mbox)
log_info (" addr-spec: %s\n", sl->mbox);
+ if (sl->expired || sl->revoked)
+ log_info (" flags:%s%s\n",
+ sl->expired? " expired":"", sl->revoked?" revoked":"");
}
}
if (!found)
@@ -1112,7 +1127,7 @@ command_check (char *userid)
/* Locate the key by fingerprint and userid and send a publication
* request. */
static gpg_error_t
-command_send (const char *fingerprint, const char *userid)
+command_create (const char *fingerprint, const char *userid)
{
gpg_error_t err;
KEYDB_SEARCH_DESC desc;
@@ -1128,6 +1143,7 @@ command_send (const char *fingerprint, const char *userid)
uidinfo_list_t uidlist = NULL;
uidinfo_list_t uid, thisuid;
time_t thistime;
+ int any;
if (classify_user_id (fingerprint, &desc, 1)
|| !(desc.mode == KEYDB_SEARCH_MODE_FPR
@@ -1145,7 +1161,7 @@ command_send (const char *fingerprint, const char *userid)
err = gpg_error (GPG_ERR_INV_USER_ID);
goto leave;
}
- err = wks_get_key (&key, fingerprint, addrspec, 0);
+ err = wks_get_key (&key, fingerprint, addrspec, 0, 1);
if (err)
goto leave;
@@ -1189,12 +1205,20 @@ command_send (const char *fingerprint, const char *userid)
}
thistime = 0;
thisuid = NULL;
+ any = 0;
for (uid = uidlist; uid; uid = uid->next)
{
if (!uid->mbox)
continue; /* Should not happen anyway. */
if (policy->mailbox_only && ascii_strcasecmp (uid->uid, uid->mbox))
continue; /* UID has more than just the mailbox. */
+ if (uid->expired)
+ {
+ if (opt.verbose)
+ log_info ("ignoring expired user id '%s'\n", uid->uid);
+ continue;
+ }
+ any = 1;
if (uid->created > thistime)
{
thistime = uid->created;
@@ -1203,6 +1227,14 @@ command_send (const char *fingerprint, const char *userid)
}
if (!thisuid)
thisuid = uidlist; /* This is the case for a missing timestamp. */
+ if (!any)
+ {
+ log_error ("public key %s has no mail address '%s'\n",
+ fingerprint, addrspec);
+ err = gpg_error (GPG_ERR_INV_USER_ID);
+ goto leave;
+ }
+
if (opt.verbose)
log_info ("submitting key with user id '%s'\n", thisuid->uid);
@@ -1213,7 +1245,7 @@ command_send (const char *fingerprint, const char *userid)
estream_t newkey;
es_rewind (key);
- err = wks_filter_uid (&newkey, key, thisuid->uid, 0);
+ err = wks_filter_uid (&newkey, key, thisuid->uid, 1);
if (err)
{
log_error ("error filtering key: %s\n", gpg_strerror (err));
@@ -1238,11 +1270,47 @@ command_send (const char *fingerprint, const char *userid)
* the key again. */
es_fclose (key);
key = NULL;
- err = wks_get_key (&key, fingerprint, addrspec, 1);
+ err = wks_get_key (&key, fingerprint, addrspec, 1, 1);
if (err)
goto leave;
}
+ if (opt.add_revocs)
+ {
+ if (es_fseek (key, 0, SEEK_END))
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error seeking stream: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+ err = wks_find_add_revocs (key, addrspec);
+ if (err)
+ {
+ log_error ("error finding revocations for '%s': %s\n",
+ addrspec, gpg_strerror (err));
+ goto leave;
+ }
+ }
+
+
+ /* Now put the armor around the key. */
+ {
+ estream_t newkey;
+
+ es_rewind (key);
+ err = wks_armor_key (&newkey, key,
+ no_encrypt? NULL
+ /* */ : ("Content-Type: application/pgp-keys\n"
+ "\n"));
+ if (err)
+ {
+ log_error ("error armoring key: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+ es_fclose (key);
+ key = newkey;
+ }
+
/* Hack to support posteo but let them disable this by setting the
* new policy-version flag. */
if (policy->protocol_version < 3
@@ -1287,7 +1355,7 @@ command_send (const char *fingerprint, const char *userid)
if (no_encrypt)
{
void *data;
- size_t datalen, n;
+ size_t datalen;
if (posteo_hack)
{
@@ -1312,16 +1380,7 @@ command_send (const char *fingerprint, const char *userid)
goto leave;
}
key = NULL;
- /* We need to skip over the first line which has a content-type
- * header not needed here. */
- for (n=0; n < datalen ; n++)
- if (((const char *)data)[n] == '\n')
- {
- n++;
- break;
- }
-
- err = mime_maker_add_body_data (mime, (char*)data + n, datalen - n);
+ err = mime_maker_add_body_data (mime, data, datalen);
xfree (data);
if (err)
goto leave;
@@ -1808,7 +1867,7 @@ domain_matches_mbox (const char *domain, const char *mbox)
/* Core of mirror_one_key with the goal of mirroring just one uid.
* UIDLIST is used to figure out whether the given MBOX occurs several
- * times in UIDLIST and then to single out the newwest one. This is
+ * times in UIDLIST and then to single out the newest one. This is
* so that for a key with
* uid: Joe Someone <joe@example.org>
* uid: Joe <joe@example.org>
@@ -1849,24 +1908,36 @@ mirror_one_keys_userid (estream_t key, const char *mbox, uidinfo_list_t uidlist,
err = gpg_error (GPG_ERR_NO_USER_ID);
goto leave;
}
- /* FIXME: Consult blacklist. */
-
- /* Only if we have more than one user id we bother to run the
- * filter. In this case the result will be put into NEWKEY*/
+ /* Always filter the key so that the result will be non-armored. */
es_rewind (key);
- if (uidlist->next)
+ err = wks_filter_uid (&newkey, key, thisuid->uid, 1);
+ if (err)
{
- err = wks_filter_uid (&newkey, key, thisuid->uid, 0);
+ log_error ("error filtering key %s: %s\n", fpr, gpg_strerror (err));
+ err = gpg_error (GPG_ERR_NO_PUBKEY);
+ goto leave;
+ }
+
+ if (opt.add_revocs)
+ {
+ if (es_fseek (newkey, 0, SEEK_END))
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error seeking stream: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+ err = wks_find_add_revocs (newkey, mbox);
if (err)
{
- log_error ("error filtering key %s: %s\n", fpr, gpg_strerror (err));
- err = gpg_error (GPG_ERR_NO_PUBKEY);
+ log_error ("error finding revocations for '%s': %s\n",
+ mbox, gpg_strerror (err));
goto leave;
}
+ es_rewind (newkey);
}
- err = wks_install_key_core (newkey? newkey : key, mbox);
+ err = wks_install_key_core (newkey, mbox);
if (opt.verbose)
log_info ("key %s published for '%s'\n", fpr, mbox);
mirror_one_key_parm.nuids++;
@@ -1905,7 +1976,9 @@ mirror_one_key (estream_t key)
{
if (!uid->mbox || (uid->flags & 1))
continue; /* No mail box or already processed. */
- if (!domain_matches_mbox (domain, uid->mbox))
+ if (uid->expired)
+ continue;
+ if (*domain && !domain_matches_mbox (domain, uid->mbox))
continue; /* We don't want this one. */
if (is_in_blacklist (uid->mbox))
continue;
diff --git a/tools/gpg-wks-client.w32-manifest.in b/tools/gpg-wks-client.w32-manifest.in
index ba2508e..c44620f 100644
--- a/tools/gpg-wks-client.w32-manifest.in
+++ b/tools/gpg-wks-client.w32-manifest.in
@@ -15,4 +15,11 @@
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/><!-- Vista -->
</application>
</compatibility>
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker"/>
+ </requestedPrivileges>
+ </security>
+</trustInfo>
</assembly>
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index 32aa8c3..a7c17ca 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -39,6 +39,7 @@ struct
int use_sendmail;
int with_colons;
int no_autostart;
+ int add_revocs;
const char *output;
const char *gpg_program;
const char *directory;
@@ -80,6 +81,8 @@ struct uidinfo_list_s
time_t created; /* Time the userid was created. */
char *mbox; /* NULL or the malloced mailbox from UID. */
unsigned int flags; /* These flags are cleared on creation. */
+ unsigned int expired:1;
+ unsigned int revoked:1;
char uid[1];
};
typedef struct uidinfo_list_s *uidinfo_list_t;
@@ -91,11 +94,14 @@ void wks_set_status_fd (int fd);
void wks_write_status (int no, const char *format, ...) GPGRT_ATTR_PRINTF(2,3);
void free_uidinfo_list (uidinfo_list_t list);
gpg_error_t wks_get_key (estream_t *r_key, const char *fingerprint,
- const char *addrspec, int exact);
+ const char *addrspec, int exact, int binary);
gpg_error_t wks_list_key (estream_t key, char **r_fpr,
uidinfo_list_t *r_mboxes);
gpg_error_t wks_filter_uid (estream_t *r_newkey, estream_t key,
const char *uid, int binary);
+gpg_error_t wks_armor_key (estream_t *r_newkey, estream_t key,
+ const char *prefix);
+gpg_error_t wks_find_add_revocs (estream_t key, const char *addrspec);
gpg_error_t wks_send_mime (mime_maker_t mime);
gpg_error_t wks_parse_policy (policy_flags_t flags, estream_t stream,
int ignore_unknown);
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index 1b3f2be..d12a2c6 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -77,49 +77,53 @@ enum cmd_and_opt_values
/* The list of commands and options. */
static ARGPARSE_OPTS opts[] =
{
- { 300, NULL, 0, N_("@Commands:\n ") },
-
- { aListComponents, "list-components", 256, N_("list all components") },
- { aCheckPrograms, "check-programs", 256, N_("check all programs") },
- { aListOptions, "list-options", 256, N_("|COMPONENT|list options") },
- { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") },
- { aCheckOptions, "check-options", 256, N_("|COMPONENT|check options") },
- { aApplyDefaults, "apply-defaults", 256,
- N_("apply global default values") },
- { aApplyProfile, "apply-profile", 256,
- N_("|FILE|update configuration files using FILE") },
- { aListDirs, "list-dirs", 256,
- N_("get the configuration directories for @GPGCONF@") },
- { aListConfig, "list-config", 256,
- N_("list global configuration file") },
- { aCheckConfig, "check-config", 256,
- N_("check global configuration file") },
- { aQuerySWDB, "query-swdb", 256,
- N_("query the software version database") },
- { aReload, "reload", 256, N_("reload all or a given component")},
- { aLaunch, "launch", 256, N_("launch a given component")},
- { aKill, "kill", 256, N_("kill a given component")},
- { aCreateSocketDir, "create-socketdir", 256, "@"},
- { aRemoveSocketDir, "remove-socketdir", 256, "@"},
+ ARGPARSE_group (300, N_("@Commands:\n ")),
+
+ ARGPARSE_c (aListComponents, "list-components", N_("list all components")),
+ ARGPARSE_c (aCheckPrograms, "check-programs", N_("check all programs")),
+ ARGPARSE_c (aListOptions, "list-options", N_("|COMPONENT|list options")),
+ ARGPARSE_c (aChangeOptions, "change-options",
+ N_("|COMPONENT|change options")),
+ ARGPARSE_c (aCheckOptions, "check-options", N_("|COMPONENT|check options")),
+ ARGPARSE_c (aApplyDefaults, "apply-defaults",
+ N_("apply global default values")),
+ ARGPARSE_c (aApplyProfile, "apply-profile",
+ N_("|FILE|update configuration files using FILE")),
+ ARGPARSE_c (aListDirs, "list-dirs",
+ N_("get the configuration directories for @GPGCONF@")),
+ ARGPARSE_c (aListConfig, "list-config",
+ N_("list global configuration file")),
+ ARGPARSE_c (aCheckConfig, "check-config",
+ N_("check global configuration file")),
+ ARGPARSE_c (aQuerySWDB, "query-swdb",
+ N_("query the software version database")),
+ ARGPARSE_c (aReload, "reload", N_("reload all or a given component")),
+ ARGPARSE_c (aLaunch, "launch", N_("launch a given component")),
+ ARGPARSE_c (aKill, "kill", N_("kill a given component")),
+ ARGPARSE_c (aCreateSocketDir, "create-socketdir", "@"),
+ ARGPARSE_c (aRemoveSocketDir, "remove-socketdir", "@"),
ARGPARSE_c (aShowVersions, "show-versions", ""),
ARGPARSE_c (aShowConfigs, "show-configs", ""),
- { 301, NULL, 0, N_("@\nOptions:\n ") },
+ ARGPARSE_header (NULL, N_("@\nOptions:\n ")),
+
+ ARGPARSE_s_s (oOutput, "output", N_("use as output file")),
+ ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
+ ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")),
+ ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
+ ARGPARSE_s_n (oRuntime, "runtime",
+ N_("activate changes at runtime, if possible")),
+ ARGPARSE_s_i (oStatusFD, "status-fd",
+ N_("|FD|write status info to this FD")),
- { oOutput, "output", 2, N_("use as output file") },
- { oVerbose, "verbose", 0, N_("verbose") },
- { oQuiet, "quiet", 0, N_("quiet") },
- { oDryRun, "dry-run", 0, N_("do not make any changes") },
- { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") },
- ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")),
/* hidden options */
- { oHomedir, "homedir", 2, "@" },
- { oBuilddir, "build-prefix", 2, "@" },
- { oNull, "null", 0, "@" },
- { oNoVerbose, "no-verbose", 0, "@"},
+ ARGPARSE_s_s (oHomedir, "homedir", "@"),
+ ARGPARSE_s_s (oBuilddir, "build-prefix", "@"),
+ ARGPARSE_s_n (oNull, "null", "@"),
+ ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
ARGPARSE_s_n (oShowSocket, "show-socket", "@"),
- ARGPARSE_end(),
+ ARGPARSE_end ()
};
@@ -243,10 +247,10 @@ gpgconf_write_status (int no, const char *format, ...)
static void
-list_dirs (estream_t fp, char **names, int special)
+list_dirs (estream_t fp, char **names, int show_config_mode)
{
static struct {
- const char *name;
+ const char *name; /* If NULL only a file check will be done. */
const char *(*fnc)(void);
const char *extra;
} list[] = {
@@ -262,13 +266,16 @@ list_dirs (estream_t fp, char **names, int special)
{ "agent-extra-socket", gnupg_socketdir, GPG_AGENT_EXTRA_SOCK_NAME },
{ "agent-browser-socket",gnupg_socketdir, GPG_AGENT_BROWSER_SOCK_NAME },
{ "agent-socket", gnupg_socketdir, GPG_AGENT_SOCK_NAME },
+ { NULL, gnupg_socketdir, "S.uiserver" },
{ "homedir", gnupg_homedir, NULL }
};
int idx, j;
char *tmp;
const char *s;
+ gpg_error_t err;
-
+ if (show_config_mode)
+ es_fprintf (fp, "#+begin_example\n");
for (idx = 0; idx < DIM (list); idx++)
{
s = list[idx].fnc ();
@@ -279,20 +286,45 @@ list_dirs (estream_t fp, char **names, int special)
}
else
tmp = NULL;
- if (!names)
- es_fprintf (fp, "%s:%s\n", list[idx].name, gc_percent_escape (s));
+
+ if (!list[idx].name)
+ ;
+ else if (!names)
+ es_fprintf (fp, "%s%s:%s\n", show_config_mode? " ":"",
+ list[idx].name, gc_percent_escape (s));
else
{
for (j=0; names[j]; j++)
if (!strcmp (names[j], list[idx].name))
{
+ if (show_config_mode)
+ es_fputs (" ", fp);
es_fputs (s, fp);
es_putc (opt.null? '\0':'\n', fp);
}
}
+ /* In show config mode check that the socket files are accessible. */
+ if (list[idx].extra && show_config_mode)
+ {
+ estream_t tmpfp;
+
+ tmpfp = es_fopen (s, "rb");
+ if (tmpfp)
+ es_fclose (tmpfp); /* All fine - we can read that file. */
+ else if ((err=gpg_error_from_syserror ()) == GPG_ERR_ENOENT
+ || err == GPG_ERR_ENXIO)
+ ; /* No such file/ No such device or address - this is okay. */
+ else
+ es_fprintf (fp,
+ "# Warning: error reading existing file '%s': %s\n",
+ s, gpg_strerror (err));
+ }
+
xfree (tmp);
}
+ if (show_config_mode)
+ es_fprintf (fp, "#+end_example\n");
#ifdef HAVE_W32_SYSTEM
@@ -321,9 +353,9 @@ list_dirs (estream_t fp, char **names, int special)
}
es_fflush (fp);
- if (special)
+ if (show_config_mode)
es_fprintf (fp, "\n"
- "### Note: homedir taken from registry key %s%s\\%s:%s\n"
+ "Note: homedir taken from registry key %s%s\\%s:%s\n"
"\n",
hkcu?" HKCU":"", hklm?" HKLM":"",
GNUPG_REGISTRY_DIR, "HomeDir");
@@ -339,9 +371,9 @@ list_dirs (estream_t fp, char **names, int special)
{
xfree (tmp);
es_fflush (fp);
- if (special)
+ if (show_config_mode)
es_fprintf (fp, "\n"
- "### Note: registry key %s without value in HKCU or HKLM\n"
+ "Note: registry key %s without value in HKCU or HKLM\n"
"\n", GNUPG_REGISTRY_DIR);
else
log_info ("Warning: registry key (%s) without value in HKCU or HKLM\n",
@@ -349,7 +381,7 @@ list_dirs (estream_t fp, char **names, int special)
}
#else /*!HAVE_W32_SYSTEM*/
- (void)special;
+ (void)show_config_mode;
#endif /*!HAVE_W32_SYSTEM*/
}
@@ -1042,16 +1074,18 @@ get_revision_from_blurb (const char *blurb, int *r_len)
static void
show_version_gnupg (estream_t fp, const char *prefix)
{
- char *fname, *p;
+ char *fname, *p, *p0;
size_t n;
estream_t verfp;
- char line[100];
+ char *line = NULL;
+ size_t line_len = 0;
+ ssize_t length;
es_fprintf (fp, "%s%sGnuPG %s (%s)\n%s%s\n", prefix, *prefix?"":"* ",
strusage (13), BUILD_REVISION, prefix, strusage (17));
/* Show the GnuPG VS-Desktop version in --show-configs mode */
- if (prefix && *prefix == '#')
+ if (prefix && *prefix)
{
fname = make_filename (gnupg_bindir (), NULL);
n = strlen (fname);
@@ -1064,20 +1098,46 @@ show_version_gnupg (estream_t fp, const char *prefix)
verfp = es_fopen (fname, "r");
if (!verfp)
es_fprintf (fp, "%s[VERSION file not found]\n", prefix);
- else if (!es_fgets (line, sizeof line, verfp))
- es_fprintf (fp, "%s[VERSION file is empty]\n", prefix);
else
{
- trim_spaces (line);
- for (p=line; *p; p++)
- if (*p < ' ' || *p > '~' || *p == '[')
- *p = '?';
- es_fprintf (fp, "%s%s\n", prefix, line);
+ int lnr = 0;
+
+ p0 = NULL;
+ while ((length = es_read_line (verfp, &line, &line_len, NULL))>0)
+ {
+ lnr++;
+ trim_spaces (line);
+ if (lnr == 1 && *line != '[')
+ {
+ /* Old file format where we look only at the
+ * first line. */
+ p0 = line;
+ break;
+ }
+ else if (!strncmp (line, "version=", 8))
+ {
+ p0 = line + 8;
+ break;
+ }
+ }
+ if (length < 0 || es_ferror (verfp))
+ es_fprintf (fp, "%s[VERSION file read error]\n", prefix);
+ else if (p0)
+ {
+ for (p=p0; *p; p++)
+ if (*p < ' ' || *p > '~' || *p == '[')
+ *p = '?';
+ es_fprintf (fp, "%s%s\n", prefix, p0);
+ }
+ else
+ es_fprintf (fp, "%s[VERSION file is empty]\n", prefix);
+
+ es_fclose (verfp);
}
- es_fclose (verfp);
}
xfree (fname);
}
+ xfree (line);
#ifdef HAVE_W32_SYSTEM
{
@@ -1203,7 +1263,7 @@ show_versions (estream_t fp)
/* Copy data from file SRC to DST. Returns 0 on success or an error
* code on failure. If LISTP is not NULL, that strlist is updated
- * with the variabale or registry key names detected. Flag bit 0
+ * with the variable or registry key names detected. Flag bit 0
* indicates a registry entry. */
static gpg_error_t
my_copy_file (estream_t src, estream_t dst, strlist_t *listp)
@@ -1216,7 +1276,14 @@ my_copy_file (estream_t src, estream_t dst, strlist_t *listp)
while ((length = es_read_line (src, &line, &line_len, NULL)) > 0)
{
- /* Strip newline and carriage return, if present. */
+ /* Prefix each line with two spaces but use a comma if the line
+ * starts with a special org-mode character. */
+ if (*line == '*' || (*line == '#' && line[1] == '+'))
+ es_fputc (',', dst);
+ else
+ es_fputc (' ', dst);
+ es_fputc (' ', dst);
+
written = gpgrt_fwrite (line, 1, length, dst);
if (written != length)
return gpg_error_from_syserror ();
@@ -1284,21 +1351,19 @@ show_configs_one_file (const char *fname, int global, estream_t outfp,
if (!fp)
{
err = gpg_error_from_syserror ();
- es_fprintf (outfp, "###\n### %s config \"%s\": %s\n###\n",
- global? "global":"local", fname,
- (gpg_err_code (err) == GPG_ERR_ENOENT)?
- "not installed" : gpg_strerror (err));
+ if (gpg_err_code (err) != GPG_ERR_ENOENT)
+ es_fprintf (outfp, "** %s config \"%s\": %s\n",
+ global? "global":"local", fname, gpg_strerror (err));
}
else
{
- es_fprintf (outfp, "###\n### %s config \"%s\"\n###\n",
+ es_fprintf (outfp, "** %s config \"%s\"\n#+begin_src\n",
global? "global":"local", fname);
- es_fprintf (outfp, CUTLINE_FMT, "start");
err = my_copy_file (fp, outfp, listp);
+ es_fprintf (outfp, "\n#+end_src\n");
if (err)
- log_error ("error copying file \"%s\": %s\n",
+ log_error ("Error copying file \"%s\": %s\n",
fname, gpg_strerror (err));
- es_fprintf (outfp, CUTLINE_FMT, "end--");
es_fclose (fp);
}
}
@@ -1315,9 +1380,10 @@ show_other_registry_entries (estream_t outfp)
const char *name;
} names[] =
{
- { 1, "HKLM\\Software\\Gpg4win:Install Directory" },
{ 1, "HKLM\\Software\\Gpg4win:Desktop-Version" },
{ 1, "HKLM\\Software\\Gpg4win:VS-Desktop-Version" },
+ { 1, "\\Software\\Gpg4win:Install Directory" },
+ { 1, "\\Software\\GnuPG:Install Directory" },
{ 1, "\\" GNUPG_REGISTRY_DIR ":HomeDir" },
{ 1, "\\" GNUPG_REGISTRY_DIR ":DefaultLogFile" },
{ 2, "\\Software\\Microsoft\\Office\\Outlook\\Addins\\GNU.GpgOL"
@@ -1373,7 +1439,7 @@ show_other_registry_entries (estream_t outfp)
if (names[idx].group != group)
{
group = names[idx].group;
- es_fprintf (outfp, "###\n### %s related:\n",
+ es_fprintf (outfp, "\n%s related:\n",
group == 1 ? "GnuPG Desktop" :
group == 2 ? "Outlook" :
group == 3 ? "\\Software\\GNU\\GpgOL"
@@ -1381,16 +1447,15 @@ show_other_registry_entries (estream_t outfp)
}
if (group == 3)
- es_fprintf (outfp, "### %s=%s%s\n", names[idx].name, value,
+ es_fprintf (outfp, " %s=%s%s\n", names[idx].name, value,
from_hklm? " [hklm]":"");
else
- es_fprintf (outfp, "### %s\n### ->%s<-%s\n", name, value,
+ es_fprintf (outfp, " %s\n ->%s<-%s\n", name, value,
from_hklm? " [hklm]":"");
xfree (value);
}
- es_fprintf (outfp, "###\n");
xfree (namebuf);
}
@@ -1441,10 +1506,10 @@ show_registry_entries_from_file (estream_t outfp)
if (!any)
{
any = 1;
- es_fprintf (outfp, "### Taken from gpgconf.rnames:\n");
+ es_fprintf (outfp, "Taken from gpgconf.rnames:\n");
}
- es_fprintf (outfp, "### %s\n### ->%s<-%s\n", line, value,
+ es_fprintf (outfp, " %s\n ->%s<-%s\n", line, value,
from_hklm? " [hklm]":"");
}
@@ -1455,8 +1520,6 @@ show_registry_entries_from_file (estream_t outfp)
}
leave:
- if (any)
- es_fprintf (outfp, "###\n");
xfree (value);
xfree (line);
es_fclose (fp);
@@ -1472,23 +1535,32 @@ show_configs (estream_t outfp)
static const char *names[] = { "common.conf", "gpg-agent.conf",
"scdaemon.conf", "dirmngr.conf",
"gpg.conf", "gpgsm.conf" };
+ static const char *envvars[] = { "PATH",
+ "http_proxy", "HTTP_PROXY",
+ "https_proxy", "HTTPS_PROXY",
+ "LD_LIBRARY_PATH", "LD_PRELOAD",
+ "LD_AUDIT", "LD_ORIGIN_PATH" };
gpg_error_t err;
int idx;
char *fname;
gnupg_dir_t dir;
gnupg_dirent_t dir_entry;
size_t n;
- int any;
+ int any, anywarn;
strlist_t list = NULL;
strlist_t sl;
const char *s;
-
- es_fprintf (outfp, "### Dump of all standard config files\n");
- show_version_gnupg (outfp, "### ");
- es_fprintf (outfp, "### Libgcrypt %s\n", gcry_check_version (NULL));
- es_fprintf (outfp, "### GpgRT %s\n", gpg_error_check_version (NULL));
+ int got_gpgconfconf = 0;
+
+ es_fprintf (outfp, "# gpgconf -X invoked %s%*s-*- org -*-\n\n",
+ isotimestamp (time (NULL)), 28, "");
+ es_fprintf (outfp, "* General information\n");
+ es_fprintf (outfp, "** Versions\n");
+ show_version_gnupg (outfp, " ");
+ es_fprintf (outfp, " Libgcrypt %s\n", gcry_check_version (NULL));
+ es_fprintf (outfp, " GpgRT %s\n", gpg_error_check_version (NULL));
#ifdef HAVE_W32_SYSTEM
- es_fprintf (outfp, "### Codepages:");
+ es_fprintf (outfp, " Codepages:");
if (GetConsoleCP () != GetConsoleOutputCP ())
es_fprintf (outfp, " %u/%u", GetConsoleCP (), GetConsoleOutputCP ());
else
@@ -1496,11 +1568,28 @@ show_configs (estream_t outfp)
es_fprintf (outfp, " %u", GetACP ());
es_fprintf (outfp, " %u\n", GetOEMCP ());
#endif
- es_fprintf (outfp, "###\n\n");
+ es_fprintf (outfp, "\n\n");
+ es_fprintf (outfp, "** Directories\n");
list_dirs (outfp, NULL, 1);
es_fprintf (outfp, "\n");
+ es_fprintf (outfp, "** Environment\n#+begin_example\n");
+ for (idx=0; idx < DIM(envvars); idx++)
+ if ((s = getenv (envvars[idx])))
+ es_fprintf (outfp, "%s=%s\n", envvars[idx], s);
+ es_fprintf (outfp, "#+end_example\n");
+
+ es_fprintf (outfp, "* Config files\n");
+ fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
+ if (!gnupg_access (fname, F_OK))
+ {
+ got_gpgconfconf = 1;
+ show_configs_one_file (fname, 1, outfp, &list);
+ es_fprintf (outfp, "\n");
+ }
+ xfree (fname);
+
for (idx = 0; idx < DIM (names); idx++)
{
fname = make_filename (gnupg_sysconfdir (), names[idx], NULL);
@@ -1513,6 +1602,7 @@ show_configs (estream_t outfp)
}
/* Print the encountered registry values and envvars. */
+ es_fprintf (outfp, "* Other info\n");
if (list)
{
any = 0;
@@ -1523,20 +1613,21 @@ show_configs (estream_t outfp)
{
any = 1;
es_fprintf (outfp,
- "###\n"
- "### List of encountered environment variables:\n");
+ "** List of encountered environment variables\n"
+ "#+begin_example\n");
}
if ((s = getenv (sl->d)))
- es_fprintf (outfp, "### %-12s ->%s<-\n", sl->d, s);
+ es_fprintf (outfp, " %-12s ->%s<-\n", sl->d, s);
else
- es_fprintf (outfp, "### %-12s [not set]\n", sl->d);
+ es_fprintf (outfp, " %-12s [not set]\n", sl->d);
}
if (any)
- es_fprintf (outfp, "###\n");
+ es_fprintf (outfp, "#+end_example\n");
}
#ifdef HAVE_W32_SYSTEM
- es_fprintf (outfp, "###\n### Registry entries:\n");
+ es_fprintf (outfp, "** Registry entries\n");
+ es_fprintf (outfp, "#+begin_example\n");
any = 0;
if (list)
{
@@ -1549,24 +1640,33 @@ show_configs (estream_t outfp)
if (!any)
{
any = 1;
- es_fprintf (outfp, "###\n### Encountered in config files:\n");
+ es_fprintf (outfp, "Encountered in config files:\n");
}
if ((p = read_w32_reg_string (sl->d, &from_hklm)))
- es_fprintf (outfp, "### %s ->%s<-%s\n", sl->d, p,
+ es_fprintf (outfp, " %s ->%s<-%s\n", sl->d, p,
from_hklm? " [hklm]":"");
else
- es_fprintf (outfp, "### %s [not set]\n", sl->d);
+ es_fprintf (outfp, " %s [not set]\n", sl->d);
xfree (p);
}
}
- if (!any)
- es_fprintf (outfp, "###\n");
show_other_registry_entries (outfp);
show_registry_entries_from_file (outfp);
+ es_fprintf (outfp, "#+end_example\n");
#endif /*HAVE_W32_SYSTEM*/
free_strlist (list);
+ /* Additional warning. */
+ anywarn = 0;
+ if (got_gpgconfconf)
+ {
+ anywarn = 1;
+ es_fprintf (outfp, "* Warnings\n");
+ es_fprintf (outfp,
+ "- Legacy config file \"gpgconf.conf\" found\n");
+ }
+
/* Check for uncommon files in the home directory. */
dir = gnupg_opendir (gnupg_homedir ());
if (!dir)
@@ -1587,19 +1687,22 @@ show_configs (estream_t outfp)
&& dir_entry->d_name[n] == '-'
&& ascii_strncasecmp (dir_entry->d_name, "gpg.conf-1", 10))
{
+ if (!anywarn)
+ {
+ anywarn = 1;
+ es_fprintf (outfp, "* Warnings\n");
+ }
if (!any)
{
any = 1;
es_fprintf (outfp,
- "###\n"
- "### Warning: suspicious files in \"%s\":\n",
+ "- Suspicious files in \"%s\":\n",
gnupg_homedir ());
}
- es_fprintf (outfp, "### %s\n", dir_entry->d_name);
+ es_fprintf (outfp, " - %s\n", dir_entry->d_name);
}
}
}
- if (any)
- es_fprintf (outfp, "###\n");
gnupg_closedir (dir);
+ es_fprintf (outfp, "# eof #\n");
}
diff --git a/tools/gpgconf.w32-manifest.in b/tools/gpgconf.w32-manifest.in
index d7a1b01..ab5f17d 100644
--- a/tools/gpgconf.w32-manifest.in
+++ b/tools/gpgconf.w32-manifest.in
@@ -15,4 +15,11 @@
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/><!-- Vista -->
</application>
</compatibility>
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker"/>
+ </requestedPrivileges>
+ </security>
+</trustInfo>
</assembly>
diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
index e642da0..8cb65c7 100644
--- a/tools/gpgtar-create.c
+++ b/tools/gpgtar-create.c
@@ -1,5 +1,5 @@
/* gpgtar-create.c - Create a TAR archive
- * Copyright (C) 2016-2017, 2019-2022 g10 Code GmbH
+ * Copyright (C) 2016-2017, 2019-2023 g10 Code GmbH
* Copyright (C) 2010, 2012, 2013 Werner Koch
* Copyright (C) 2010 Free Software Foundation, Inc.
*
@@ -49,10 +49,19 @@
#define lstat(a,b) gnupg_stat ((a), (b))
#endif
+/* Number of files to be write. */
+static unsigned long global_total_files;
+
+/* Count the number of written file and thus headers. Extended
+ * headers are not counted. */
+static unsigned long global_written_files;
+
+/* Total data expected to be written. */
+static unsigned long long global_total_data;
+
+/* Number of data bytes written so far. */
+static unsigned long long global_written_data;
-/* Count the number of written headers. Extended headers are not
- * counted. */
-static unsigned long global_header_count;
/* Object to control the file scanning. */
@@ -62,10 +71,62 @@ struct scanctrl_s
{
tar_header_t flist;
tar_header_t *flist_tail;
+ unsigned long file_count;
int nestlevel;
};
+/* See ../g10/progress.c:write_status_progress for some background. */
+static void
+write_progress (int countmode, unsigned long long current,
+ unsigned long long total_arg)
+{
+ char units[] = "BKMGTPEZY?";
+ int unitidx = 0;
+ uint64_t total = total_arg;
+
+ if (!opt.status_stream)
+ return; /* Not enabled. */
+
+ if (countmode)
+ {
+ if (total && current > total)
+ current = total;
+ }
+ else if (total) /* Size mode: This may use units. */
+ {
+ if (current > total)
+ current = total;
+
+ while (total > 1024*1024)
+ {
+ total /= 1024;
+ current /= 1024;
+ unitidx++;
+ }
+ }
+ else /* Size mode */
+ {
+ while (current > 1024*1024)
+ {
+ current /= 1024;
+ unitidx++;
+ }
+ }
+
+ if (unitidx > sizeof units - 1)
+ unitidx = sizeof units - 1;
+
+ if (countmode)
+ es_fprintf (opt.status_stream, "[GNUPG:] PROGRESS gpgtar c %zu %zu\n",
+ (size_t)current, (size_t)total);
+ else
+ es_fprintf (opt.status_stream, "[GNUPG:] PROGRESS gpgtar s %zu %zu %c%s\n",
+ (size_t)current, (size_t)total,
+ units[unitidx],
+ unitidx? "iB" : "");
+}
+
/* On Windows convert name to UTF8 and return it; caller must release
* the result. On Unix or if ALREADY_UTF8 is set, this function is a
@@ -300,6 +361,12 @@ add_entry (const char *dname, const char *entryname, scanctrl_t scanctrl)
gpgtar_print_header (hdr, NULL, log_get_stream ());
*scanctrl->flist_tail = hdr;
scanctrl->flist_tail = &hdr->next;
+ scanctrl->file_count++;
+ /* Print a progress line during scnanning in increments of 5000
+ * and not of 100 as we doing during write: Scanning is of
+ * course much faster. */
+ if (!(scanctrl->file_count % 5000))
+ write_progress (1, scanctrl->file_count, 0);
}
return 0;
@@ -709,7 +776,7 @@ build_header (void *record, tar_header_t hdr, strlist_t *r_exthdr)
* will do. To ease testing we also put in the PID. The
* count is bumped after the header has been written. */
snprintf (raw->name, sizeof raw->name-1, "_@paxheader.%u.%lu",
- (unsigned int)getpid(), global_header_count + 1);
+ (unsigned int)getpid(), global_written_files + 1);
}
}
@@ -881,7 +948,7 @@ write_extended_header (estream_t stream, const void *record, strlist_t exthdr)
static gpg_error_t
-write_file (estream_t stream, tar_header_t hdr)
+write_file (estream_t stream, tar_header_t hdr, unsigned int *skipped_open)
{
gpg_error_t err;
char record[RECORDSIZE];
@@ -895,7 +962,7 @@ write_file (estream_t stream, tar_header_t hdr)
{
if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
{
- log_info ("skipping unsupported file '%s'\n", hdr->name);
+ log_info ("silently skipping unsupported file '%s'\n", hdr->name);
err = 0;
}
return err;
@@ -907,9 +974,12 @@ write_file (estream_t stream, tar_header_t hdr)
if (!infp)
{
err = gpg_error_from_syserror ();
- log_error ("can't open '%s': %s - skipped\n",
+ log_info ("can't open '%s': %s - skipped\n",
hdr->name, gpg_strerror (err));
- return err;
+ ++*skipped_open;
+ if (!*skipped_open) /* Protect against overflow. */
+ --*skipped_open;
+ return 0;
}
}
else
@@ -920,7 +990,9 @@ write_file (estream_t stream, tar_header_t hdr)
err = write_record (stream, record);
if (err)
goto leave;
- global_header_count++;
+ global_written_files++;
+ if (!(global_written_files % 100))
+ write_progress (1, global_written_files, global_total_files);
if (hdr->typeflag == TF_REGULAR)
{
@@ -946,6 +1018,9 @@ write_file (estream_t stream, tar_header_t hdr)
err = write_record (stream, record);
if (err)
goto leave;
+ global_written_data += nbytes;
+ if (!((global_written_data/nbytes) % (2048*100)))
+ write_progress (0, global_written_data, global_total_data);
}
nread = es_fread (record, 1, 1, infp);
if (nread)
@@ -995,6 +1070,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
estream_t outstream = NULL;
int eof_seen = 0;
pid_t pid = (pid_t)(-1);
+ unsigned int skipped_open = 0;
memset (scanctrl, 0, sizeof *scanctrl);
scanctrl->flist_tail = &scanctrl->flist;
@@ -1147,10 +1223,22 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
if (files_from_stream && files_from_stream != es_stdin)
es_fclose (files_from_stream);
+ global_total_files = global_total_data = 0;
+ global_written_files = global_written_data = 0;
+ for (hdr = scanctrl->flist; hdr; hdr = hdr->next)
+ {
+ global_total_files++;
+ global_total_data += hdr->size;
+ }
+ write_progress (1, 0, global_total_files);
+ write_progress (0, 0, global_total_data);
+
+
if (encrypt || sign)
{
strlist_t arg;
ccparray_t ccp;
+ int except[2] = { -1, -1 };
const char **argv;
/* '--encrypt' may be combined with '--symmetric', but 'encrypt'
@@ -1174,6 +1262,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%d", opt.status_fd);
ccparray_put (&ccp, tmpbuf);
+ except[0] = opt.status_fd;
}
ccparray_put (&ccp, "--output");
@@ -1194,6 +1283,8 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
ccparray_put (&ccp, "--recipient");
ccparray_put (&ccp, arg->d);
}
+ if (opt.no_compress)
+ ccparray_put (&ccp, "-z0");
for (arg = opt.gpg_arguments; arg; arg = arg->next)
ccparray_put (&ccp, arg->d);
@@ -1205,7 +1296,9 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
goto leave;
}
- err = gnupg_spawn_process (opt.gpg_program, argv, NULL, NULL,
+ err = gnupg_spawn_process (opt.gpg_program, argv,
+ except[0] == -1? NULL : except,
+ NULL,
(GNUPG_SPAWN_KEEP_STDOUT
| GNUPG_SPAWN_KEEP_STDERR),
&outstream, NULL, NULL, &pid);
@@ -1235,17 +1328,20 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
es_set_binary (outstream);
}
-
+ skipped_open = 0;
for (hdr = scanctrl->flist; hdr; hdr = hdr->next)
{
- err = write_file (outstream, hdr);
+ err = write_file (outstream, hdr, &skipped_open);
if (err)
goto leave;
}
+
err = write_eof_mark (outstream);
if (err)
goto leave;
+ write_progress (1, global_written_files, global_total_files);
+ write_progress (0, global_written_data, global_total_data);
if (pid != (pid_t)(-1))
{
@@ -1266,6 +1362,12 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names,
}
}
+ if (skipped_open)
+ {
+ log_info ("number of skipped files: %u\n", skipped_open);
+ log_error ("exiting with failure status due to previous errors\n");
+ }
+
leave:
if (!err)
{
diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
index 832039b..cdf726d 100644
--- a/tools/gpgtar-extract.c
+++ b/tools/gpgtar-extract.c
@@ -37,7 +37,7 @@
#include "gpgtar.h"
static gpg_error_t
-check_suspicious_name (const char *name)
+check_suspicious_name (const char *name, tarinfo_t info)
{
size_t n;
@@ -47,6 +47,7 @@ check_suspicious_name (const char *name)
{
log_error ("filename '%s' contains a backslash - "
"can't extract on this system\n", name);
+ info->skipped_badname++;
return gpg_error (GPG_ERR_INV_NAME);
}
#endif /*HAVE_DOSISH_SYSTEM*/
@@ -59,6 +60,7 @@ check_suspicious_name (const char *name)
{
log_error ("filename '%s' has suspicious parts - not extracting\n",
name);
+ info->skipped_suspicious++;
return gpg_error (GPG_ERR_INV_NAME);
}
@@ -83,7 +85,7 @@ extract_regular (estream_t stream, const char *dirname,
if (sl->flags == 1)
fname = sl->d;
- err = check_suspicious_name (fname);
+ err = check_suspicious_name (fname, info);
if (err)
goto leave;
@@ -131,8 +133,12 @@ extract_regular (estream_t stream, const char *dirname,
/* Fixme: Set permissions etc. */
leave:
- if (!err && opt.verbose)
- log_info ("extracted '%s'\n", fname);
+ if (!err)
+ {
+ if (opt.verbose)
+ log_info ("extracted '%s'\n", fname);
+ info->nextracted++;
+ }
es_fclose (outfp);
if (err && fname && outfp)
{
@@ -146,7 +152,8 @@ extract_regular (estream_t stream, const char *dirname,
static gpg_error_t
-extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr)
+extract_directory (const char *dirname, tarinfo_t info,
+ tar_header_t hdr, strlist_t exthdr)
{
gpg_error_t err;
const char *name;
@@ -158,7 +165,7 @@ extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr)
if (sl->flags == 1)
name = sl->d;
- err = check_suspicious_name (name);
+ err = check_suspicious_name (name, info);
if (err)
goto leave;
@@ -198,6 +205,9 @@ extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr)
{
*p = 0;
rc = gnupg_mkdir (fname, "-rwx------");
+ if (rc && (gpg_err_code (gpg_error_from_syserror ())
+ == GPG_ERR_EEXIST))
+ rc = 0;
*p = '/';
if (rc)
break;
@@ -228,13 +238,19 @@ extract (estream_t stream, const char *dirname, tarinfo_t info,
if (hdr->typeflag == TF_REGULAR || hdr->typeflag == TF_UNKNOWN)
err = extract_regular (stream, dirname, info, hdr, exthdr);
else if (hdr->typeflag == TF_DIRECTORY)
- err = extract_directory (dirname, hdr, exthdr);
+ err = extract_directory (dirname, info, hdr, exthdr);
else
{
char record[RECORDSIZE];
log_info ("unsupported file type %d for '%s' - skipped\n",
(int)hdr->typeflag, hdr->name);
+ if (hdr->typeflag == TF_SYMLINK)
+ info->skipped_symlinks++;
+ else if (hdr->typeflag == TF_HARDLINK)
+ info->skipped_hardlinks++;
+ else
+ info->skipped_other++;
for (err = 0, n=0; !err && n < hdr->nrecords; n++)
{
err = read_record (stream, record);
@@ -326,7 +342,7 @@ gpgtar_extract (const char *filename, int decrypt)
tarinfo_t tarinfo = &tarinfo_buffer;
pid_t pid = (pid_t)(-1);
char *logfilename = NULL;
-
+ unsigned long long notextracted;
memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer);
@@ -369,6 +385,7 @@ gpgtar_extract (const char *filename, int decrypt)
{
strlist_t arg;
ccparray_t ccp;
+ int except[2] = { -1, -1 };
const char **argv;
ccparray_init (&ccp, 0);
@@ -382,6 +399,7 @@ gpgtar_extract (const char *filename, int decrypt)
snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%d", opt.status_fd);
ccparray_put (&ccp, tmpbuf);
+ except[0] = opt.status_fd;
}
if (opt.with_log)
{
@@ -408,7 +426,9 @@ gpgtar_extract (const char *filename, int decrypt)
goto leave;
}
- err = gnupg_spawn_process (opt.gpg_program, argv, NULL, NULL,
+ err = gnupg_spawn_process (opt.gpg_program, argv,
+ except[0] == -1? NULL : except,
+ NULL,
((filename? 0 : GNUPG_SPAWN_KEEP_STDIN)
| GNUPG_SPAWN_KEEP_STDERR),
NULL, &stream, NULL, &pid);
@@ -473,8 +493,37 @@ gpgtar_extract (const char *filename, int decrypt)
}
}
-
leave:
+ notextracted = tarinfo->skipped_badname;
+ notextracted += tarinfo->skipped_suspicious;
+ notextracted += tarinfo->skipped_symlinks;
+ notextracted += tarinfo->skipped_hardlinks;
+ notextracted += tarinfo->skipped_other;
+ if (opt.status_stream)
+ es_fprintf (opt.status_stream, "[GNUPG:] GPGTAR_EXTRACT"
+ " %llu %llu %lu %lu %lu %lu %lu\n",
+ tarinfo->nextracted,
+ notextracted,
+ tarinfo->skipped_badname,
+ tarinfo->skipped_suspicious,
+ tarinfo->skipped_symlinks,
+ tarinfo->skipped_hardlinks,
+ tarinfo->skipped_other);
+ if (notextracted && !opt.quiet)
+ {
+ log_info ("Number of files not extracted: %llu\n", notextracted);
+ if (tarinfo->skipped_badname)
+ log_info (" invalid name: %lu\n", tarinfo->skipped_badname);
+ if (tarinfo->skipped_suspicious)
+ log_info (" suspicious name: %lu\n", tarinfo->skipped_suspicious);
+ if (tarinfo->skipped_symlinks)
+ log_info (" symlink: %lu\n", tarinfo->skipped_symlinks);
+ if (tarinfo->skipped_hardlinks)
+ log_info (" hardlink: %lu\n", tarinfo->skipped_hardlinks);
+ if (tarinfo->skipped_other)
+ log_info (" other reason: %lu\n", tarinfo->skipped_other);
+ }
+
free_strlist (extheader);
xfree (header);
xfree (dirname);
diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c
index 08ab967..37951d6 100644
--- a/tools/gpgtar-list.c
+++ b/tools/gpgtar-list.c
@@ -468,6 +468,7 @@ gpgtar_list (const char *filename, int decrypt)
{
strlist_t arg;
ccparray_t ccp;
+ int except[2] = { -1, -1 };
const char **argv;
ccparray_init (&ccp, 0);
@@ -481,6 +482,7 @@ gpgtar_list (const char *filename, int decrypt)
snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%d", opt.status_fd);
ccparray_put (&ccp, tmpbuf);
+ except[0] = opt.status_fd;
}
ccparray_put (&ccp, "--output");
ccparray_put (&ccp, "-");
@@ -501,7 +503,9 @@ gpgtar_list (const char *filename, int decrypt)
goto leave;
}
- err = gnupg_spawn_process (opt.gpg_program, argv, NULL, NULL,
+ err = gnupg_spawn_process (opt.gpg_program, argv,
+ except[0] == -1? NULL : except,
+ NULL,
((filename? 0 : GNUPG_SPAWN_KEEP_STDIN)
| GNUPG_SPAWN_KEEP_STDERR),
NULL, &stream, NULL, &pid);
diff --git a/tools/gpgtar.c b/tools/gpgtar.c
index e86ed32..e4ae0ea 100644
--- a/tools/gpgtar.c
+++ b/tools/gpgtar.c
@@ -75,6 +75,7 @@ enum cmd_and_opt_values
oSetFilename,
oNull,
oUtf8Strings,
+ oNoCompress,
oBatch,
oAnswerYes,
@@ -118,6 +119,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
ARGPARSE_s_n (oOpenPGP, "openpgp", "@"),
ARGPARSE_s_n (oCMS, "cms", "@"),
+ ARGPARSE_s_n (oNoCompress, "no-compress", "@"),
ARGPARSE_s_n (oBatch, "batch", "@"),
ARGPARSE_s_n (oAnswerYes, "yes", "@"),
@@ -344,6 +346,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
case oFilesFrom: files_from = pargs->r.ret_str; break;
case oNull: null_names = 1; break;
case oUtf8Strings: opt.utf8strings = 1; break;
+ case oNoCompress: opt.no_compress = 1; break;
case aList:
case aDecrypt:
@@ -453,7 +456,7 @@ main (int argc, char **argv)
gnupg_reopen_std (GPGTAR_NAME);
set_strusage (my_strusage);
- log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX);
+ log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX|GPGRT_LOG_NO_REGISTRY);
/* Make sure that our subsystems are ready. */
i18n_init();
@@ -485,6 +488,36 @@ main (int argc, char **argv)
log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
}
+ /* Set status stream for our own use of --status-fd. The original
+ * status fd is passed verbatim to gpg. */
+ if (opt.status_fd != -1)
+ {
+ int fd = translate_sys2libc_fd_int (opt.status_fd, 1);
+
+ if (!gnupg_fd_valid (fd))
+ log_fatal ("status-fd is invalid: %s\n", strerror (errno));
+
+ if (fd == 1)
+ {
+ opt.status_stream = es_stdout;
+ if (!skip_crypto)
+ log_fatal ("using stdout for the status-fd is not possible\n");
+ }
+ else if (fd == 2)
+ opt.status_stream = es_stderr;
+ else
+ {
+ opt.status_stream = es_fdopen (fd, "w");
+ if (opt.status_stream)
+ es_setvbuf (opt.status_stream, NULL, _IOLBF, 0);
+ }
+ if (!opt.status_stream)
+ {
+ log_fatal ("can't open fd %d for status output: %s\n",
+ fd, strerror (errno));
+ }
+ }
+
if (! opt.gpg_program)
opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG);
@@ -493,17 +526,27 @@ main (int argc, char **argv)
switch (cmd)
{
+ case aDecrypt:
case aList:
if (argc > 1)
usage (1);
- fname = argc ? *argv : NULL;
+ fname = (argc && strcmp (*argv, "-"))? *argv : NULL;
if (opt.filename)
log_info ("note: ignoring option --set-filename\n");
if (files_from)
log_info ("note: ignoring option --files-from\n");
- err = gpgtar_list (fname, !skip_crypto);
- if (err && log_get_errorcount (0) == 0)
- log_error ("listing archive failed: %s\n", gpg_strerror (err));
+ if (cmd == aDecrypt)
+ {
+ err = gpgtar_extract (fname, !skip_crypto);
+ if (err && !log_get_errorcount (0))
+ log_error ("extracting archive failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ err = gpgtar_list (fname, !skip_crypto);
+ if (err && !log_get_errorcount (0))
+ log_error ("listing archive failed: %s\n", gpg_strerror (err));
+ }
break;
case aEncrypt:
@@ -524,24 +567,21 @@ main (int argc, char **argv)
log_error ("creating archive failed: %s\n", gpg_strerror (err));
break;
- case aDecrypt:
- if (argc != 1)
- usage (1);
- if (opt.outfile)
- log_info ("note: ignoring option --output\n");
- if (files_from)
- log_info ("note: ignoring option --files-from\n");
- fname = argc ? *argv : NULL;
- err = gpgtar_extract (fname, !skip_crypto);
- if (err && log_get_errorcount (0) == 0)
- log_error ("extracting archive failed: %s\n", gpg_strerror (err));
- break;
-
default:
log_error (_("invalid command (there is no implicit command)\n"));
+ err = 0;
break;
}
+ if (opt.status_stream)
+ {
+ if (err || log_get_errorcount (0))
+ es_fprintf (opt.status_stream, "[GNUPG:] FAILURE - %u\n",
+ err? err : gpg_error (GPG_ERR_GENERAL));
+ else
+ es_fprintf (opt.status_stream, "[GNUPG:] SUCCESS\n");
+ }
+
return log_get_errorcount (0)? 1:0;
}
diff --git a/tools/gpgtar.h b/tools/gpgtar.h
index 9f3c90f..0b6fa2b 100644
--- a/tools/gpgtar.h
+++ b/tools/gpgtar.h
@@ -33,6 +33,7 @@ struct
int quiet;
int dry_run;
int utf8strings;
+ int no_compress;
const char *gpg_program;
strlist_t gpg_arguments;
const char *outfile;
@@ -45,6 +46,7 @@ struct
int answer_yes;
int answer_no;
int status_fd;
+ estream_t status_stream;
int require_compliance;
int with_log;
} opt;
@@ -53,8 +55,14 @@ struct
/* An info structure to avoid global variables. */
struct tarinfo_s
{
- unsigned long long nblocks; /* Count of processed blocks. */
+ unsigned long long nblocks; /* Count of processed blocks. */
unsigned long long headerblock; /* Number of current header block. */
+ unsigned long long nextracted; /* Number of extracted files. */
+ unsigned long skipped_badname;
+ unsigned long skipped_suspicious;
+ unsigned long skipped_symlinks;
+ unsigned long skipped_hardlinks;
+ unsigned long skipped_other;
};
typedef struct tarinfo_s *tarinfo_t;
diff --git a/tools/gpgtar.w32-manifest.in b/tools/gpgtar.w32-manifest.in
index 62d5937..b949a6b 100644
--- a/tools/gpgtar.w32-manifest.in
+++ b/tools/gpgtar.w32-manifest.in
@@ -15,4 +15,11 @@
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/><!-- Vista -->
</application>
</compatibility>
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker"/>
+ </requestedPrivileges>
+ </security>
+</trustInfo>
</assembly>
diff --git a/tools/wks-util.c b/tools/wks-util.c
index 3044fe2..2660c93 100644
--- a/tools/wks-util.c
+++ b/tools/wks-util.c
@@ -101,7 +101,8 @@ wks_write_status (int no, const char *format, ...)
* updated. C-style escaping is removed from UID. On error ERRNO is
* set and NULL returned. */
static uidinfo_list_t
-append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created)
+append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created,
+ int expired, int revoked)
{
uidinfo_list_t r, sl;
char *plainuid;
@@ -121,6 +122,8 @@ append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created)
sl->created = created;
sl->flags = 0;
sl->mbox = mailbox_from_userid (plainuid);
+ sl->expired = !!expired;
+ sl->revoked = !!revoked;
sl->next = NULL;
if (!*list)
*list = sl;
@@ -150,6 +153,21 @@ free_uidinfo_list (uidinfo_list_t list)
}
+static void
+debug_gpg_invocation (const char *func, const char **argv)
+{
+ int i;
+
+ if (!(opt.debug & DBG_EXTPROG_VALUE))
+ return;
+
+ log_debug ("%s: exec '%s' with", func, opt.gpg_program);
+ for (i=0; argv[i]; i++)
+ log_printf (" '%s'", argv[i]);
+ log_printf ("\n");
+}
+
+
struct get_key_status_parm_s
{
@@ -164,7 +182,8 @@ get_key_status_cb (void *opaque, const char *keyword, char *args)
{
struct get_key_status_parm_s *parm = opaque;
- /*log_debug ("%s: %s\n", keyword, args);*/
+ if (DBG_CRYPTO)
+ log_debug ("%s: %s\n", keyword, args);
if (!strcmp (keyword, "EXPORTED"))
{
parm->count++;
@@ -177,10 +196,11 @@ get_key_status_cb (void *opaque, const char *keyword, char *args)
* mail address ADDRSPEC is included in the key. If EXACT is set the
* returned user id must match Addrspec exactly and not just in the
* addr-spec (mailbox) part. The key is returned as a new memory
- * stream at R_KEY. */
+ * stream at R_KEY. If BINARY is set the returned key is
+ * non-armored. */
gpg_error_t
wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
- int exact)
+ int exact, int binary)
{
gpg_error_t err;
ccparray_t ccp;
@@ -202,8 +222,9 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
}
/* Prefix the key with the MIME content type. */
- es_fputs ("Content-Type: application/pgp-keys\n"
- "\n", key);
+ if (!binary)
+ es_fputs ("Content-Type: application/pgp-keys\n"
+ "\n", key);
filterexp = es_bsprintf ("keep-uid=%s= %s", exact? "uid":"mbox", addrspec);
if (!filterexp)
@@ -223,8 +244,9 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
ccparray_put (&ccp, "--batch");
ccparray_put (&ccp, "--status-fd=2");
ccparray_put (&ccp, "--always-trust");
- ccparray_put (&ccp, "--armor");
- ccparray_put (&ccp, "--export-options=export-minimal");
+ if (!binary)
+ ccparray_put (&ccp, "--armor");
+ ccparray_put (&ccp, "--export-options=export-clean");
ccparray_put (&ccp, "--export-filter");
ccparray_put (&ccp, filterexp);
ccparray_put (&ccp, "--export");
@@ -239,6 +261,7 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
goto leave;
}
parm.fpr = fingerprint;
+ debug_gpg_invocation (__func__, argv);
err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL,
NULL, key,
get_key_status_cb, &parm);
@@ -276,6 +299,22 @@ key_status_cb (void *opaque, const char *keyword, char *args)
}
+/* Parse field 1 and set revoked and expired on return. */
+static void
+set_expired_revoked (const char *string, int *expired, int *revoked)
+{
+ *expired = *revoked = 0;
+ /* Look at letters and stop at the first digit. */
+ for ( ;*string && !digitp (string); string++)
+ {
+ if (*string == 'e')
+ *expired = 1;
+ else if (*string == 'r')
+ *revoked = 1;
+ }
+}
+
+
/* Run gpg on KEY and store the primary fingerprint at R_FPR and the
* list of mailboxes at R_MBOXES. Returns 0 on success; on error NULL
* is stored at R_FPR and R_MBOXES and an error code is returned.
@@ -296,6 +335,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
int lnr;
char *fpr = NULL;
uidinfo_list_t mboxes = NULL;
+ int expired, revoked;
if (r_fpr)
*r_fpr = NULL;
@@ -332,6 +372,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
err = gpg_error_from_syserror ();
goto leave;
}
+ debug_gpg_invocation (__func__, argv);
err = gnupg_exec_tool_stream (opt.gpg_program, argv, key,
NULL, listing,
key_status_cb, NULL);
@@ -343,6 +384,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
es_rewind (listing);
lnr = 0;
+ expired = revoked = 0;
maxlen = 2048; /* Set limit. */
while ((len = es_read_line (listing, &line, &length_of_line, &maxlen)) > 0)
{
@@ -387,12 +429,20 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
err = gpg_error (GPG_ERR_INV_ENGINE);
goto leave;
}
- if (lnr > 1 && !strcmp (fields[0], "pub"))
+ if (!strcmp (fields[0], "pub"))
{
- /* More than one public key. */
- err = gpg_error (GPG_ERR_TOO_MANY);
- goto leave;
+ if (lnr > 1)
+ {
+ /* More than one public key. */
+ err = gpg_error (GPG_ERR_TOO_MANY);
+ goto leave;
+ }
+ if (nfields > 1)
+ set_expired_revoked (fields[1], &expired, &revoked);
+ else
+ expired = revoked = 0;
}
+
if (!strcmp (fields[0], "sub") || !strcmp (fields[0], "ssb"))
break; /* We can stop parsing here. */
@@ -407,8 +457,13 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
}
else if (!strcmp (fields[0], "uid") && nfields > 9)
{
+ int uidexpired, uidrevoked;
+
+ set_expired_revoked (fields[1], &uidexpired, &uidrevoked);
if (!append_to_uidinfo_list (&mboxes, fields[9],
- parse_timestamp (fields[5], NULL)))
+ parse_timestamp (fields[5], NULL),
+ expired || uidexpired,
+ revoked || uidrevoked))
{
err = gpg_error_from_syserror ();
goto leave;
@@ -510,6 +565,7 @@ wks_filter_uid (estream_t *r_newkey, estream_t key, const char *uid,
err = gpg_error_from_syserror ();
goto leave;
}
+ debug_gpg_invocation (__func__, argv);
err = gnupg_exec_tool_stream (opt.gpg_program, argv, key,
NULL, newkey,
key_status_cb, NULL);
@@ -531,6 +587,124 @@ wks_filter_uid (estream_t *r_newkey, estream_t key, const char *uid,
}
+/* Put the ascii-armor around KEY and return that as a new estream
+ * object at R_NEWKEY. Caller must make sure that KEY has been seeked
+ * to the right position (usually by calling es_rewind). The
+ * resulting NEWKEY has already been rewound. If PREFIX is not NULL,
+ * its content is written to NEWKEY propr to the armor; this may be
+ * used for MIME headers. */
+gpg_error_t
+wks_armor_key (estream_t *r_newkey, estream_t key, const char *prefix)
+{
+ gpg_error_t err;
+ estream_t newkey;
+ struct b64state b64state;
+ char buffer[4096];
+ size_t nread;
+
+ *r_newkey = NULL;
+
+ newkey = es_fopenmem (0, "w+b");
+ if (!newkey)
+ {
+ err = gpg_error_from_syserror ();
+ return err;
+ }
+
+ if (prefix)
+ es_fputs (prefix, newkey);
+
+ err = b64enc_start_es (&b64state, newkey, "PGP PUBLIC KEY BLOCK");
+ if (err)
+ goto leave;
+
+ do
+ {
+ nread = es_fread (buffer, 1, sizeof buffer, key);
+ if (!nread)
+ break;
+ err = b64enc_write (&b64state, buffer, nread);
+ if (err)
+ goto leave;
+ }
+ while (!es_feof (key) && !es_ferror (key));
+ if (!es_feof (key) || es_ferror (key))
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ err = b64enc_finish (&b64state);
+ if (err)
+ goto leave;
+
+ es_rewind (newkey);
+ *r_newkey = newkey;
+ newkey = NULL;
+
+ leave:
+ es_fclose (newkey);
+ return err;
+}
+
+
+/* Run gpg to export the revocation certificates for ADDRSPEC. Add
+ * them to KEY which is expected to be non-armored keyblock. */
+gpg_error_t
+wks_find_add_revocs (estream_t key, const char *addrspec)
+{
+ gpg_error_t err;
+ ccparray_t ccp;
+ const char **argv = NULL;
+ char *filterexp = NULL;
+
+ filterexp = es_bsprintf ("select=mbox= %s", addrspec);
+ if (!filterexp)
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ ccparray_init (&ccp, 0);
+
+ ccparray_put (&ccp, "--no-options");
+ if (opt.verbose < 2)
+ ccparray_put (&ccp, "--quiet");
+ else
+ ccparray_put (&ccp, "--verbose");
+ ccparray_put (&ccp, "--batch");
+ ccparray_put (&ccp, "--status-fd=2");
+ ccparray_put (&ccp, "--export-options=export-revocs");
+ ccparray_put (&ccp, "--export-filter");
+ ccparray_put (&ccp, filterexp);
+ ccparray_put (&ccp, "--export");
+ ccparray_put (&ccp, addrspec);
+
+ ccparray_put (&ccp, NULL);
+ argv = ccparray_get (&ccp, NULL);
+ if (!argv)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ debug_gpg_invocation (__func__, argv);
+ err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL,
+ NULL, key,
+ key_status_cb, NULL);
+ if (err)
+ {
+ log_error ("exporting revocs failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ leave:
+ xfree (filterexp);
+ xfree (argv);
+ return err;
+}
+
+
/* Helper to write mail to the output(s). */
gpg_error_t
wks_send_mime (mime_maker_t mime)
@@ -1103,7 +1277,7 @@ wks_cmd_install_key (const char *fname, const char *userid)
{
/* FNAME looks like a fingerprint. Get the key from the
* standard keyring. */
- err = wks_get_key (&fp, fname, addrspec, 0);
+ err = wks_get_key (&fp, fname, addrspec, 0, 1);
if (err)
{
log_error ("error getting key '%s' (uid='%s'): %s\n",
@@ -1140,6 +1314,12 @@ wks_cmd_install_key (const char *fname, const char *userid)
continue; /* Should not happen anyway. */
if (ascii_strcasecmp (uid->mbox, addrspec))
continue; /* Not the requested addrspec. */
+ if (uid->expired)
+ {
+ if (opt.verbose)
+ log_info ("ignoring expired user id '%s'\n", uid->uid);
+ continue;
+ }
any = 1;
if (uid->created > thistime)
{
@@ -1175,6 +1355,24 @@ wks_cmd_install_key (const char *fname, const char *userid)
fp = fp2;
}
+ if (opt.add_revocs)
+ {
+ if (es_fseek (fp, 0, SEEK_END))
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error seeking stream: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+ err = wks_find_add_revocs (fp, addrspec);
+ if (err)
+ {
+ log_error ("error finding revocations for '%s': %s\n",
+ addrspec, gpg_strerror (err));
+ goto leave;
+ }
+ es_rewind (fp);
+ }
+
err = wks_install_key_core (fp, addrspec);
if (!opt.quiet)
log_info ("key %s published for '%s'\n", fpr, addrspec);