mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-17 14:07:03 +01:00
wks: Add special mode to --install-key.
* tools/gpg-wks-client.c (get_key_status_parm_s) (get_key_status_cb, get_key): Move to ... * tools/wks-util.c: ...here. (get_key): Rename to wks_get_key. * tools/gpg-wks-server.c: Include userids.h. (command_install_key): Allow use of a fingerprint. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
ee474856ec
commit
685a5e1558
17
doc/wks.texi
17
doc/wks.texi
@ -224,7 +224,9 @@ the process returns failure; to suppress the diagnostic, use option
|
||||
|
||||
The command @option{--install-key} manually installs a key into the
|
||||
WKD. The arguments are a file with the keyblock and the user-id to
|
||||
install.
|
||||
install. If the first argument resembles a fingerprint the key is
|
||||
taken from the current keyring; to force the use of a file, prefix the
|
||||
first argument with "./".
|
||||
|
||||
The command @option{--remove-key} uninstalls a key from the WKD. The
|
||||
process returns success in this case; to also print a diagnostic, use
|
||||
@ -330,7 +332,7 @@ the submission address:
|
||||
|
||||
@example
|
||||
$ gpg --batch --passphrase '' --quick-gen-key key-submission@@example.net
|
||||
$ gpg --with-wkd-hash -K key-submission@@example.net
|
||||
$ gpg -K key-submission@@example.net
|
||||
@end example
|
||||
|
||||
The output of the last command looks similar to this:
|
||||
@ -339,21 +341,16 @@ The output of the last command looks similar to this:
|
||||
sec rsa2048 2016-08-30 [SC]
|
||||
C0FCF8642D830C53246211400346653590B3795B
|
||||
uid [ultimate] key-submission@@example.net
|
||||
bxzcxpxk8h87z1k7bzk86xn5aj47intu@@example.net
|
||||
ssb rsa2048 2016-08-30 [E]
|
||||
@end example
|
||||
|
||||
Take the hash of the string "key-submission", which is
|
||||
"bxzcxpxk8h87z1k7bzk86xn5aj47intu" and manually publish that key:
|
||||
Take the fingerprint from that output and manually publish the key:
|
||||
|
||||
@example
|
||||
$ gpg --export-options export-minimal --export \
|
||||
> -o /var/lib/gnupg/wks/example.net/hu/bxzcxpxk8h87z1k7bzk86xn5aj47intu \
|
||||
> key-submission@@example.new
|
||||
$ gpg-wks-server --install-key C0FCF8642D830C53246211400346653590B3795B \
|
||||
> key-submission@@example.net
|
||||
@end example
|
||||
|
||||
Make sure that the created file is world readable.
|
||||
|
||||
Finally that submission address needs to be redirected to a script
|
||||
running @command{gpg-wks-server}. The @command{procmail} command can
|
||||
be used for this: Redirect the submission address to the user "webkey"
|
||||
|
@ -325,119 +325,6 @@ main (int argc, char **argv)
|
||||
|
||||
|
||||
|
||||
struct get_key_status_parm_s
|
||||
{
|
||||
const char *fpr;
|
||||
int found;
|
||||
int count;
|
||||
};
|
||||
|
||||
static void
|
||||
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 (!strcmp (keyword, "EXPORTED"))
|
||||
{
|
||||
parm->count++;
|
||||
if (!ascii_strcasecmp (args, parm->fpr))
|
||||
parm->found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get a key by fingerprint from gpg's keyring and make sure that the
|
||||
* 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. */
|
||||
static gpg_error_t
|
||||
get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
|
||||
int exact)
|
||||
{
|
||||
gpg_error_t err;
|
||||
ccparray_t ccp;
|
||||
const char **argv = NULL;
|
||||
estream_t key = NULL;
|
||||
struct get_key_status_parm_s parm;
|
||||
char *filterexp = NULL;
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
|
||||
*r_key = NULL;
|
||||
|
||||
key = es_fopenmem (0, "w+b");
|
||||
if (!key)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Prefix the key with the MIME content type. */
|
||||
es_fputs ("Content-Type: application/pgp-keys\n"
|
||||
"\n", key);
|
||||
|
||||
filterexp = es_bsprintf ("keep-uid=%s=%s", exact? "uid":"mbox", 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)
|
||||
ccparray_put (&ccp, "--quiet");
|
||||
else if (opt.verbose > 1)
|
||||
ccparray_put (&ccp, "--verbose");
|
||||
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");
|
||||
ccparray_put (&ccp, "--export-filter");
|
||||
ccparray_put (&ccp, filterexp);
|
||||
ccparray_put (&ccp, "--export");
|
||||
ccparray_put (&ccp, "--");
|
||||
ccparray_put (&ccp, fingerprint);
|
||||
|
||||
ccparray_put (&ccp, NULL);
|
||||
argv = ccparray_get (&ccp, NULL);
|
||||
if (!argv)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
parm.fpr = fingerprint;
|
||||
err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL,
|
||||
NULL, key,
|
||||
get_key_status_cb, &parm);
|
||||
if (!err && parm.count > 1)
|
||||
err = gpg_error (GPG_ERR_TOO_MANY);
|
||||
else if (!err && !parm.found)
|
||||
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||
if (err)
|
||||
{
|
||||
log_error ("export failed: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
es_rewind (key);
|
||||
*r_key = key;
|
||||
key = NULL;
|
||||
|
||||
leave:
|
||||
es_fclose (key);
|
||||
xfree (argv);
|
||||
xfree (filterexp);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Add the user id UID to the key identified by FINGERPRINT. */
|
||||
static gpg_error_t
|
||||
add_user_id (const char *fingerprint, const char *uid)
|
||||
@ -767,7 +654,7 @@ command_send (const char *fingerprint, const char *userid)
|
||||
err = gpg_error (GPG_ERR_INV_USER_ID);
|
||||
goto leave;
|
||||
}
|
||||
err = get_key (&key, fingerprint, addrspec, 0);
|
||||
err = wks_get_key (&key, fingerprint, addrspec, 0);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -897,7 +784,7 @@ command_send (const char *fingerprint, const char *userid)
|
||||
* the key again. */
|
||||
es_fclose (key);
|
||||
key = NULL;
|
||||
err = get_key (&key, fingerprint, addrspec, 1);
|
||||
err = wks_get_key (&key, fingerprint, addrspec, 1);
|
||||
if (err)
|
||||
goto leave;
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "../common/util.h"
|
||||
#include "../common/init.h"
|
||||
#include "../common/sysutils.h"
|
||||
#include "../common/userids.h"
|
||||
#include "../common/ccparray.h"
|
||||
#include "../common/exectool.h"
|
||||
#include "../common/zb32.h"
|
||||
@ -2002,7 +2003,8 @@ static gpg_error_t
|
||||
command_install_key (const char *fname, const char *userid)
|
||||
{
|
||||
gpg_error_t err;
|
||||
estream_t fp;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
estream_t fp = NULL;
|
||||
char *addrspec = NULL;
|
||||
char *fpr = NULL;
|
||||
uidinfo_list_t uidlist = NULL;
|
||||
@ -2011,6 +2013,30 @@ command_install_key (const char *fname, const char *userid)
|
||||
char *huname = NULL;
|
||||
int any;
|
||||
|
||||
addrspec = mailbox_from_userid (userid);
|
||||
if (!addrspec)
|
||||
{
|
||||
log_error ("\"%s\" is not a proper mail address\n", userid);
|
||||
err = gpg_error (GPG_ERR_INV_USER_ID);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!classify_user_id (fname, &desc, 1)
|
||||
&& (desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20))
|
||||
{
|
||||
/* FNAME looks like a fingerprint. Get the key from the
|
||||
* standard keyring. */
|
||||
err = wks_get_key (&fp, fname, addrspec, 0);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error getting key '%s' (uid='%s'): %s\n",
|
||||
fname, addrspec, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
else /* Take it from the file */
|
||||
{
|
||||
fp = es_fopen (fname, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
@ -2018,13 +2044,6 @@ command_install_key (const char *fname, const char *userid)
|
||||
log_error ("error reading '%s': %s\n", fname, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
addrspec = mailbox_from_userid (userid);
|
||||
if (!addrspec)
|
||||
{
|
||||
log_error ("\"%s\" is not a proper mail address\n", userid);
|
||||
err = gpg_error (GPG_ERR_INV_USER_ID);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* List the key so that we can figure out the newest UID with the
|
||||
|
@ -86,6 +86,8 @@ typedef struct uidinfo_list_s *uidinfo_list_t;
|
||||
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);
|
||||
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,
|
||||
|
114
tools/wks-util.c
114
tools/wks-util.c
@ -132,6 +132,120 @@ free_uidinfo_list (uidinfo_list_t list)
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct get_key_status_parm_s
|
||||
{
|
||||
const char *fpr;
|
||||
int found;
|
||||
int count;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
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 (!strcmp (keyword, "EXPORTED"))
|
||||
{
|
||||
parm->count++;
|
||||
if (!ascii_strcasecmp (args, parm->fpr))
|
||||
parm->found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a key by fingerprint from gpg's keyring and make sure that the
|
||||
* 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. */
|
||||
gpg_error_t
|
||||
wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
|
||||
int exact)
|
||||
{
|
||||
gpg_error_t err;
|
||||
ccparray_t ccp;
|
||||
const char **argv = NULL;
|
||||
estream_t key = NULL;
|
||||
struct get_key_status_parm_s parm;
|
||||
char *filterexp = NULL;
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
|
||||
*r_key = NULL;
|
||||
|
||||
key = es_fopenmem (0, "w+b");
|
||||
if (!key)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Prefix the key with the MIME content type. */
|
||||
es_fputs ("Content-Type: application/pgp-keys\n"
|
||||
"\n", key);
|
||||
|
||||
filterexp = es_bsprintf ("keep-uid=%s=%s", exact? "uid":"mbox", 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)
|
||||
ccparray_put (&ccp, "--quiet");
|
||||
else if (opt.verbose > 1)
|
||||
ccparray_put (&ccp, "--verbose");
|
||||
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");
|
||||
ccparray_put (&ccp, "--export-filter");
|
||||
ccparray_put (&ccp, filterexp);
|
||||
ccparray_put (&ccp, "--export");
|
||||
ccparray_put (&ccp, "--");
|
||||
ccparray_put (&ccp, fingerprint);
|
||||
|
||||
ccparray_put (&ccp, NULL);
|
||||
argv = ccparray_get (&ccp, NULL);
|
||||
if (!argv)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
parm.fpr = fingerprint;
|
||||
err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL,
|
||||
NULL, key,
|
||||
get_key_status_cb, &parm);
|
||||
if (!err && parm.count > 1)
|
||||
err = gpg_error (GPG_ERR_TOO_MANY);
|
||||
else if (!err && !parm.found)
|
||||
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||
if (err)
|
||||
{
|
||||
log_error ("export failed: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
es_rewind (key);
|
||||
*r_key = key;
|
||||
key = NULL;
|
||||
|
||||
leave:
|
||||
es_fclose (key);
|
||||
xfree (argv);
|
||||
xfree (filterexp);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Helper for wks_list_key and wks_filter_uid. */
|
||||
static void
|
||||
|
Loading…
x
Reference in New Issue
Block a user