aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/applygnupgdefaults2
-rw-r--r--tools/gpg-wks-server.c195
-rw-r--r--tools/gpgconf-comp.c29
-rw-r--r--tools/gpgconf.c112
-rw-r--r--tools/gpgconf.h4
5 files changed, 311 insertions, 31 deletions
diff --git a/tools/applygnupgdefaults b/tools/applygnupgdefaults
index 54365ce34..316509faf 100755
--- a/tools/applygnupgdefaults
+++ b/tools/applygnupgdefaults
@@ -1,5 +1,5 @@
#!/bin/sh
-# Apply defaults from /etc/gnupg/gpg.conf to all users -*- sh -*-
+# Apply defaults from /etc/gnupg/gpgconf.conf to all users -*- sh -*-
#
# Copyright 2007 Free Software Foundation, Inc.
#
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index 7e3f05017..0b1d64261 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -66,11 +66,14 @@ enum cmd_and_opt_values
aInstallKey,
aRevokeKey,
aRemoveKey,
+ aCheck,
oGpgProgram,
oSend,
oFrom,
oHeader,
+ oWithDir,
+ oWithFile,
oDummy
};
@@ -86,12 +89,15 @@ static ARGPARSE_OPTS opts[] = {
("run regular jobs")),
ARGPARSE_c (aListDomains, "list-domains",
("list configured domains")),
+ ARGPARSE_c (aCheck, "check",
+ ("check whether a key is installed")),
+ ARGPARSE_c (aCheck, "check-key", "@"),
ARGPARSE_c (aInstallKey, "install-key",
- "|FILE|install a key from FILE into the WKD"),
+ "install a key from FILE into the WKD"),
ARGPARSE_c (aRemoveKey, "remove-key",
- "|ADDR|remove the key ADDR from the WKD"),
+ "remove a key from the WKD"),
ARGPARSE_c (aRevokeKey, "revoke-key",
- "|ADDR|mark the key ADDR in the WKD as revoked"),
+ "mark a key as revoked"),
ARGPARSE_group (301, ("@\nOptions:\n ")),
@@ -104,6 +110,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oFrom, "from", "|ADDR|use ADDR as the default sender"),
ARGPARSE_s_s (oHeader, "header" ,
"|NAME=VALUE|add \"NAME: VALUE\" as header to all mails"),
+ ARGPARSE_s_n (oWithDir, "with-dir", "@"),
+ ARGPARSE_s_n (oWithFile, "with-file", "@"),
ARGPARSE_end ()
};
@@ -132,6 +140,13 @@ struct server_ctx_s
};
typedef struct server_ctx_s *server_ctx_t;
+
+/* Flag for --with-dir. */
+static int opt_with_dir;
+/* Flag for --with-file. */
+static int opt_with_file;
+
+
/* Prototypes. */
static gpg_error_t get_domain_list (strlist_t *r_list);
@@ -142,6 +157,7 @@ static gpg_error_t command_list_domains (void);
static gpg_error_t command_install_key (const char *fname);
static gpg_error_t command_remove_key (const char *mailaddr);
static gpg_error_t command_revoke_key (const char *mailaddr);
+static gpg_error_t command_check_key (const char *mailaddr);
static gpg_error_t command_cron (void);
@@ -220,10 +236,17 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
case oOutput:
opt.output = pargs->r.ret_str;
break;
+ case oWithDir:
+ opt_with_dir = 1;
+ break;
+ case oWithFile:
+ opt_with_file = 1;
+ break;
case aReceive:
case aCron:
case aListDomains:
+ case aCheck:
case aInstallKey:
case aRemoveKey:
case aRevokeKey:
@@ -243,7 +266,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
int
main (int argc, char **argv)
{
- gpg_error_t err;
+ gpg_error_t err, firsterr;
ARGPARSE_ARGS pargs;
enum cmd_and_opt_values cmd;
@@ -360,16 +383,29 @@ main (int argc, char **argv)
case aRemoveKey:
if (argc != 1)
- wrong_args ("--remove-key MAILADDR");
+ wrong_args ("--remove-key USER-ID");
err = command_remove_key (*argv);
break;
case aRevokeKey:
if (argc != 1)
- wrong_args ("--revoke-key MAILADDR");
+ wrong_args ("--revoke-key USER-ID");
err = command_revoke_key (*argv);
break;
+ case aCheck:
+ if (!argc)
+ wrong_args ("--check USER-IDs");
+ firsterr = 0;
+ for (; argc; argc--, argv++)
+ {
+ err = command_check_key (*argv);
+ if (!firsterr)
+ firsterr = err;
+ }
+ err = firsterr;
+ break;
+
default:
usage (1);
err = gpg_error (GPG_ERR_BUG);
@@ -1776,7 +1812,11 @@ command_list_domains (void)
domain = strrchr (sl->d, '/');
log_assert (domain);
domain++;
- es_printf ("%s\n", domain);
+ if (opt_with_dir)
+ es_printf ("%s %s\n", domain, sl->d);
+ else
+ es_printf ("%s\n", domain);
+
/* Check that the required directories are there. */
for (i=0; i < DIM (requireddirs); i++)
@@ -1900,12 +1940,140 @@ command_install_key (const char *fname)
}
-/* Remove the key with mail address MAILADDR. */
+/* Return the filename and optioanlly the addrspec for USERID at
+ * R_FNAME and R_ADDRSPEC. R_ADDRSPEC might also be set on error. */
static gpg_error_t
-command_remove_key (const char *mailaddr)
+fname_from_userid (const char *userid, char **r_fname, char **r_addrspec)
{
- (void)mailaddr;
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ gpg_error_t err;
+ char *addrspec = NULL;
+ const char *domain;
+ char *hash = NULL;
+ const char *s;
+ char shaxbuf[32]; /* Used for SHA-1 and SHA-256 */
+
+ *r_fname = NULL;
+ if (r_addrspec)
+ *r_addrspec = NULL;
+
+ addrspec = mailbox_from_userid (userid);
+ if (!addrspec)
+ {
+ if (opt.verbose)
+ log_info ("\"%s\" is not a proper mail address\n", userid);
+ err = gpg_error (GPG_ERR_INV_USER_ID);
+ goto leave;
+ }
+
+ domain = strchr (addrspec, '@');
+ log_assert (domain);
+ domain++;
+
+ /* Hash user ID and create filename. */
+ s = strchr (addrspec, '@');
+ log_assert (s);
+ gcry_md_hash_buffer (GCRY_MD_SHA1, shaxbuf, addrspec, s - addrspec);
+ hash = zb32_encode (shaxbuf, 8*20);
+ if (!hash)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ *r_fname = make_filename_try (opt.directory, domain, "hu", hash, NULL);
+ if (!*r_fname)
+ err = gpg_error_from_syserror ();
+ else
+ err = 0;
+
+ leave:
+ if (r_addrspec && addrspec)
+ *r_addrspec = addrspec;
+ else
+ xfree (addrspec);
+ xfree (hash);
+ return err;
+}
+
+
+/* Check whether the key with USER_ID is installed. */
+static gpg_error_t
+command_check_key (const char *userid)
+{
+ gpg_error_t err;
+ char *addrspec = NULL;
+ char *fname = NULL;
+
+ err = fname_from_userid (userid, &fname, &addrspec);
+ if (err)
+ goto leave;
+
+ if (access (fname, R_OK))
+ {
+ err = gpg_error_from_syserror ();
+ if (opt_with_file)
+ es_printf ("%s n %s\n", addrspec, fname);
+ if (gpg_err_code (err) == GPG_ERR_ENOENT)
+ {
+ if (!opt.quiet)
+ log_info ("key for '%s' is NOT installed\n", addrspec);
+ log_inc_errorcount ();
+ err = 0;
+ }
+ else
+ log_error ("error stating '%s': %s\n", fname, gpg_strerror (err));
+ goto leave;
+ }
+
+ if (opt_with_file)
+ es_printf ("%s i %s\n", addrspec, fname);
+
+ if (opt.verbose)
+ log_info ("key for '%s' is installed\n", addrspec);
+ err = 0;
+
+ leave:
+ xfree (fname);
+ xfree (addrspec);
+ return err;
+}
+
+
+/* Remove the key with mail address in USERID. */
+static gpg_error_t
+command_remove_key (const char *userid)
+{
+ gpg_error_t err;
+ char *addrspec = NULL;
+ char *fname = NULL;
+
+ err = fname_from_userid (userid, &fname, &addrspec);
+ if (err)
+ goto leave;
+
+ if (gnupg_remove (fname))
+ {
+ err = gpg_error_from_syserror ();
+ if (gpg_err_code (err) == GPG_ERR_ENOENT)
+ {
+ if (!opt.quiet)
+ log_info ("key for '%s' is not installed\n", addrspec);
+ log_inc_errorcount ();
+ err = 0;
+ }
+ else
+ log_error ("error removing '%s': %s\n", fname, gpg_strerror (err));
+ goto leave;
+ }
+
+ if (opt.verbose)
+ log_info ("key for '%s' removed\n", addrspec);
+ err = 0;
+
+ leave:
+ xfree (fname);
+ xfree (addrspec);
+ return err;
}
@@ -1913,6 +2081,7 @@ command_remove_key (const char *mailaddr)
static gpg_error_t
command_revoke_key (const char *mailaddr)
{
- (void)mailaddr;
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ /* Remove should be different from removing but we have not yet
+ * defined a suitable way to do this. */
+ return command_remove_key (mailaddr);
}
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index c799143cd..099f43952 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -48,6 +48,7 @@
#include "../common/i18n.h"
#include "../common/exechelp.h"
#include "../common/sysutils.h"
+#include "../common/status.h"
#include "../common/gc-opt-flags.h"
#include "gpgconf.h"
@@ -99,7 +100,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
{
log_printf (NULL);
log_printf ("fatal error (exit status %i)\n", status);
- exit (status);
+ gpgconf_failure (gpg_error_from_errno (errnum));
}
}
@@ -1310,7 +1311,7 @@ gc_component_launch (int component)
{
es_fputs (_("Component not suitable for launching"), es_stderr);
es_putc ('\n', es_stderr);
- exit (1);
+ gpgconf_failure (0);
}
pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
@@ -3757,6 +3758,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{
gc_error (0, 0, "missing rule at '%s', line %d", fname, lineno);
result = -1;
+ gpgconf_write_status (STATUS_WARNING,
+ "gpgconf.conf %d file '%s' line %d "
+ "missing rule",
+ GPG_ERR_SYNTAX, fname, lineno);
continue;
}
*p++ = 0;
@@ -3786,6 +3791,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{
gc_error (0, 0, "missing component at '%s', line %d",
fname, lineno);
+ gpgconf_write_status (STATUS_WARNING,
+ "gpgconf.conf %d file '%s' line %d "
+ " missing component",
+ GPG_ERR_NO_NAME, fname, lineno);
result = -1;
continue;
}
@@ -3797,6 +3806,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{
gc_error (0, 0, "unknown component at '%s', line %d",
fname, lineno);
+ gpgconf_write_status (STATUS_WARNING,
+ "gpgconf.conf %d file '%s' line %d "
+ "unknown component",
+ GPG_ERR_UNKNOWN_NAME, fname, lineno);
result = -1;
}
@@ -3809,6 +3822,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{
gc_error (0, 0, "missing option at '%s', line %d",
fname, lineno);
+ gpgconf_write_status (STATUS_WARNING,
+ "gpgconf.conf %d file '%s' line %d "
+ "missing option",
+ GPG_ERR_INV_NAME, fname, lineno);
result = -1;
continue;
}
@@ -3821,6 +3838,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{
gc_error (0, 0, "unknown option at '%s', line %d",
fname, lineno);
+ gpgconf_write_status (STATUS_WARNING,
+ "gpgconf.conf %d file '%s' line %d "
+ "unknown option",
+ GPG_ERR_UNKNOWN_OPTION, fname, lineno);
result = -1;
}
}
@@ -3837,6 +3858,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{
gc_error (0, 0, "syntax error in rule at '%s', line %d",
fname, lineno);
+ gpgconf_write_status (STATUS_WARNING,
+ "gpgconf.conf %d file '%s' line %d "
+ "syntax error in rule",
+ GPG_ERR_SYNTAX, fname, lineno);
result = -1;
continue;
}
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index 09b2a76e9..59085d8b5 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -29,6 +29,7 @@
#include "../common/i18n.h"
#include "../common/sysutils.h"
#include "../common/init.h"
+#include "../common/status.h"
/* Constants to identify the commands and options. */
@@ -45,6 +46,7 @@ enum cmd_and_opt_values
oNoVerbose = 500,
oHomedir,
oBuilddir,
+ oStatusFD,
aListComponents,
aCheckPrograms,
@@ -100,6 +102,7 @@ static ARGPARSE_OPTS opts[] =
{ 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, "@" },
@@ -110,6 +113,11 @@ static ARGPARSE_OPTS opts[] =
};
+/* The stream to output the status information. Status Output is disabled if
+ * this is NULL. */
+static estream_t statusfp;
+
+
/* Print usage information and provide strings for help. */
static const char *
my_strusage( int level )
@@ -159,6 +167,60 @@ get_outfp (estream_t *fp)
}
+/* Set the status FD. */
+static void
+set_status_fd (int fd)
+{
+ static int last_fd = -1;
+
+ if (fd != -1 && last_fd == fd)
+ return;
+
+ if (statusfp && statusfp != es_stdout && statusfp != es_stderr)
+ es_fclose (statusfp);
+ statusfp = NULL;
+ if (fd == -1)
+ return;
+
+ if (fd == 1)
+ statusfp = es_stdout;
+ else if (fd == 2)
+ statusfp = es_stderr;
+ else
+ statusfp = es_fdopen (fd, "w");
+ if (!statusfp)
+ {
+ log_fatal ("can't open fd %d for status output: %s\n",
+ fd, gpg_strerror (gpg_error_from_syserror ()));
+ }
+ last_fd = fd;
+}
+
+
+/* Write a status line with code NO followed by the output of the
+ * printf style FORMAT. The caller needs to make sure that LFs and
+ * CRs are not printed. */
+void
+gpgconf_write_status (int no, const char *format, ...)
+{
+ va_list arg_ptr;
+
+ if (!statusfp)
+ return; /* Not enabled. */
+
+ es_fputs ("[GNUPG:] ", statusfp);
+ es_fputs (get_status_string (no), statusfp);
+ if (format)
+ {
+ es_putc (' ', statusfp);
+ va_start (arg_ptr, format);
+ es_vfprintf (statusfp, format, arg_ptr);
+ va_end (arg_ptr);
+ }
+ es_putc ('\n', statusfp);
+}
+
+
static void
list_dirs (estream_t fp, char **names)
{
@@ -493,6 +555,9 @@ main (int argc, char **argv)
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oBuilddir: gnupg_set_builddir (pargs.r.ret_str); break;
case oNull: opt.null = 1; break;
+ case oStatusFD:
+ set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
+ break;
case aListDirs:
case aListComponents:
@@ -518,7 +583,7 @@ main (int argc, char **argv)
}
if (log_get_errorcount (0))
- exit (2);
+ gpgconf_failure (GPG_ERR_USER_2);
/* Print a warning if an argument looks like an option. */
if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
@@ -554,7 +619,7 @@ main (int argc, char **argv)
es_putc ('\n', es_stderr);
es_fputs (_("Need one component argument"), es_stderr);
es_putc ('\n', es_stderr);
- exit (2);
+ gpgconf_failure (GPG_ERR_USER_2);
}
else
{
@@ -563,7 +628,7 @@ main (int argc, char **argv)
{
es_fputs (_("Component not found"), es_stderr);
es_putc ('\n', es_stderr);
- exit (1);
+ gpgconf_failure (0);
}
if (cmd == aCheckOptions)
gc_component_check_options (idx, get_outfp (&outfp), NULL);
@@ -571,7 +636,7 @@ main (int argc, char **argv)
{
gc_component_retrieve_options (idx);
if (gc_process_gpgconf_conf (NULL, 1, 0, NULL))
- exit (1);
+ gpgconf_failure (0);
if (cmd == aListOptions)
gc_component_list_options (idx, get_outfp (&outfp));
else if (cmd == aChangeOptions)
@@ -589,14 +654,14 @@ main (int argc, char **argv)
es_putc ('\n', es_stderr);
es_fputs (_("Need one component argument"), es_stderr);
es_putc ('\n', es_stderr);
- exit (2);
+ gpgconf_failure (GPG_ERR_USER_2);
}
else if (!strcmp (fname, "all"))
{
if (cmd == aLaunch)
{
if (gc_component_launch (-1))
- exit (1);
+ gpgconf_failure (0);
}
else
{
@@ -613,12 +678,12 @@ main (int argc, char **argv)
{
es_fputs (_("Component not found"), es_stderr);
es_putc ('\n', es_stderr);
- exit (1);
+ gpgconf_failure (0);
}
else if (cmd == aLaunch)
{
if (gc_component_launch (idx))
- exit (1);
+ gpgconf_failure (0);
}
else
{
@@ -646,7 +711,7 @@ main (int argc, char **argv)
{
es_fputs (_("Component not found"), es_stderr);
es_putc ('\n', es_stderr);
- exit (1);
+ gpgconf_failure (0);
}
else
{
@@ -657,12 +722,12 @@ main (int argc, char **argv)
case aListConfig:
if (gc_process_gpgconf_conf (fname, 0, 0, get_outfp (&outfp)))
- exit (1);
+ gpgconf_failure (0);
break;
case aCheckConfig:
if (gc_process_gpgconf_conf (fname, 0, 0, NULL))
- exit (1);
+ gpgconf_failure (0);
break;
case aApplyDefaults:
@@ -672,17 +737,17 @@ main (int argc, char **argv)
es_putc ('\n', es_stderr);
es_fputs (_("No argument allowed"), es_stderr);
es_putc ('\n', es_stderr);
- exit (2);
+ gpgconf_failure (GPG_ERR_USER_2);
}
gc_component_retrieve_options (-1);
if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
- exit (1);
+ gpgconf_failure (0);
break;
case aApplyProfile:
gc_component_retrieve_options (-1);
if (gc_apply_profile (fname))
- exit (1);
+ gpgconf_failure (0);
break;
case aListDirs:
@@ -697,7 +762,7 @@ main (int argc, char **argv)
{
es_fprintf (es_stderr, "usage: %s --query-swdb NAME [VERSION]\n",
GPGCONF_NAME);
- exit (2);
+ gpgconf_failure (GPG_ERR_USER_2);
}
get_outfp (&outfp);
query_swdb (outfp, fname, argc > 1? argv[1] : NULL);
@@ -804,5 +869,22 @@ main (int argc, char **argv)
if (es_fclose (outfp))
gc_error (1, errno, "error closing '%s'", opt.outfile);
+
+ if (log_get_errorcount (0))
+ gpgconf_failure (0);
+ else
+ gpgconf_write_status (STATUS_SUCCESS, NULL);
return 0;
}
+
+
+void
+gpgconf_failure (gpg_error_t err)
+{
+ if (!err)
+ err = gpg_error (GPG_ERR_GENERAL);
+ gpgconf_write_status
+ (STATUS_FAILURE, "- %u",
+ gpg_err_code (err) == GPG_ERR_USER_2? GPG_ERR_EINVAL : err);
+ exit (gpg_err_code (err) == GPG_ERR_USER_2? 2 : 1);
+}
diff --git a/tools/gpgconf.h b/tools/gpgconf.h
index d6d7627aa..8a061ef68 100644
--- a/tools/gpgconf.h
+++ b/tools/gpgconf.h
@@ -36,6 +36,10 @@ struct
} opt;
+/*-- gpgconf.c --*/
+void gpgconf_write_status (int no, const char *format,
+ ...) GPGRT_ATTR_PRINTF(2,3);
+void gpgconf_failure (gpg_error_t err) GPGRT_ATTR_NORETURN;
/*-- gpgconf-comp.c --*/