mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +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
|
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
|
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
|
The command @option{--remove-key} uninstalls a key from the WKD. The
|
||||||
process returns success in this case; to also print a diagnostic, use
|
process returns success in this case; to also print a diagnostic, use
|
||||||
@ -330,7 +332,7 @@ the submission address:
|
|||||||
|
|
||||||
@example
|
@example
|
||||||
$ gpg --batch --passphrase '' --quick-gen-key key-submission@@example.net
|
$ 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
|
@end example
|
||||||
|
|
||||||
The output of the last command looks similar to this:
|
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]
|
sec rsa2048 2016-08-30 [SC]
|
||||||
C0FCF8642D830C53246211400346653590B3795B
|
C0FCF8642D830C53246211400346653590B3795B
|
||||||
uid [ultimate] key-submission@@example.net
|
uid [ultimate] key-submission@@example.net
|
||||||
bxzcxpxk8h87z1k7bzk86xn5aj47intu@@example.net
|
|
||||||
ssb rsa2048 2016-08-30 [E]
|
ssb rsa2048 2016-08-30 [E]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Take the hash of the string "key-submission", which is
|
Take the fingerprint from that output and manually publish the key:
|
||||||
"bxzcxpxk8h87z1k7bzk86xn5aj47intu" and manually publish that key:
|
|
||||||
|
|
||||||
@example
|
@example
|
||||||
$ gpg --export-options export-minimal --export \
|
$ gpg-wks-server --install-key C0FCF8642D830C53246211400346653590B3795B \
|
||||||
> -o /var/lib/gnupg/wks/example.net/hu/bxzcxpxk8h87z1k7bzk86xn5aj47intu \
|
> key-submission@@example.net
|
||||||
> key-submission@@example.new
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Make sure that the created file is world readable.
|
|
||||||
|
|
||||||
Finally that submission address needs to be redirected to a script
|
Finally that submission address needs to be redirected to a script
|
||||||
running @command{gpg-wks-server}. The @command{procmail} command can
|
running @command{gpg-wks-server}. The @command{procmail} command can
|
||||||
be used for this: Redirect the submission address to the user "webkey"
|
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. */
|
/* Add the user id UID to the key identified by FINGERPRINT. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
add_user_id (const char *fingerprint, const char *uid)
|
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);
|
err = gpg_error (GPG_ERR_INV_USER_ID);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
err = get_key (&key, fingerprint, addrspec, 0);
|
err = wks_get_key (&key, fingerprint, addrspec, 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -897,7 +784,7 @@ command_send (const char *fingerprint, const char *userid)
|
|||||||
* the key again. */
|
* the key again. */
|
||||||
es_fclose (key);
|
es_fclose (key);
|
||||||
key = NULL;
|
key = NULL;
|
||||||
err = get_key (&key, fingerprint, addrspec, 1);
|
err = wks_get_key (&key, fingerprint, addrspec, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "../common/util.h"
|
#include "../common/util.h"
|
||||||
#include "../common/init.h"
|
#include "../common/init.h"
|
||||||
#include "../common/sysutils.h"
|
#include "../common/sysutils.h"
|
||||||
|
#include "../common/userids.h"
|
||||||
#include "../common/ccparray.h"
|
#include "../common/ccparray.h"
|
||||||
#include "../common/exectool.h"
|
#include "../common/exectool.h"
|
||||||
#include "../common/zb32.h"
|
#include "../common/zb32.h"
|
||||||
@ -2002,7 +2003,8 @@ static gpg_error_t
|
|||||||
command_install_key (const char *fname, const char *userid)
|
command_install_key (const char *fname, const char *userid)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
estream_t fp;
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
estream_t fp = NULL;
|
||||||
char *addrspec = NULL;
|
char *addrspec = NULL;
|
||||||
char *fpr = NULL;
|
char *fpr = NULL;
|
||||||
uidinfo_list_t uidlist = NULL;
|
uidinfo_list_t uidlist = NULL;
|
||||||
@ -2011,14 +2013,6 @@ command_install_key (const char *fname, const char *userid)
|
|||||||
char *huname = NULL;
|
char *huname = NULL;
|
||||||
int any;
|
int any;
|
||||||
|
|
||||||
fp = es_fopen (fname, "rb");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_syserror ();
|
|
||||||
log_error ("error reading '%s': %s\n", fname, gpg_strerror (err));
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
addrspec = mailbox_from_userid (userid);
|
addrspec = mailbox_from_userid (userid);
|
||||||
if (!addrspec)
|
if (!addrspec)
|
||||||
{
|
{
|
||||||
@ -2027,6 +2021,31 @@ command_install_key (const char *fname, const char *userid)
|
|||||||
goto leave;
|
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)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error reading '%s': %s\n", fname, gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* List the key so that we can figure out the newest UID with the
|
/* List the key so that we can figure out the newest UID with the
|
||||||
* requested addrspec. */
|
* requested addrspec. */
|
||||||
err = wks_list_key (fp, &fpr, &uidlist);
|
err = wks_list_key (fp, &fpr, &uidlist);
|
||||||
|
@ -86,6 +86,8 @@ typedef struct uidinfo_list_s *uidinfo_list_t;
|
|||||||
void wks_set_status_fd (int fd);
|
void wks_set_status_fd (int fd);
|
||||||
void wks_write_status (int no, const char *format, ...) GPGRT_ATTR_PRINTF(2,3);
|
void wks_write_status (int no, const char *format, ...) GPGRT_ATTR_PRINTF(2,3);
|
||||||
void free_uidinfo_list (uidinfo_list_t list);
|
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,
|
gpg_error_t wks_list_key (estream_t key, char **r_fpr,
|
||||||
uidinfo_list_t *r_mboxes);
|
uidinfo_list_t *r_mboxes);
|
||||||
gpg_error_t wks_filter_uid (estream_t *r_newkey, estream_t key,
|
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. */
|
/* Helper for wks_list_key and wks_filter_uid. */
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user