1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-09-21 15:01:41 +02:00

Fixed the Read-Only keyring bug and changed the way the keydb interface

works.
This commit is contained in:
Werner Koch 2001-10-18 11:56:03 +00:00
parent ced9e24bfb
commit cfd10815b3
14 changed files with 469 additions and 343 deletions

View File

@ -1,3 +1,7 @@
2001-10-17 Werner Koch <wk@gnupg.org>
* README: Removed note on local_ID.
2001-09-28 Werner Koch <wk@gnupg.org>
* configure.ac: From now on add a string "-cvs" to the version to

3
NEWS
View File

@ -67,6 +67,9 @@ Noteworthy changes in version 1.0.6 (2001-05-29)
* The usual set of minor bug fixes and enhancements.
* non-writable keyrings are now correctly handled.
Noteworthy changes in version 1.0.5 (2001-04-29)
------------------------------------------------

7
README
View File

@ -425,13 +425,6 @@
any order in the user ID. Words are any sequences of letters,
digits, the underscore and characters with bit 7 set.
* By the Local ID (from the trust DB):
"#34"
This may be used by a MUA to specify an exact key after selecting
a key from GnuPG (by using a special option or an extra utility)
* Or by the usual substring:
"Heine"

2
THANKS
View File

@ -38,6 +38,7 @@ David Hallinan hallinan@rtd.com
David Hollenberg dhollen@ISI.EDU
David Mathog MATHOG@seqaxp.bio.caltech.edu
David R. Bergstein dbergstein@home.com
David Shaw dshaw@jabberwocky.com
Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
Dimitri dmitri@advantrix.com
Dirk Lattermann dlatt@t-online.de
@ -67,6 +68,7 @@ Greg Troxel gdt@ir.bbn.com
Gregory Steuck steuck@iname.com
Geoff Keating geoffk@ozemail.com.au
Harald Denker harry@hal.westfalen.de
Holger Baust Holger.Baust@freenet-ag.de
Hendrik Buschkamp buschkamp@rheumanet.org
Holger Schurig holger@d.om.org
Holger Smolinski smolinsk@de.ibm.com

14
TODO
View File

@ -1,4 +1,14 @@
* Pot the lsign flag into the hashed area.
* check whether the "n signatures not checked due to missing keys"
from --edit/check can be due to revoked signatures. Chnage the
wording in this case.
* Remove all references to the local-ID from the docs
* What about adding a feture -word to the +wordlist search mode.
* getkey does not return revoked/expired keys - therefore it is not
possible to override it.
@ -81,10 +91,6 @@
* --disable-asm should still assemble _udiv_qrnnd when needed
* Skip RO keyrings when importing a key.
[Do an access(2) when registering a keyring and add code to
keydb_locate_writable()]
* replace the keyserver stuff either by a call to a specialized
utility and SOCKSify this utility.
[David is working on this]

View File

@ -1293,6 +1293,12 @@ on key material. This option forces v3 signatures for
signatures on data.
</para></listitem></varlistentry>
<varlistentry>
<term>--no-force-v3-sigs</term>
<listitem><para>
Reset the --force-v3-sigs option.
</para></listitem></varlistentry>
<varlistentry>
<term>--force-mdc</term>

View File

@ -1,8 +1,38 @@
2001-10-18 Werner Koch <wk@gnupg.org>
* keydb.c (keydb_add_resource): Rearranged the way we keep track
of the resource. There will now be an entry for each keyring here
and not in keyring.c itself. Store a token to allow creation of a
keyring handle. Changed all functions to utilize this new design.
(keydb_locate_writable): Make a real implementation.
* keyring.c (next_kr): Removed and changed all callers to set the
resource directly from the one given with the handle.
(keyring_is_writable): New.
(keyring_rebuild_cache): Add an arg to pass the token from keydb.
2001-10-17 Werner Koch <wk@gnupg.org>
* keyring.c (keyring_search): Enabled word search mode but print a
warning that it is buggy.
2001-10-11 Werner Koch <wk@gnupg.org>
* hkp.c (hkp_ask_import): No more need to set the port number for
the x-hkp scheme.
(hkp_export): Ditto.
2001-10-06 Stefan Bellon <sbellon@sbellon.de>
* passphrase.c [__riscos__]: Disabled agent specific stuff.
* g10.c: New option --no-force-v3-sigs.
2001-10-04 Werner Koch <wk@gnupg.org>
* export.c (do_export_stream): Do not push the compress filter
here because the context would run out of scope due to the
iobuf_close done by the caller.
(do_export): Do it here instead.
2001-09-28 Werner Koch <wk@gnupg.org>
* keyedit.c (sign_uids): Always use the primary key to sign keys.

View File

@ -83,8 +83,10 @@ do_export( STRLIST users, int secret, int onlyrfc )
IOBUF out = NULL;
int any, rc;
armor_filter_context_t afx;
compress_filter_context_t zfx;
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
rc = open_outfile( NULL, 0, &out );
if( rc )
@ -94,6 +96,8 @@ do_export( STRLIST users, int secret, int onlyrfc )
afx.what = secret?5:1;
iobuf_push_filter( out, armor_filter, &afx );
}
if( opt.compress_keys && opt.compress )
iobuf_push_filter( out, compress_filter, &zfx );
rc = do_export_stream( out, users, secret, onlyrfc, &any );
if( rc || !any )
@ -108,7 +112,6 @@ static int
do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
{
int rc = 0;
compress_filter_context_t zfx;
PACKET pkt;
KBNODE keyblock = NULL;
KBNODE kbctx, node;
@ -118,14 +121,10 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
int all_first = 1;
*any = 0;
memset( &zfx, 0, sizeof zfx);
init_packet( &pkt );
kdbhd = keydb_new (secret);
if( opt.compress_keys && opt.compress )
iobuf_push_filter( out, compress_filter, &zfx );
/* use the correct sequence. strlist_last,prev do work correctly with
* NULL pointers :-) */
for( sl=strlist_last(users); sl || all ; sl=strlist_prev( users, sl )) {

View File

@ -75,7 +75,7 @@ hkp_ask_import( u32 *keyid, void *stats_handle)
opt.keyserver_name, (ulong)keyid[1] );
}
else {
sprintf( request, "x-hkp://%s:11371/pks/lookup?op=get&search=0x%08lX",
sprintf( request, "x-hkp://%s/pks/lookup?op=get&search=0x%08lX",
opt.keyserver_name, (ulong)keyid[1] );
}
rc = http_open_document( &hd, request, hflags );
@ -167,7 +167,7 @@ hkp_export( STRLIST users )
sprintf( request, "%s/pks/add", opt.keyserver_name );
}
else {
sprintf( request, "x-hkp://%s:11371/pks/add", opt.keyserver_name );
sprintf( request, "x-hkp://%s/pks/add", opt.keyserver_name );
}
rc = http_open( &hd, HTTP_REQ_POST, request , hflags );
if( rc ) {

View File

@ -42,21 +42,26 @@ typedef enum {
KEYDB_RESOURCE_TYPE_NONE = 0,
KEYDB_RESOURCE_TYPE_KEYRING
} KeydbResourceType;
#define MAX_KEYDB_RESOURCES 1
#define MAX_KEYDB_RESOURCES 20
struct resource_item {
KeydbResourceType type;
union {
KEYRING_HANDLE kr;
} u;
KeydbResourceType type;
union {
KEYRING_HANDLE kr;
} u;
void *token;
int secret;
};
static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
static int used_resources;
struct keydb_handle {
int locked;
int found;
int current;
struct resource_item active[MAX_KEYDB_RESOURCES];
int locked;
int found;
int current;
int used; /* items in active */
struct resource_item active[MAX_KEYDB_RESOURCES];
};
@ -193,7 +198,21 @@ keydb_add_resource (const char *url, int force, int secret)
iobuf = NULL;
if (created_fname) /* must invalidate that ugly cache */
iobuf_ioctl (NULL, 2, 0, (char*)created_fname);
keyring_register_filename (filename, secret);
{
void *token = keyring_register_filename (filename, secret);
if (!token)
; /* already registered - ignore it */
else if (used_resources >= MAX_KEYDB_RESOURCES)
rc = G10ERR_RESOURCE_LIMIT;
else
{
all_resources[used_resources].type = rt;
all_resources[used_resources].u.kr = NULL; /* Not used here */
all_resources[used_resources].token = token;
all_resources[used_resources].secret = secret;
used_resources++;
}
}
break;
default:
@ -221,24 +240,38 @@ keydb_add_resource (const char *url, int force, int secret)
KEYDB_HANDLE
keydb_new (int secret)
{
KEYDB_HANDLE hd;
int i=0;
hd = m_alloc_clear (sizeof *hd);
hd->found = -1;
hd->active[i].type = KEYDB_RESOURCE_TYPE_KEYRING;
hd->active[i].u.kr = keyring_new (secret);
if (!hd->active[i].u.kr) {
m_free (hd);
return NULL;
KEYDB_HANDLE hd;
int i, j;
hd = m_alloc_clear (sizeof *hd);
hd->found = -1;
assert (used_resources <= MAX_KEYDB_RESOURCES);
for (i=j=0; i < used_resources; i++)
{
if (!all_resources[i].secret != !secret)
continue;
switch (all_resources[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
break;
case KEYDB_RESOURCE_TYPE_KEYRING:
hd->active[j].type = all_resources[i].type;
hd->active[j].token = all_resources[i].token;
hd->active[j].secret = all_resources[i].secret;
hd->active[j].u.kr = keyring_new (all_resources[i].token, secret);
if (!hd->active[j].u.kr) {
m_free (hd);
return NULL; /* fixme: release all previously allocated handles*/
}
j++;
break;
}
}
i++;
assert (i <= MAX_KEYDB_RESOURCES);
active_handles++;
return hd;
hd->used = j;
active_handles++;
return hd;
}
void
@ -252,7 +285,7 @@ keydb_release (KEYDB_HANDLE hd)
active_handles--;
unlock_all (hd);
for (i=0; i < MAX_KEYDB_RESOURCES; i++) {
for (i=0; i < hd->used; i++) {
switch (hd->active[i].type) {
case KEYDB_RESOURCE_TYPE_NONE:
break;
@ -283,9 +316,9 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
if (!hd)
return NULL;
if ( hd->found >= 0 && hd->found < MAX_KEYDB_RESOURCES)
if ( hd->found >= 0 && hd->found < hd->used)
idx = hd->found;
else if ( hd->current >= 0 && hd->current < MAX_KEYDB_RESOURCES)
else if ( hd->current >= 0 && hd->current < hd->used)
idx = hd->current;
else
idx = 0;
@ -309,7 +342,7 @@ lock_all (KEYDB_HANDLE hd)
{
int i, rc = 0;
for (i=0; !rc && i < MAX_KEYDB_RESOURCES; i++) {
for (i=0; !rc && i < hd->used; i++) {
switch (hd->active[i].type) {
case KEYDB_RESOURCE_TYPE_NONE:
break;
@ -345,7 +378,7 @@ unlock_all (KEYDB_HANDLE hd)
if (!hd->locked)
return;
for (i=MAX_KEYDB_RESOURCES-1; i >= 0; i--) {
for (i=hd->used-1; i >= 0; i--) {
switch (hd->active[i].type) {
case KEYDB_RESOURCE_TYPE_NONE:
break;
@ -372,7 +405,7 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
if (!hd)
return G10ERR_INV_ARG;
if ( hd->found < 0 || hd->found >= MAX_KEYDB_RESOURCES)
if ( hd->found < 0 || hd->found >= hd->used)
return -1; /* nothing found */
switch (hd->active[hd->found].type) {
@ -398,7 +431,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
if (!hd)
return G10ERR_INV_ARG;
if ( hd->found < 0 || hd->found >= MAX_KEYDB_RESOURCES)
if ( hd->found < 0 || hd->found >= hd->used)
return -1; /* nothing found */
if( opt.dry_run )
@ -437,9 +470,9 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
if( opt.dry_run )
return 0;
if ( hd->found >= 0 && hd->found < MAX_KEYDB_RESOURCES)
if ( hd->found >= 0 && hd->found < hd->used)
idx = hd->found;
else if ( hd->current >= 0 && hd->current < MAX_KEYDB_RESOURCES)
else if ( hd->current >= 0 && hd->current < hd->used)
idx = hd->current;
else
return G10ERR_GENERAL;
@ -473,7 +506,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
if (!hd)
return G10ERR_INV_ARG;
if ( hd->found < 0 || hd->found >= MAX_KEYDB_RESOURCES)
if ( hd->found < 0 || hd->found >= hd->used)
return -1; /* nothing found */
if( opt.dry_run )
@ -505,16 +538,30 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
int
keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
{
int rc;
if (!hd)
return G10ERR_INV_ARG;
rc = keydb_search_reset (hd);
if (!rc) {
/* fixme: set forward to a writable one */
}
int rc;
if (!hd)
return G10ERR_INV_ARG;
rc = keydb_search_reset (hd); /* this does reset hd->current */
if (rc)
return rc;
for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
{
switch (hd->active[hd->current].type)
{
case KEYDB_RESOURCE_TYPE_NONE:
BUG();
break;
case KEYDB_RESOURCE_TYPE_KEYRING:
if (keyring_is_writable (hd->active[hd->current].token))
return 0; /* found (hd->current is set to it) */
break;
}
}
return -1;
}
/*
@ -523,13 +570,24 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
void
keydb_rebuild_caches (void)
{
int rc;
int i, rc;
rc = keyring_rebuild_cache ();
if (rc)
log_error (_("failed to rebuild all keyring caches: %s\n"),
g10_errstr (rc));
/* add other types here */
for (i=0; i < used_resources; i++)
{
if (all_resources[i].secret)
continue;
switch (all_resources[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
break;
case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_rebuild_cache (all_resources[i].token);
if (rc)
log_error (_("failed to rebuild keyring cache: %s\n"),
g10_errstr (rc));
break;
}
}
}
@ -548,7 +606,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
hd->current = 0;
hd->found = -1;
/* and reset all resources */
for (i=0; !rc && i < MAX_KEYDB_RESOURCES; i++) {
for (i=0; !rc && i < hd->used; i++) {
switch (hd->active[i].type) {
case KEYDB_RESOURCE_TYPE_NONE:
break;
@ -573,10 +631,10 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
if (!hd)
return G10ERR_INV_ARG;
while (rc == -1 && hd->current >= 0 && hd->current < MAX_KEYDB_RESOURCES) {
while (rc == -1 && hd->current >= 0 && hd->current < hd->used) {
switch (hd->active[hd->current].type) {
case KEYDB_RESOURCE_TYPE_NONE:
rc = -1; /* no resource = eof */
BUG(); /* we should never see it here */
break;
case KEYDB_RESOURCE_TYPE_KEYRING:
rc = keyring_search (hd->active[hd->current].u.kr, desc, ndesc);

View File

@ -24,6 +24,7 @@
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -66,7 +67,8 @@ static int kr_offtbl_ready;
struct keyring_handle {
int secret; /* this is for a secret keyring */
CONST_KR_NAME resource;
int secret; /* this is for a secret keyring */
struct {
CONST_KR_NAME kr;
IOBUF iobuf;
@ -191,9 +193,10 @@ update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off)
/*
* Register a filename for plain keyring files
*/
void
* Register a filename for plain keyring files. Returns a pointer to
* be used to create a handles etc or NULL to indicate that it has
* already been registered */
void *
keyring_register_filename (const char *fname, int secret)
{
KR_NAME kr;
@ -203,7 +206,7 @@ keyring_register_filename (const char *fname, int secret)
for (kr=kr_names; kr; kr = kr->next) {
if ( !compare_filenames (kr->fname, fname) )
return; /* already registered */
return NULL; /* already registered */
}
kr = m_alloc (sizeof *kr + strlen (fname));
@ -211,27 +214,44 @@ keyring_register_filename (const char *fname, int secret)
kr->secret = !!secret;
kr->lockhd = NULL;
kr->is_locked = 0;
/* keep a list of all issued pointers */
kr->next = kr_names;
kr_names = kr;
/* create the offset table the first time a function here is used */
if (!kr_offtbl)
kr_offtbl = new_offset_hash_table ();
return kr;
}
int
keyring_is_writable (void *token)
{
KR_NAME r = token;
return r? !access (r->fname, W_OK) : 0;
}
/* Create a new handle for the resource associated with TOKEN. SECRET
is just just as a cross-check.
The returned handle must be released using keyring_release (). */
KEYRING_HANDLE
keyring_new (int secret)
keyring_new (void *token, int secret)
{
KEYRING_HANDLE hd;
KEYRING_HANDLE hd;
KR_NAME resource = token;
hd = m_alloc_clear (sizeof *hd);
hd->secret = !!secret;
active_handles++;
return hd;
assert (resource && !resource->secret == !secret);
hd = m_alloc_clear (sizeof *hd);
hd->resource = resource;
hd->secret = !!secret;
active_handles++;
return hd;
}
void
@ -247,32 +267,13 @@ keyring_release (KEYRING_HANDLE hd)
m_free (hd);
}
static CONST_KR_NAME
next_kr (CONST_KR_NAME start, int secret)
{
start = start? start->next : kr_names;
while ( start && start->secret != secret )
start = start->next;
return start;
}
const char *
keyring_get_resource_name (KEYRING_HANDLE hd)
{
const char *fname;
if (!hd)
fname = NULL;
else if (hd->found.kr)
fname = hd->found.kr->fname;
else if (hd->current.kr)
fname = hd->current.kr->fname;
else {
CONST_KR_NAME kr = next_kr (NULL, hd->secret);
fname = kr? kr->fname:NULL;
}
return fname;
if (!hd || !hd->resource)
return NULL;
return hd->resource->fname;
}
@ -512,10 +513,8 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
fname = hd->found.kr->fname;
else if (hd->current.kr)
fname = hd->current.kr->fname;
else {
CONST_KR_NAME kr = next_kr (NULL, hd->secret);
fname = kr? kr->fname:NULL;
}
else
fname = hd->resource? hd->resource->fname:NULL;
if (!fname)
return G10ERR_GENERAL;
@ -537,6 +536,7 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
return rc;
}
int
keyring_delete_keyblock (KEYRING_HANDLE hd)
{
@ -614,21 +614,19 @@ prepare_search (KEYRING_HANDLE hd)
return -1; /* still EOF */
if (!hd->current.kr) { /* start search with first keyring */
hd->current.kr = next_kr (NULL, hd->secret);
hd->current.kr = hd->resource;
if (!hd->current.kr) {
hd->current.eof = 1;
return -1; /* no keyring available */
return -1; /* keyring not available */
}
assert (!hd->current.iobuf);
}
else { /* EOF on last keyring - switch to next one */
else { /* EOF */
iobuf_close (hd->current.iobuf);
hd->current.iobuf = NULL;
hd->current.kr = next_kr (hd->current.kr, hd->secret);
if (!hd->current.kr) {
hd->current.eof = 1;
return -1;
}
hd->current.kr = NULL;
hd->current.eof = 1;
return -1;
}
hd->current.eof = 0;
@ -834,244 +832,262 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen)
int
keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
{
int rc;
PACKET pkt;
int save_mode;
off_t offset, main_offset;
size_t n;
int need_uid, need_words, need_keyid, need_fpr, any_skip;
int pk_no, uid_no;
int initial_skip;
int use_offtbl;
PKT_user_id *uid = NULL;
PKT_public_key *pk = NULL;
PKT_secret_key *sk = NULL;
int rc;
PACKET pkt;
int save_mode;
off_t offset, main_offset;
size_t n;
int need_uid, need_words, need_keyid, need_fpr, any_skip;
int pk_no, uid_no;
int initial_skip;
int use_offtbl;
PKT_user_id *uid = NULL;
PKT_public_key *pk = NULL;
PKT_secret_key *sk = NULL;
/* figure out what information we need */
need_uid = need_words = need_keyid = need_fpr = any_skip = 0;
for (n=0; n < ndesc; n++) {
switch (desc[n].mode) {
/* figure out what information we need */
need_uid = need_words = need_keyid = need_fpr = any_skip = 0;
for (n=0; n < ndesc; n++)
{
switch (desc[n].mode)
{
case KEYDB_SEARCH_MODE_EXACT:
case KEYDB_SEARCH_MODE_SUBSTR:
case KEYDB_SEARCH_MODE_MAIL:
case KEYDB_SEARCH_MODE_MAILSUB:
case KEYDB_SEARCH_MODE_MAILEND:
need_uid = 1;
break;
case KEYDB_SEARCH_MODE_WORDS:
need_uid = 1;
need_words = 1;
break;
case KEYDB_SEARCH_MODE_SHORT_KID:
case KEYDB_SEARCH_MODE_LONG_KID:
need_keyid = 1;
break;
case KEYDB_SEARCH_MODE_FPR16:
case KEYDB_SEARCH_MODE_FPR20:
case KEYDB_SEARCH_MODE_FPR:
need_fpr = 1;
break;
case KEYDB_SEARCH_MODE_FIRST:
/* always restart the search in this mode */
keyring_search_reset (hd);
break;
default: break;
}
if (desc[n].skipfnc)
{
any_skip = 1;
need_keyid = 1;
}
}
rc = prepare_search (hd);
if (rc)
return rc;
use_offtbl = !hd->secret && kr_offtbl;
if (!use_offtbl)
;
else if (!kr_offtbl_ready)
need_keyid = 1;
else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID)
{
struct off_item *oi;
oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid);
if (!oi)
{ /* We know that we don't have this key */
hd->found.kr = NULL;
hd->current.eof = 1;
return -1;
}
/* We could now create a positive search status and return.
* However the problem is that another instance of gpg may
* have changed the keyring so that the offsets are not valid
* anymore - therefore we don't do it
*/
}
if (need_words)
{
const char *name = NULL;
log_debug ("word search mode does not yet work\n");
/* FIXME: here is a long standing bug in our function and in addition we
just use the first search description */
for (n=0; n < ndesc && !name; n++)
{
if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS)
name = desc[n].u.name;
}
assert (name);
if ( !hd->word_match.name || strcmp (hd->word_match.name, name) )
{
/* name changed */
m_free (hd->word_match.name);
m_free (hd->word_match.pattern);
hd->word_match.name = m_strdup (name);
hd->word_match.pattern = prepare_word_match (name);
}
name = hd->word_match.pattern;
}
init_packet(&pkt);
save_mode = set_packet_list_mode(0);
hd->found.kr = NULL;
main_offset = 0;
pk_no = uid_no = 0;
initial_skip = 1; /* skip until we see the start of a keyblock */
while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid)))
{
byte afp[MAX_FINGERPRINT_LEN];
size_t an;
u32 aki[2];
if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY)
{
main_offset = offset;
pk_no = uid_no = 0;
initial_skip = 0;
}
if (initial_skip)
{
free_packet (&pkt);
continue;
}
pk = NULL;
sk = NULL;
uid = NULL;
if ( pkt.pkttype == PKT_PUBLIC_KEY
|| pkt.pkttype == PKT_PUBLIC_SUBKEY)
{
pk = pkt.pkt.public_key;
++pk_no;
if (need_fpr) {
fingerprint_from_pk (pk, afp, &an);
while (an < 20) /* fill up to 20 bytes */
afp[an++] = 0;
}
if (need_keyid)
keyid_from_pk (pk, aki);
if (use_offtbl && !kr_offtbl_ready)
update_offset_hash_table (kr_offtbl, aki, main_offset);
}
else if (pkt.pkttype == PKT_USER_ID)
{
uid = pkt.pkt.user_id;
++uid_no;
}
else if ( pkt.pkttype == PKT_SECRET_KEY
|| pkt.pkttype == PKT_SECRET_SUBKEY)
{
sk = pkt.pkt.secret_key;
++pk_no;
if (need_fpr) {
fingerprint_from_sk (sk, afp, &an);
while (an < 20) /* fill up to 20 bytes */
afp[an++] = 0;
}
if (need_keyid)
keyid_from_sk (sk, aki);
}
for (n=0; n < ndesc; n++)
{
switch (desc[n].mode) {
case KEYDB_SEARCH_MODE_NONE:
BUG ();
break;
case KEYDB_SEARCH_MODE_EXACT:
case KEYDB_SEARCH_MODE_SUBSTR:
case KEYDB_SEARCH_MODE_MAIL:
case KEYDB_SEARCH_MODE_MAILSUB:
case KEYDB_SEARCH_MODE_MAILEND:
need_uid = 1;
break;
case KEYDB_SEARCH_MODE_WORDS:
need_uid = 1;
need_words = 1;
if ( uid && !compare_name (desc[n].mode,
desc[n].u.name,
uid->name, uid->len))
goto found;
break;
case KEYDB_SEARCH_MODE_SHORT_KID:
case KEYDB_SEARCH_MODE_LONG_KID:
need_keyid = 1;
if ((pk||sk) && desc[n].u.kid[1] == aki[1])
goto found;
break;
case KEYDB_SEARCH_MODE_LONG_KID:
if ((pk||sk) && desc[n].u.kid[0] == aki[0]
&& desc[n].u.kid[1] == aki[1])
goto found;
break;
case KEYDB_SEARCH_MODE_FPR16:
if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16))
goto found;
break;
case KEYDB_SEARCH_MODE_FPR16:
case KEYDB_SEARCH_MODE_FPR20:
case KEYDB_SEARCH_MODE_FPR:
need_fpr = 1;
if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20))
goto found;
break;
case KEYDB_SEARCH_MODE_FIRST:
/* always restart the search in this mode */
keyring_search_reset (hd);
case KEYDB_SEARCH_MODE_FIRST:
if (pk||sk)
goto found;
break;
default: break;
}
if (desc[n].skipfnc) {
any_skip = 1;
need_keyid = 1;
}
}
rc = prepare_search (hd);
if (rc)
return rc;
use_offtbl = !hd->secret && kr_offtbl;
if (!use_offtbl)
;
else if (!kr_offtbl_ready)
need_keyid = 1;
else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID)
{
struct off_item *oi;
oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid);
if (!oi)
{ /* We know that we don't have this key */
hd->found.kr = NULL;
hd->current.eof = 1;
return -1;
case KEYDB_SEARCH_MODE_NEXT:
if (pk||sk)
goto found;
break;
default:
rc = G10ERR_INV_ARG;
goto found;
}
/* We could now create a positive search status and return.
* However the problem is that another instance of gpg may
* have changed the keyring so that the offsets are not valid
* anymore - therefore we don't do it
*/
}
#if 0
if (need_words) {
BUG();
if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) {
/* name changed */
m_free (hd->word_match.name);
m_free (hd->word_match.pattern);
hd->word_match.name = m_strdup (name);
hd->word_match.pattern = prepare_word_match (name);
}
name = hd->word_match.pattern;
}
#endif
init_packet(&pkt);
save_mode = set_packet_list_mode(0);
hd->found.kr = NULL;
main_offset = 0;
pk_no = uid_no = 0;
initial_skip = 1; /* skip until we see the start of a keyblock */
while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) {
byte afp[MAX_FINGERPRINT_LEN];
size_t an;
u32 aki[2];
if (pkt.pkttype == PKT_PUBLIC_KEY
|| pkt.pkttype == PKT_SECRET_KEY) {
main_offset = offset;
pk_no = uid_no = 0;
initial_skip = 0;
}
if (initial_skip) {
free_packet (&pkt);
continue;
}
pk = NULL;
sk = NULL;
uid = NULL;
if ( pkt.pkttype == PKT_PUBLIC_KEY
|| pkt.pkttype == PKT_PUBLIC_SUBKEY) {
pk = pkt.pkt.public_key;
++pk_no;
if (need_fpr) {
fingerprint_from_pk (pk, afp, &an);
while (an < 20) /* fill up to 20 bytes */
afp[an++] = 0;
}
if (need_keyid)
keyid_from_pk (pk, aki);
if (use_offtbl && !kr_offtbl_ready)
update_offset_hash_table (kr_offtbl, aki, main_offset);
}
else if (pkt.pkttype == PKT_USER_ID) {
uid = pkt.pkt.user_id;
++uid_no;
}
else if ( pkt.pkttype == PKT_SECRET_KEY
|| pkt.pkttype == PKT_SECRET_SUBKEY) {
sk = pkt.pkt.secret_key;
++pk_no;
if (need_fpr) {
fingerprint_from_sk (sk, afp, &an);
while (an < 20) /* fill up to 20 bytes */
afp[an++] = 0;
}
if (need_keyid)
keyid_from_sk (sk, aki);
}
for (n=0; n < ndesc; n++) {
switch (desc[n].mode) {
case KEYDB_SEARCH_MODE_NONE:
BUG ();
break;
case KEYDB_SEARCH_MODE_EXACT:
case KEYDB_SEARCH_MODE_SUBSTR:
case KEYDB_SEARCH_MODE_MAIL:
case KEYDB_SEARCH_MODE_MAILSUB:
case KEYDB_SEARCH_MODE_MAILEND:
case KEYDB_SEARCH_MODE_WORDS:
if ( uid && !compare_name (desc[n].mode,
desc[n].u.name,
uid->name, uid->len))
goto found;
break;
case KEYDB_SEARCH_MODE_SHORT_KID:
if ((pk||sk) && desc[n].u.kid[1] == aki[1])
goto found;
break;
case KEYDB_SEARCH_MODE_LONG_KID:
if ((pk||sk) && desc[n].u.kid[0] == aki[0]
&& desc[n].u.kid[1] == aki[1])
goto found;
break;
case KEYDB_SEARCH_MODE_FPR16:
if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16))
goto found;
break;
case KEYDB_SEARCH_MODE_FPR20:
case KEYDB_SEARCH_MODE_FPR:
if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20))
goto found;
break;
case KEYDB_SEARCH_MODE_FIRST:
if (pk||sk)
goto found;
break;
case KEYDB_SEARCH_MODE_NEXT:
if (pk||sk)
goto found;
break;
default:
rc = G10ERR_INV_ARG;
goto found;
}
}
free_packet (&pkt);
continue;
found:
for (n=any_skip?0:ndesc; n < ndesc; n++) {
if (desc[n].skipfnc
&& desc[n].skipfnc (desc[n].skipfncvalue, aki))
break;
free_packet (&pkt);
continue;
found:
for (n=any_skip?0:ndesc; n < ndesc; n++)
{
if (desc[n].skipfnc
&& desc[n].skipfnc (desc[n].skipfncvalue, aki))
break;
}
if (n == ndesc)
goto real_found;
free_packet (&pkt);
if (n == ndesc)
goto real_found;
free_packet (&pkt);
}
real_found:
if( !rc ) {
hd->found.offset = main_offset;
hd->found.kr = hd->current.kr;
hd->found.pk_no = (pk||sk)? pk_no : 0;
hd->found.uid_no = uid? uid_no : 0;
if (!rc)
{
hd->found.offset = main_offset;
hd->found.kr = hd->current.kr;
hd->found.pk_no = (pk||sk)? pk_no : 0;
hd->found.uid_no = uid? uid_no : 0;
}
else if (rc == -1)
{
hd->current.eof = 1;
/* if we scanned the entire keyring, we are sure that
* all known key IDs are in our offtbl, mark that. */
if (use_offtbl)
kr_offtbl_ready = 1;
}
else
hd->current.error = rc;
else if (rc == -1)
{
hd->current.eof = 1;
/* if we scanned the entire keyring, we are sure that
* all known key IDs are in our offtbl, mark that. */
if (use_offtbl)
kr_offtbl_ready = 1;
}
else
hd->current.error = rc;
free_packet(&pkt);
set_packet_list_mode(save_mode);
return rc;
free_packet(&pkt);
set_packet_list_mode(save_mode);
return rc;
}
static int
create_tmp_file (const char *template,
char **r_bakfname, char **r_tmpfname, IOBUF *r_fp)
@ -1236,7 +1252,7 @@ write_keyblock (IOBUF fp, KBNODE keyblock)
* This is only done for the public keyrings.
*/
int
keyring_rebuild_cache ()
keyring_rebuild_cache (void *token)
{
KEYRING_HANDLE hd;
KEYDB_SEARCH_DESC desc;
@ -1248,7 +1264,7 @@ keyring_rebuild_cache ()
int rc;
ulong count = 0, sigcount = 0;
hd = keyring_new (0);
hd = keyring_new (token, 0);
memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FIRST;
@ -1366,7 +1382,10 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
char *bakfname = NULL;
char *tmpfname = NULL;
/* open the source file */
/* Open the source file. Because we do a rname, we have to check the
permissions of the file */
if (access (fname, W_OK))
return G10ERR_WRITE_FILE;
fp = iobuf_open (fname);
if (mode == 1 && !fp && errno == ENOENT) {
/* insert mode but file does not exist: create a new file */

View File

@ -26,19 +26,20 @@
typedef struct keyring_handle *KEYRING_HANDLE;
void keyring_register_filename (const char *fname, int secret);
void *keyring_register_filename (const char *fname, int secret);
int keyring_is_writable (void *token);
KEYRING_HANDLE keyring_new (int secret);
KEYRING_HANDLE keyring_new (void *token, int secret);
void keyring_release (KEYRING_HANDLE hd);
const char *keyring_get_resource_name (KEYRING_HANDLE hd);
int keyring_lock (KEYRING_HANDLE hd, int yes);
int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb);
int keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb);
int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb);
int keyring_locate_writable (KEYRING_HANDLE hd);
int keyring_delete_keyblock (KEYRING_HANDLE hd);
int keyring_search_reset (KEYRING_HANDLE hd);
int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc);
int keyring_rebuild_cache (void);
int keyring_rebuild_cache (void *);
#endif /*GPG_KEYRING_H*/

View File

@ -1,3 +1,8 @@
2001-10-11 Werner Koch <wk@gnupg.org>
* http.c (do_parse_uri): Changed initialization of the port number
so that it does also work with x-hkp. By David Shaw.
2001-09-19 Werner Koch <wk@gnupg.org>
* w32reg.c (get_root_key): New.

View File

@ -284,10 +284,11 @@ do_parse_uri( PARSED_URI uri, int only_local_part )
*p2++ = 0;
strlwr( p );
uri->scheme = p;
uri->port = 80;
if( !strcmp( uri->scheme, "http" ) )
;
else if( !strcmp( uri->scheme, "x-hkp" ) ) /* same as HTTP */
;
uri->port = 11371;
else
return G10ERR_INVALID_URI; /* Unsupported scheme */
@ -308,8 +309,7 @@ do_parse_uri( PARSED_URI uri, int only_local_part )
*p3++ = 0;
uri->port = atoi( p3 );
}
else
uri->port = 80;
uri->host = p;
if( (n = remove_escapes( uri->host )) < 0 )
return G10ERR_BAD_URI;