mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
* options.h, keydb.h, g10.c (main), getkey.c (parse_auto_key_locate):
Parse a list of key access methods. (get_pubkey_byname): Walk the list here to try and retrieve keys we don't have locally.
This commit is contained in:
parent
e396cd2c7c
commit
7eab1846ca
@ -1,3 +1,10 @@
|
|||||||
|
2006-02-22 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* options.h, keydb.h, g10.c (main), getkey.c
|
||||||
|
(parse_auto_key_locate): Parse a list of key access methods.
|
||||||
|
(get_pubkey_byname): Walk the list here to try and retrieve keys
|
||||||
|
we don't have locally.
|
||||||
|
|
||||||
2006-02-21 David Shaw <dshaw@jabberwocky.com>
|
2006-02-21 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* getkey.c (get_pubkey_byname): Fix minor security problem with
|
* getkey.c (get_pubkey_byname): Fix minor security problem with
|
||||||
|
114
g10/getkey.c
114
g10/getkey.c
@ -905,45 +905,38 @@ get_pubkey_byname (PKT_public_key *pk,
|
|||||||
KEYDB_HANDLE *ret_kdbhd, int include_unusable )
|
KEYDB_HANDLE *ret_kdbhd, int include_unusable )
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int tried_cert=0, tried_pka=0, tried_ks=0;
|
|
||||||
STRLIST namelist = NULL;
|
STRLIST namelist = NULL;
|
||||||
|
|
||||||
add_to_strlist( &namelist, name );
|
add_to_strlist( &namelist, name );
|
||||||
retry:
|
|
||||||
rc = key_byname( NULL, namelist, pk, NULL, 0,
|
rc = key_byname( NULL, namelist, pk, NULL, 0,
|
||||||
include_unusable, ret_keyblock, ret_kdbhd);
|
include_unusable, ret_keyblock, ret_kdbhd);
|
||||||
|
|
||||||
|
/* If the requested name resembles a valid mailbox and automatic
|
||||||
|
retrieval has been enabled, we try to import the key. */
|
||||||
|
|
||||||
if (rc == G10ERR_NO_PUBKEY && is_valid_mailbox(name))
|
if (rc == G10ERR_NO_PUBKEY && is_valid_mailbox(name))
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
struct akl *akl;
|
||||||
|
|
||||||
if(!tried_cert
|
for(akl=opt.auto_key_locate;akl;akl=akl->next)
|
||||||
&& (opt.keyserver_options.options&KEYSERVER_AUTO_CERT_RETRIEVE))
|
|
||||||
{
|
{
|
||||||
tried_cert=1;
|
switch(akl->type)
|
||||||
|
{
|
||||||
|
case AKL_CERT:
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
res=keyserver_import_cert(name);
|
res=keyserver_import_cert(name);
|
||||||
glo_ctrl.in_auto_key_retrieve--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
|
|
||||||
if(res==0)
|
if(res==0)
|
||||||
{
|
|
||||||
log_info(_("Automatically retrieved `%s' via %s\n"),
|
log_info(_("Automatically retrieved `%s' via %s\n"),
|
||||||
name,"DNS CERT");
|
name,"DNS CERT");
|
||||||
goto retry;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!tried_pka
|
case AKL_PKA:
|
||||||
&& opt.allow_pka_lookup
|
|
||||||
&& (opt.keyserver_options.options&KEYSERVER_AUTO_PKA_RETRIEVE))
|
|
||||||
{
|
{
|
||||||
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
||||||
/* If the requested name resembles a valid mailbox and
|
|
||||||
automatic retrieval via PKA records has been enabled, we
|
|
||||||
try to import the key via the URI and try again. */
|
|
||||||
|
|
||||||
tried_pka=1;
|
|
||||||
|
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
res=keyserver_import_pka(name,fpr);
|
res=keyserver_import_pka(name,fpr);
|
||||||
@ -952,7 +945,7 @@ get_pubkey_byname (PKT_public_key *pk,
|
|||||||
if(res==0)
|
if(res==0)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char fpr_string[2+(MAX_FINGERPRINT_LEN*2)+1];
|
char fpr_string[MAX_FINGERPRINT_LEN*2+1];
|
||||||
|
|
||||||
log_info(_("Automatically retrieved `%s' via %s\n"),
|
log_info(_("Automatically retrieved `%s' via %s\n"),
|
||||||
name,"PKA");
|
name,"PKA");
|
||||||
@ -964,32 +957,42 @@ get_pubkey_byname (PKT_public_key *pk,
|
|||||||
sprintf(fpr_string+2*i,"%02X",fpr[i]);
|
sprintf(fpr_string+2*i,"%02X",fpr[i]);
|
||||||
|
|
||||||
add_to_strlist( &namelist, fpr_string );
|
add_to_strlist( &namelist, fpr_string );
|
||||||
|
|
||||||
goto retry;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* Try keyserver last as it is likely to be the slowest.
|
case AKL_LDAP:
|
||||||
Strictly speaking, we don't need to only use a valid mailbox
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
for the getname search, but it helps cut down on a problem
|
res=keyserver_import_ldap(name);
|
||||||
with searching for something like "john" and getting a lot of
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
keys back. */
|
|
||||||
if(!tried_ks
|
if(res==0)
|
||||||
&& opt.keyserver
|
log_info(_("Automatically retrieved `%s' via %s\n"),
|
||||||
&& (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE))
|
name,"LDAP");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AKL_KEYSERVER:
|
||||||
|
/* Strictly speaking, we don't need to only use a valid
|
||||||
|
mailbox for the getname search, but it helps cut down
|
||||||
|
on the problem of searching for something like "john"
|
||||||
|
and getting a whole lot of keys back. */
|
||||||
|
if(opt.keyserver)
|
||||||
{
|
{
|
||||||
tried_ks=1;
|
|
||||||
|
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
res=keyserver_import_name(name);
|
res=keyserver_import_name(name);
|
||||||
glo_ctrl.in_auto_key_retrieve--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
|
|
||||||
if(res==0)
|
if(res==0)
|
||||||
{
|
|
||||||
log_info(_("Automatically retrieved `%s' via %s\n"),
|
log_info(_("Automatically retrieved `%s' via %s\n"),
|
||||||
name,opt.keyserver->uri);
|
name,opt.keyserver->uri);
|
||||||
goto retry;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = key_byname( NULL, namelist, pk, NULL, 0,
|
||||||
|
include_unusable, ret_keyblock, ret_kdbhd);
|
||||||
|
if(rc!=G10ERR_NO_PUBKEY)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2875,3 +2878,48 @@ get_ctx_handle(GETKEY_CTX ctx)
|
|||||||
{
|
{
|
||||||
return ctx->kr_handle;
|
return ctx->kr_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_auto_key_locate(char *options)
|
||||||
|
{
|
||||||
|
char *tok;
|
||||||
|
|
||||||
|
while((tok=optsep(&options)))
|
||||||
|
{
|
||||||
|
struct akl *akl,*last;
|
||||||
|
|
||||||
|
if(tok[0]=='\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
akl=xmalloc_clear(sizeof(*akl));
|
||||||
|
|
||||||
|
if(ascii_strcasecmp(tok,"cert")==0)
|
||||||
|
akl->type=AKL_CERT;
|
||||||
|
else if(ascii_strcasecmp(tok,"pka")==0)
|
||||||
|
akl->type=AKL_PKA;
|
||||||
|
else if(ascii_strcasecmp(tok,"ldap")==0)
|
||||||
|
akl->type=AKL_LDAP;
|
||||||
|
else if(ascii_strcasecmp(tok,"keyserver")==0)
|
||||||
|
akl->type=AKL_KEYSERVER;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xfree(akl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We must maintain the order the user gave us */
|
||||||
|
for(last=opt.auto_key_locate;last && last->next;last=last->next)
|
||||||
|
{
|
||||||
|
/* Check for duplicates */
|
||||||
|
if(last && last->type==akl->type)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(last)
|
||||||
|
last->next=akl;
|
||||||
|
else
|
||||||
|
opt.auto_key_locate=akl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
15
g10/gpg.c
15
g10/gpg.c
@ -354,14 +354,13 @@ enum cmd_and_opt_values
|
|||||||
oKeyidFormat,
|
oKeyidFormat,
|
||||||
oExitOnStatusWriteError,
|
oExitOnStatusWriteError,
|
||||||
oLimitCardInsertTries,
|
oLimitCardInsertTries,
|
||||||
|
|
||||||
oReaderPort,
|
oReaderPort,
|
||||||
octapiDriver,
|
octapiDriver,
|
||||||
opcscDriver,
|
opcscDriver,
|
||||||
oDisableCCID,
|
oDisableCCID,
|
||||||
|
|
||||||
oRequireBacksigs,
|
oRequireBacksigs,
|
||||||
oNoRequireBacksigs,
|
oNoRequireBacksigs,
|
||||||
|
oAutoKeyLocate,
|
||||||
|
|
||||||
oNoop
|
oNoop
|
||||||
};
|
};
|
||||||
@ -707,6 +706,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oRecipient, "user", 2, "@" },
|
{ oRecipient, "user", 2, "@" },
|
||||||
{ oRequireBacksigs, "require-backsigs", 0, "@"},
|
{ oRequireBacksigs, "require-backsigs", 0, "@"},
|
||||||
{ oNoRequireBacksigs, "no-require-backsigs", 0, "@"},
|
{ oNoRequireBacksigs, "no-require-backsigs", 0, "@"},
|
||||||
|
{ oAutoKeyLocate, "auto-key-locate", 2, "@"},
|
||||||
{0,NULL,0,NULL}
|
{0,NULL,0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2645,6 +2645,17 @@ main (int argc, char **argv )
|
|||||||
case oRequireBacksigs: opt.require_backsigs=1; break;
|
case oRequireBacksigs: opt.require_backsigs=1; break;
|
||||||
case oNoRequireBacksigs: opt.require_backsigs=0; break;
|
case oNoRequireBacksigs: opt.require_backsigs=0; break;
|
||||||
|
|
||||||
|
case oAutoKeyLocate:
|
||||||
|
if(!parse_auto_key_locate(pargs.r.ret_str))
|
||||||
|
{
|
||||||
|
if(configname)
|
||||||
|
log_error(_("%s:%d: invalid auto-key-locate list\n"),
|
||||||
|
configname,configlineno);
|
||||||
|
else
|
||||||
|
log_error(_("invalid auto-key-locate list\n"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case oNoop: break;
|
case oNoop: break;
|
||||||
|
|
||||||
default : pargs.err = configfp? 1:2; break;
|
default : pargs.err = configfp? 1:2; break;
|
||||||
|
@ -258,6 +258,7 @@ char*get_long_user_id_string( u32 *keyid );
|
|||||||
char*get_user_id( u32 *keyid, size_t *rn );
|
char*get_user_id( u32 *keyid, size_t *rn );
|
||||||
char*get_user_id_native( u32 *keyid );
|
char*get_user_id_native( u32 *keyid );
|
||||||
KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
|
KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
|
||||||
|
int parse_auto_key_locate(char *options);
|
||||||
|
|
||||||
/*-- keyid.c --*/
|
/*-- keyid.c --*/
|
||||||
int pubkey_letter( int algo );
|
int pubkey_letter( int algo );
|
||||||
|
@ -220,6 +220,14 @@ struct
|
|||||||
error (but an invalid backsig still is). */
|
error (but an invalid backsig still is). */
|
||||||
int require_backsigs;
|
int require_backsigs;
|
||||||
|
|
||||||
|
/* Linked list of ways to find a key if the key isn't on the local
|
||||||
|
keyring. */
|
||||||
|
struct akl
|
||||||
|
{
|
||||||
|
enum {AKL_CERT, AKL_PKA, AKL_LDAP, AKL_KEYSERVER} type;
|
||||||
|
struct akl *next;
|
||||||
|
} *auto_key_locate;
|
||||||
|
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
/* CTRL is used to keep some global variables we currently can't
|
/* CTRL is used to keep some global variables we currently can't
|
||||||
|
Loading…
x
Reference in New Issue
Block a user