aboutsummaryrefslogtreecommitdiffstats
path: root/dirmngr
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2014-03-11 15:19:41 +0000
committerWerner Koch <[email protected]>2014-03-11 15:30:36 +0000
commita3dee2889106fcab112c1c96b32e04d8154875e7 (patch)
tree01f9d12c29df3e3ae6a5db1183e56137f112adfc /dirmngr
parentdirmngr: Make Assuan output of keyblocks easier readable (diff)
downloadgnupg-a3dee2889106fcab112c1c96b32e04d8154875e7.tar.gz
gnupg-a3dee2889106fcab112c1c96b32e04d8154875e7.zip
dirmngr: Add command option to mark hosts as dead or alive.
* dirmngr/server.c (cmd_killdirmngr): Factor some code out to ... (check_owner_permission): here. (cmd_keyserver): Add options --dead and --alive. * dirmngr/ks-engine-hkp.c (host_in_pool_p): New. (ks_hkp_mark_host): New. -- Also removed the warning that the widnows part has not yet been done. AFAICS, the current mingw supports the all used socket functions.
Diffstat (limited to 'dirmngr')
-rw-r--r--dirmngr/ks-engine-hkp.c88
-rw-r--r--dirmngr/ks-engine.h1
-rw-r--r--dirmngr/server.c95
3 files changed, 164 insertions, 20 deletions
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index 5d68cce3f..40759304d 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -18,7 +18,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#warning fixme Windows part not yet done
#include <config.h>
#include <stdio.h>
@@ -153,6 +152,19 @@ sort_hostpool (const void *xa, const void *xb)
}
+/* Return true if the host with the hosttable index TBLIDX is in POOL. */
+static int
+host_in_pool_p (int *pool, int tblidx)
+{
+ int i, pidx;
+
+ for (i=0; (pidx = pool[i]) != -1; i++)
+ if (pidx == tblidx && hosttable[pidx])
+ return 1;
+ return 0;
+}
+
+
/* Select a random host. Consult TABLE which indices into the global
hosttable. Returns index into TABLE or -1 if no host could be
selected. */
@@ -374,6 +386,80 @@ mark_host_dead (const char *name)
}
+/* Mark a host in the hosttable as dead or - if ALIVE is true - as
+ alive. If the host NAME does not exist a warning status message is
+ printed. */
+gpg_error_t
+ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
+{
+ gpg_error_t err = 0;
+ hostinfo_t hi, hi2;
+ int idx, idx2, idx3, n;
+
+ if (!name || !*name || !strcmp (name, "localhost"))
+ return 0;
+
+ idx = find_hostinfo (name);
+ if (idx == -1)
+ return gpg_error (GPG_ERR_NOT_FOUND);
+
+ hi = hosttable[idx];
+ if (alive && hi->dead)
+ {
+ hi->dead = 0;
+ err = ks_printf_help (ctrl, "marking '%s' as alive", name);
+ }
+ else if (!alive && !hi->dead)
+ {
+ hi->dead = 1;
+ err = ks_printf_help (ctrl, "marking '%s' as dead", name);
+ }
+
+ /* If the host is a pool mark all member hosts. */
+ if (!err && hi->pool)
+ {
+ for (idx2=0; !err && (n=hi->pool[idx2]) != -1; idx2++)
+ {
+ assert (n >= 0 && n < hosttable_size);
+
+ if (!alive)
+ {
+ /* Do not mark a host from a pool dead if it is also a
+ member in another pool. */
+ for (idx3=0; idx3 < hosttable_size; idx3++)
+ {
+ if (hosttable[idx3] && hosttable[idx3]
+ && hosttable[idx3]->pool
+ && idx3 != idx
+ && host_in_pool_p (hosttable[idx3]->pool, n))
+ break;
+ }
+ if (idx3 < hosttable_size)
+ continue; /* Host is also a member of another pool. */
+ }
+
+ hi2 = hosttable[n];
+ if (!hi2)
+ ;
+ else if (alive && hi2->dead)
+ {
+ hi2->dead = 0;
+ err = ks_printf_help (ctrl, "marking '%s' as alive",
+ hi2->name);
+ }
+ else if (!alive && !hi2->dead)
+ {
+ hi2->dead = 1;
+ err = ks_printf_help (ctrl, "marking '%s' as dead",
+ hi2->name);
+ }
+ }
+ }
+
+ return err;
+}
+
+
/* Debug function to print the entire hosttable. */
gpg_error_t
ks_hkp_print_hosttable (ctrl_t ctrl)
diff --git a/dirmngr/ks-engine.h b/dirmngr/ks-engine.h
index 01a295ca9..a2faa751a 100644
--- a/dirmngr/ks-engine.h
+++ b/dirmngr/ks-engine.h
@@ -30,6 +30,7 @@ gpg_error_t ks_printf_help (ctrl_t ctrl, const char *format,
/*-- ks-engine-hkp.c --*/
gpg_error_t ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri);
+gpg_error_t ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive);
gpg_error_t ks_hkp_print_hosttable (ctrl_t ctrl);
gpg_error_t ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri);
gpg_error_t ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
diff --git a/dirmngr/server.c b/dirmngr/server.c
index d2682eaaa..fb619dfcc 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -298,6 +298,32 @@ skip_options (char *line)
}
+/* Return an error if the assuan context does not belong to teh owner
+ of the process or to root. On error FAILTEXT is set as Assuan
+ error string. */
+static gpg_error_t
+check_owner_permission (assuan_context_t ctx, const char *failtext)
+{
+#ifdef HAVE_W32_SYSTEM
+ /* Under Windows the dirmngr is always run under the control of the
+ user. */
+ (void)ctx;
+ (void)failtext;
+#else
+ gpg_err_code_t ec;
+ assuan_peercred_t cred;
+
+ ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
+ if (!ec && cred->uid && cred->uid != getuid ())
+ ec = GPG_ERR_EPERM;
+ if (ec)
+ return set_error (ec, failtext);
+#endif
+ return 0;
+}
+
+
+
/* Common code for get_cert_local and get_issuer_cert_local. */
static ksba_cert_t
do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
@@ -1392,10 +1418,16 @@ cmd_validate (assuan_context_t ctx, char *line)
static const char hlp_keyserver[] =
- "KEYSERVER [--clear|--help] [<uri>]\n"
+ "KEYSERVER [<options>] [<uri>|<host>]\n"
+ "Options are:\n"
+ " --help\n"
+ " --clear Remove all configured keyservers\n"
+ " --resolve Resolve HKP host names and rotate\n"
+ " --hosttable Print table of known hosts and pools\n"
+ " --dead Mark <host> as dead\n"
+ " --alive Mark <host> as alive\n"
"\n"
"If called without arguments list all configured keyserver URLs.\n"
- "If called with option \"--clear\" remove all configured keyservers\n"
"If called with an URI add this as keyserver. Note that keyservers\n"
"are configured on a per-session base. A default keyserver may already be\n"
"present, thus the \"--clear\" option must be used to get full control.\n"
@@ -1408,6 +1440,7 @@ cmd_keyserver (assuan_context_t ctx, char *line)
ctrl_t ctrl = assuan_get_pointer (ctx);
gpg_error_t err = 0;
int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
+ int dead_flag, alive_flag;
uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
is always initialized. */
@@ -1415,6 +1448,8 @@ cmd_keyserver (assuan_context_t ctx, char *line)
help_flag = has_option (line, "--help");
resolve_flag = has_option (line, "--resolve");
host_flag = has_option (line, "--hosttable");
+ dead_flag = has_option (line, "--dead");
+ alive_flag = has_option (line, "--alive");
line = skip_options (line);
add_flag = !!*line;
@@ -1431,13 +1466,37 @@ cmd_keyserver (assuan_context_t ctx, char *line)
goto leave;
}
+ if (alive_flag && dead_flag)
+ {
+ err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
+ goto leave;
+ }
+ if (dead_flag)
+ {
+ err = check_owner_permission (ctx, "no permission to use --dead");
+ if (err)
+ goto leave;
+ }
+ if (alive_flag || dead_flag)
+ {
+ if (!*line)
+ {
+ err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
+ goto leave;
+ }
+
+ err = ks_hkp_mark_host (ctrl, line, alive_flag);
+ if (err)
+ goto leave;
+ }
+
if (host_flag)
{
err = ks_hkp_print_hosttable (ctrl);
if (err)
goto leave;
}
- if (resolve_flag || host_flag)
+ if (resolve_flag || host_flag || alive_flag || dead_flag)
goto leave;
if (add_flag)
@@ -1746,30 +1805,28 @@ static gpg_error_t
cmd_killdirmngr (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;
(void)line;
if (opt.system_daemon)
{
if (opt.system_service)
- return set_error (GPG_ERR_NOT_SUPPORTED,
- "can't do that whilst running as system service");
-#ifndef HAVE_W32_SYSTEM
- {
- gpg_err_code_t ec;
- assuan_peercred_t cred;
-
- ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
- if (!ec && cred->uid)
- ec = GPG_ERR_EPERM; /* Only root may terminate. */
- if (ec)
- return set_error (ec, "no permission to kill this process");
- }
-#endif
+ err = set_error (GPG_ERR_NOT_SUPPORTED,
+ "can't do that whilst running as system service");
+ else
+ err = check_owner_permission (ctx,
+ "no permission to kill this process");
}
+ else
+ err = 0;
- ctrl->server_local->stopme = 1;
- return gpg_error (GPG_ERR_EOF);
+ if (!err)
+ {
+ ctrl->server_local->stopme = 1;
+ err = gpg_error (GPG_ERR_EOF);
+ }
+ return err;
}