diff --git a/g10/ChangeLog b/g10/ChangeLog index cc0c34636..7b9db0a73 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,15 @@ +2005-12-23 David Shaw + + * gpgv.c: Stub. + + * keyserver-internal.h, keyserver.c (keyserver_spawn, + keyserver_work, keygerver_getname): New keyserver_getname function + to fetch keys by name. + + * getkey.c (get_pubkey_byname): Call it here to enable locating + keys by full mailbox from a keyserver a la PKA. Try PKA first, + though, as it is likely to be faster. + 2005-12-20 Werner Koch * gpg.c: New option --allow-pka-lookup. diff --git a/g10/getkey.c b/g10/getkey.c index e66b57cdd..ebd1345fd 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -905,42 +905,60 @@ get_pubkey_byname (PKT_public_key *pk, KEYDB_HANDLE *ret_kdbhd, int include_unusable ) { int rc; - int again = 0; + int tried_ks=0, tried_pka=0; STRLIST namelist = NULL; add_to_strlist( &namelist, name ); retry: rc = key_byname( NULL, namelist, pk, NULL, 0, include_unusable, ret_keyblock, ret_kdbhd); - if (rc == G10ERR_NO_PUBKEY - && !again - && opt.allow_pka_lookup - && (opt.keyserver_options.options&KEYSERVER_AUTO_PKA_RETRIEVE) - && is_valid_mailbox (name)) + + if (rc == G10ERR_NO_PUBKEY && is_valid_mailbox(name)) { - /* 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. */ - unsigned char fpr[MAX_FINGERPRINT_LEN]; - char *uri; - struct keyserver_spec *spec; + if(!tried_pka + && opt.allow_pka_lookup + && (opt.keyserver_options.options&KEYSERVER_AUTO_PKA_RETRIEVE)) + { + /* 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. */ + unsigned char fpr[MAX_FINGERPRINT_LEN]; + char *uri; + struct keyserver_spec *spec; + int try=1; + + tried_pka=1; - uri = get_pka_info (name, fpr); - if (uri) - { - spec = parse_keyserver_uri (uri, 0, NULL, 0); - if (spec) - { - glo_ctrl.in_auto_key_retrieve++; - if (!keyserver_import_fprint (fpr, 20, spec)) - again = 1; - glo_ctrl.in_auto_key_retrieve--; - free_keyserver_spec (spec); - } - xfree (uri); - } - if (again) - goto retry; + uri = get_pka_info (name, fpr); + if (uri) + { + spec = parse_keyserver_uri (uri, 0, NULL, 0); + if (spec) + { + glo_ctrl.in_auto_key_retrieve++; + try=keyserver_import_fprint (fpr, 20, spec); + glo_ctrl.in_auto_key_retrieve--; + free_keyserver_spec (spec); + } + xfree (uri); + } + if (try==0) + goto retry; + } + + /* Try keyserver last as it is likely to be the slowest. + Strictly speaking, we don't need to only use a valid mailbox + for the getname search, but it helps cut down on a problem + with searching for something like "john" and getting a lot of + keys back. */ + if(!tried_ks + && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)) + { + tried_ks=1; + + if(keyserver_getname(name)==0) + goto retry; + } } free_strlist( namelist ); diff --git a/g10/gpgv.c b/g10/gpgv.c index dfd247da8..bd5820da7 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -291,6 +291,8 @@ keyserver_import_fprint (const byte *fprint, size_t fprint_len, return -1; } +int +keyserver_getname(const char *name) { return -1; } /* Stub: * No encryption here but mainproc links to these functions. diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index d64269030..3d2f46581 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -41,5 +41,6 @@ int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver); int keyserver_refresh(STRLIST users); int keyserver_search(STRLIST tokens); int keyserver_fetch(STRLIST urilist); +int keyserver_getname(const char *name); #endif /* !_KEYSERVER_INTERNAL_H_ */ diff --git a/g10/keyserver.c b/g10/keyserver.c index 6d9939a92..7b6bdae7a 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -43,10 +43,6 @@ #include "keyserver-internal.h" #include "util.h" -#define GET 0 -#define SEND 1 -#define SEARCH 2 - #define GPGKEYS_PREFIX "gpgkeys_" #if defined(HAVE_LIBCURL) || defined(FAKE_CURL) @@ -69,6 +65,8 @@ struct keyrec unsigned int lines; }; +enum ks_action {KS_UNKNOWN=0,KS_GET,KS_GETNAME,KS_SEND,KS_SEARCH}; + /* Tell remote processes about these options */ #define REMOTE_TELL (KEYSERVER_INCLUDE_REVOKED|KEYSERVER_INCLUDE_SUBKEYS|KEYSERVER_TRY_DNS_SRV) @@ -96,8 +94,9 @@ static struct parse_options keyserver_opts[]= {NULL,0,NULL,NULL} }; -static int keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, - int count,struct keyserver_spec *keyserver); +static int keyserver_work(enum ks_action action,STRLIST list, + KEYDB_SEARCH_DESC *desc,int count, + struct keyserver_spec *keyserver); int parse_keyserver_options(char *options) @@ -679,7 +678,7 @@ show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) while((num=strsep(&split," ,"))!=NULL) if(atoi(num)>=1 && atoi(num)<=numdesc) - keyserver_work(GET,NULL,&desc[atoi(num)-1],1,opt.keyserver); + keyserver_work(KS_GET,NULL,&desc[atoi(num)-1],1,opt.keyserver); xfree(answer); return 1; @@ -880,7 +879,7 @@ curl_cant_handle(const char *scheme,unsigned int direct_uri) #define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\"" static int -keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, +keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc, int count,int *prog,struct keyserver_spec *keyserver) { int ret=0,i,gotversion=0,outofband=0; @@ -1014,7 +1013,7 @@ keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, switch(action) { - case GET: + case KS_GET: { fprintf(spawn->tochild,"COMMAND GET\n\n"); @@ -1080,7 +1079,29 @@ keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, break; } - case SEND: + case KS_GETNAME: + { + STRLIST key; + + fprintf(spawn->tochild,"COMMAND GETNAME\n\n"); + + /* Which names do we want? */ + + for(key=list;key!=NULL;key=key->next) + fprintf(spawn->tochild,"%s\n",key->d); + + fprintf(spawn->tochild,"\n"); + + if(keyserver->host) + log_info(_("searching for names from %s server %s\n"), + keyserver->scheme,keyserver->host); + else + log_info(_("searching for names from %s\n"),keyserver->uri); + + break; + } + + case KS_SEND: { STRLIST key; @@ -1240,7 +1261,7 @@ keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, break; } - case SEARCH: + case KS_SEARCH: { STRLIST key; @@ -1344,7 +1365,8 @@ keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, if(!outofband) switch(action) { - case GET: + case KS_GET: + case KS_GETNAME: { void *stats_handle; @@ -1367,10 +1389,10 @@ keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, } /* Nothing to do here */ - case SEND: + case KS_SEND: break; - case SEARCH: + case KS_SEARCH: keyserver_search_prompt(spawn->fromchild,searchstr); break; @@ -1390,7 +1412,7 @@ keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, } static int -keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, +keyserver_work(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc, int count,struct keyserver_spec *keyserver) { int rc=0,ret=0; @@ -1422,8 +1444,8 @@ keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc, case KEYSERVER_NOT_SUPPORTED: log_error(_("action `%s' not supported with keyserver " "scheme `%s'\n"), - action==GET?"get":action==SEND?"send": - action==SEARCH?"search":"unknown", + action==KS_GET?"get":action==KS_SEND?"send": + action==KS_SEARCH?"search":"unknown", keyserver->scheme); break; @@ -1483,7 +1505,7 @@ keyserver_export(STRLIST users) if(sl) { - rc=keyserver_work(SEND,sl,NULL,0,opt.keyserver); + rc=keyserver_work(KS_SEND,sl,NULL,0,opt.keyserver); free_strlist(sl); } @@ -1521,7 +1543,7 @@ keyserver_import(STRLIST users) } if(count>0) - rc=keyserver_work(GET,NULL,desc,count,opt.keyserver); + rc=keyserver_work(KS_GET,NULL,desc,count,opt.keyserver); xfree(desc); @@ -1545,7 +1567,7 @@ keyserver_import_fprint(const byte *fprint,size_t fprint_len, memcpy(desc.u.fpr,fprint,fprint_len); - return keyserver_work(GET,NULL,&desc,1,keyserver); + return keyserver_work(KS_GET,NULL,&desc,1,keyserver); } int @@ -1559,7 +1581,7 @@ keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver) desc.u.kid[0]=keyid[0]; desc.u.kid[1]=keyid[1]; - return keyserver_work(GET,NULL,&desc,1,keyserver); + return keyserver_work(KS_GET,NULL,&desc,1,keyserver); } /* code mostly stolen from do_export_stream */ @@ -1763,7 +1785,7 @@ keyserver_refresh(STRLIST users) Note that a preferred keyserver without a scheme:// will be interpreted as hkp:// */ - rc=keyserver_work(GET,NULL,&desc[i],1,keyserver); + rc=keyserver_work(KS_GET,NULL,&desc[i],1,keyserver); if(rc) log_info(_("WARNING: unable to refresh key %s" " via %s: %s\n"),keystr_from_desc(&desc[i]), @@ -1793,7 +1815,7 @@ keyserver_refresh(STRLIST users) count,opt.keyserver->uri); } - rc=keyserver_work(GET,NULL,desc,numdesc,opt.keyserver); + rc=keyserver_work(KS_GET,NULL,desc,numdesc,opt.keyserver); } xfree(desc); @@ -1812,7 +1834,7 @@ int keyserver_search(STRLIST tokens) { if(tokens) - return keyserver_work(SEARCH,tokens,NULL,0,opt.keyserver); + return keyserver_work(KS_SEARCH,tokens,NULL,0,opt.keyserver); else return 0; } @@ -1852,7 +1874,7 @@ keyserver_fetch(STRLIST urilist) */ spec->flags.direct_uri=1; - rc=keyserver_work(GET,NULL,&desc,1,spec); + rc=keyserver_work(KS_GET,NULL,&desc,1,spec); if(rc) log_info (_("WARNING: unable to fetch URI %s: %s\n"), sl->d,g10_errstr(rc)); @@ -1872,3 +1894,18 @@ keyserver_fetch(STRLIST urilist) return 0; } + +int +keyserver_getname(const char *name) +{ + STRLIST list=NULL; + int rc; + + append_to_strlist(&list,name); + + rc=keyserver_work(KS_GETNAME,list,NULL,0,opt.keyserver); + + free_strlist(list); + + return rc; +}