diff options
author | Werner Koch <[email protected]> | 2008-04-08 11:04:16 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2008-04-08 11:04:16 +0000 |
commit | 97ec9aac2b306bd87f77c2a50813376f557e3d58 (patch) | |
tree | bd494a6312edfb8037daa9428be6bc249cbc7480 /g10/getkey.c | |
parent | Allow requesting TCP queries. (diff) | |
download | gnupg-97ec9aac2b306bd87f77c2a50813376f557e3d58.tar.gz gnupg-97ec9aac2b306bd87f77c2a50813376f557e3d58.zip |
Enhanced --auto-key-locate.
Diffstat (limited to '')
-rw-r--r-- | g10/getkey.c | 134 |
1 files changed, 90 insertions, 44 deletions
diff --git a/g10/getkey.c b/g10/getkey.c index 47cf22ea3..2e4ee92b7 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1,6 +1,6 @@ /* getkey.c - Get a key from the database * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2007 Free Software Foundation, Inc. + * 2006, 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -912,64 +912,91 @@ key_byname( GETKEY_CTX *retctx, strlist_t namelist, /* Find a public key from NAME and return the keyblock or the key. If ret_kdb is not NULL, the KEYDB handle used to locate this keyblock is returned and the caller is responsible for closing it. If a key - was not found and NAME is a valid RFC822 mailbox and --auto-key-locate - has been enabled, we try to import the key via the online mechanisms - defined by --auto-key-locate. */ + was not found (or if local search has been disabled) and NAME is a + valid RFC822 mailbox and --auto-key-locate has been enabled, we try + to import the key via the online mechanisms defined by + --auto-key-locate. */ int get_pubkey_byname (PKT_public_key *pk, const char *name, KBNODE *ret_keyblock, - KEYDB_HANDLE *ret_kdbhd, int include_unusable ) + KEYDB_HANDLE *ret_kdbhd, int include_unusable, + int no_akl) { int rc; strlist_t namelist = NULL; + struct akl *akl; + int nodefault = 0; - add_to_strlist( &namelist, name ); + /* Check whether we the default local search has been disabled. + This is the case if either the "nodefault" or the "local" keyword + are in the list of auto key locate mechanisms. */ + if (!no_akl) + { + for (akl=opt.auto_key_locate; akl; akl=akl->next) + if (akl->type == AKL_NODEFAULT || akl->type == AKL_LOCAL) + { + nodefault = 1; + break; + } + } - rc = key_byname( NULL, namelist, pk, NULL, 0, - include_unusable, ret_keyblock, ret_kdbhd); + if (nodefault) + rc = G10ERR_NO_PUBKEY; + else + { + add_to_strlist (&namelist, name); + rc = key_byname (NULL, namelist, pk, NULL, 0, + 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 && !no_akl && is_valid_mailbox(name)) { - struct akl *akl; - - for(akl=opt.auto_key_locate;akl;akl=akl->next) + for (akl=opt.auto_key_locate; akl; akl=akl->next) { - unsigned char *fpr=NULL; + unsigned char *fpr = NULL; size_t fpr_len; - + int did_key_byname = 0; + int no_fingerprint = 0; + const char *mechanism = "?"; + switch(akl->type) { + case AKL_NODEFAULT: + /* This is a dummy mechanism. */ + mechanism = "None"; + rc = G10ERR_NO_PUBKEY; + break; + + case AKL_LOCAL: + mechanism = "Local"; + did_key_byname = 1; + add_to_strlist (&namelist, name); + rc = key_byname (NULL, namelist, pk, NULL, 0, + include_unusable, ret_keyblock, ret_kdbhd); + break; + case AKL_CERT: + mechanism = "DNS CERT"; glo_ctrl.in_auto_key_retrieve++; rc=keyserver_import_cert(name,&fpr,&fpr_len); glo_ctrl.in_auto_key_retrieve--; - - if(rc==0) - log_info(_("automatically retrieved `%s' via %s\n"), - name,"DNS CERT"); break; case AKL_PKA: + mechanism = "PKA"; glo_ctrl.in_auto_key_retrieve++; rc=keyserver_import_pka(name,&fpr,&fpr_len); glo_ctrl.in_auto_key_retrieve--; - - if(rc==0) - log_info(_("automatically retrieved `%s' via %s\n"), - name,"PKA"); break; case AKL_LDAP: + mechanism = "LDAP"; glo_ctrl.in_auto_key_retrieve++; rc=keyserver_import_ldap(name,&fpr,&fpr_len); glo_ctrl.in_auto_key_retrieve--; - - if(rc==0) - log_info(_("automatically retrieved `%s' via %s\n"), - name,"LDAP"); break; case AKL_KEYSERVER: @@ -979,32 +1006,31 @@ get_pubkey_byname (PKT_public_key *pk, and getting a whole lot of keys back. */ if(opt.keyserver) { + mechanism = opt.keyserver->uri; glo_ctrl.in_auto_key_retrieve++; rc=keyserver_import_name(name,&fpr,&fpr_len,opt.keyserver); glo_ctrl.in_auto_key_retrieve--; - - if(rc==0) - log_info(_("automatically retrieved `%s' via %s\n"), - name,opt.keyserver->uri); } + else + { + mechanism = "Unconfigured keyserver"; + rc = G10ERR_NO_PUBKEY; + } break; case AKL_SPEC: { struct keyserver_spec *keyserver; + mechanism = akl->spec->uri; keyserver=keyserver_match(akl->spec); glo_ctrl.in_auto_key_retrieve++; rc=keyserver_import_name(name,&fpr,&fpr_len,keyserver); glo_ctrl.in_auto_key_retrieve--; - - if(rc==0) - log_info(_("automatically retrieved `%s' via %s\n"), - name,akl->spec->uri); } break; } - + /* Use the fingerprint of the key that we actually fetched. This helps prevent problems where the key that we fetched doesn't have the same name that we used to fetch it. In @@ -1027,14 +1053,29 @@ get_pubkey_byname (PKT_public_key *pk, log_info("auto-key-locate found fingerprint %s\n",fpr_string); add_to_strlist( &namelist, fpr_string ); - - xfree(fpr); } - - rc = key_byname( NULL, namelist, pk, NULL, 0, - include_unusable, ret_keyblock, ret_kdbhd); - if(rc!=G10ERR_NO_PUBKEY) - break; + else if (!rc && !fpr && !did_key_byname) + { + no_fingerprint = 1; + rc = G10ERR_NO_PUBKEY; + } + xfree (fpr); + fpr = NULL; + + if (!rc && !did_key_byname) + rc = key_byname (NULL, namelist, pk, NULL, 0, + include_unusable, ret_keyblock, ret_kdbhd); + if (!rc) + { + /* Key found. */ + log_info (_("automatically retrieved `%s' via %s\n"), + name, mechanism); + break; + } + if (rc != G10ERR_NO_PUBKEY || opt.verbose || no_fingerprint) + log_info (_("error retrieving `%s' via %s: %s\n"), + name, mechanism, + no_fingerprint? _("No fingerprint"):g10_errstr(rc)); } } @@ -2638,7 +2679,7 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ) rc = 0; while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) { /* If we are searching for the first key we have to make sure - that the next interation does not no an implicit reset. + that the next iteration does not do an implicit reset. This can be triggered by an empty key ring. */ if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST) ctx->items->mode = KEYDB_SEARCH_MODE_NEXT; @@ -2949,6 +2990,7 @@ release_akl(void) } } +/* Returns false on error. */ int parse_auto_key_locate(char *options) { @@ -2964,7 +3006,11 @@ parse_auto_key_locate(char *options) akl=xmalloc_clear(sizeof(*akl)); - if(ascii_strcasecmp(tok,"ldap")==0) + if(ascii_strcasecmp(tok,"nodefault")==0) + akl->type=AKL_NODEFAULT; + else if(ascii_strcasecmp(tok,"local")==0) + akl->type=AKL_LOCAL; + else if(ascii_strcasecmp(tok,"ldap")==0) akl->type=AKL_LDAP; else if(ascii_strcasecmp(tok,"keyserver")==0) akl->type=AKL_KEYSERVER; |