diff options
author | David Shaw <[email protected]> | 2005-12-23 20:51:48 +0000 |
---|---|---|
committer | David Shaw <[email protected]> | 2005-12-23 20:51:48 +0000 |
commit | da9a10d2b040ba99cb0f4fab2acb19b7ec662637 (patch) | |
tree | bfa496982cb80ba5176171ab8eaaab5fc5aadf21 | |
parent | New code to do DNS CERT queries. (diff) | |
download | gnupg-da9a10d2b040ba99cb0f4fab2acb19b7ec662637.tar.gz gnupg-da9a10d2b040ba99cb0f4fab2acb19b7ec662637.zip |
* ksutil.h, ksutil.c (parse_ks_options): New keyserver command "getname".
* gpgkeys_hkp.c (main, get_name), gpgkeys_ldap.c (main, get_name): Use it
here to do direct name (rather than key ID) fetches.
-rw-r--r-- | keyserver/ChangeLog | 8 | ||||
-rw-r--r-- | keyserver/gpgkeys_hkp.c | 98 | ||||
-rw-r--r-- | keyserver/gpgkeys_ldap.c | 159 | ||||
-rw-r--r-- | keyserver/ksutil.c | 3 | ||||
-rw-r--r-- | keyserver/ksutil.h | 4 |
5 files changed, 252 insertions, 20 deletions
diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog index 6ce2c7332..beade08f1 100644 --- a/keyserver/ChangeLog +++ b/keyserver/ChangeLog @@ -1,3 +1,11 @@ +2005-12-23 David Shaw <[email protected]> + + * ksutil.h, ksutil.c (parse_ks_options): New keyserver command + "getname". + + * gpgkeys_hkp.c (main, get_name), gpgkeys_ldap.c (main, get_name): + Use it here to do direct name (rather than key ID) fetches. + 2005-12-19 David Shaw <[email protected]> * ksutil.h, ksutil.c (curl_armor_writer, curl_writer, diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index d51c659ff..6d6ca518e 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -285,11 +285,90 @@ get_key(char *getkey) } static int +get_name(const char *getkey) +{ + CURLcode res; + char *request=NULL; + char *searchkey_encoded; + int ret=KEYSERVER_INTERNAL_ERROR; + struct curl_writer_ctx ctx; + + memset(&ctx,0,sizeof(ctx)); + + searchkey_encoded=curl_escape((char *)getkey,0); + if(!searchkey_encoded) + { + fprintf(console,"gpgkeys: out of memory\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + request=malloc(MAX_URL+60+strlen(searchkey_encoded)); + if(!request) + { + fprintf(console,"gpgkeys: out of memory\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + fprintf(output,"NAME %s BEGIN\n",getkey); + + strcpy(request,"http://"); + strcat(request,opt->host); + strcat(request,":"); + if(opt->port) + strcat(request,opt->port); + else + strcat(request,"11371"); + strcat(request,opt->path); + append_path(request,"/pks/lookup?op=get&options=mr&search="); + strcat(request,searchkey_encoded); + + if(opt->verbose>2) + fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request); + + curl_easy_setopt(curl,CURLOPT_URL,request); + curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer); + ctx.stream=output; + curl_easy_setopt(curl,CURLOPT_FILE,&ctx); + + res=curl_easy_perform(curl); + if(res!=CURLE_OK) + { + fprintf(console,"gpgkeys: HTTP fetch error %d: %s\n",res,errorbuffer); + ret=curl_err_to_gpg_err(res); + } + else + { + curl_writer_finalize(&ctx); + if(!ctx.flags.done) + { + fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); + ret=KEYSERVER_KEY_NOT_FOUND; + } + else + { + fprintf(output,"\nNAME %s END\n",getkey); + ret=KEYSERVER_OK; + } + } + + fail: + curl_free(searchkey_encoded); + free(request); + + if(ret!=KEYSERVER_OK) + fprintf(output,"\nNAME %s FAILED %d\n",getkey,ret); + + return ret; +} + +static int search_key(const char *searchkey) { CURLcode res; char *request=NULL; - char *searchkey_encoded=NULL; + char *searchkey_encoded; int ret=KEYSERVER_INTERNAL_ERROR; enum ks_search_type search_type; @@ -570,7 +649,8 @@ main(int argc,char *argv[]) if(opt->action==KS_SEND) while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n'); - else if(opt->action==KS_GET || opt->action==KS_SEARCH) + else if(opt->action==KS_GET + || opt->action==KS_GETNAME || opt->action==KS_SEARCH) { for(;;) { @@ -645,6 +725,20 @@ main(int argc,char *argv[]) keyptr=keyptr->next; } } + else if(opt->action==KS_GETNAME) + { + keyptr=keylist; + + while(keyptr!=NULL) + { + set_timeout(opt->timeout); + + if(get_name(keyptr->str)!=KEYSERVER_OK) + failed++; + + keyptr=keyptr->next; + } + } else if(opt->action==KS_SEND) { int eof=0; diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c index a483e2760..74555b8e0 100644 --- a/keyserver/gpgkeys_ldap.c +++ b/keyserver/gpgkeys_ldap.c @@ -1116,20 +1116,6 @@ get_key(char *getkey) return ret; } -static void -printquoted(FILE *stream,char *string,char delim) -{ - while(*string) - { - if(*string==delim || *string=='%') - fprintf(stream,"%%%02x",*string); - else - fputc(*string,stream); - - string++; - } -} - #define LDAP_ESCAPE_CHARS "*()\\" static int @@ -1164,6 +1150,132 @@ ldap_quote(char *buffer,const char *string) return count; } +/* Note that key-not-found is not a fatal error */ +static int +get_name(char *getkey) +{ + LDAPMessage *res,*each; + int ret=KEYSERVER_INTERNAL_ERROR,err,count; + char *expanded_search; + /* The maximum size of the search, including the optional stuff and + the trailing \0 */ + char search[2+11+3+MAX_LINE+2+15+14+1+1+20]; + /* This ordering is significant - specifically, "pgpcertid" needs to + be the second item in the list, since everything after it may be + discarded if the user isn't in verbose mode. */ + char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked", + "pgpdisabled","pgpkeycreatetime","modifytimestamp", + "pgpkeysize","pgpkeytype",NULL}; + attrs[0]=pgpkeystr; /* Some compilers don't like using variables as + array initializers. */ + + expanded_search=malloc(ldap_quote(NULL,getkey)+1); + if(!expanded_search) + { + fprintf(output,"NAME %s FAILED %d\n",getkey,KEYSERVER_NO_MEMORY); + fprintf(console,"Out of memory when quoting LDAP search string\n"); + return KEYSERVER_NO_MEMORY; + } + + ldap_quote(expanded_search,getkey); + + /* Build the search string */ + + sprintf(search,"%s(pgpuserid=*%s*)%s%s%s", + (!(opt->flags.include_disabled&&opt->flags.include_revoked))?"(&":"", + expanded_search, + opt->flags.include_disabled?"":"(pgpdisabled=0)", + opt->flags.include_revoked?"":"(pgprevoked=0)", + !(opt->flags.include_disabled&&opt->flags.include_revoked)?")":""); + + free(expanded_search); + + if(opt->verbose>2) + fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search); + + if(!opt->verbose) + attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */ + + err=ldap_search_s(ldap,basekeyspacedn, + LDAP_SCOPE_SUBTREE,search,attrs,0,&res); + if(err!=0) + { + int errtag=ldap_err_to_gpg_err(err); + + fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err)); + fprintf(output,"NAME %s BEGIN\n",getkey); + fprintf(output,"NAME %s FAILED %d\n",getkey,errtag); + return errtag; + } + + count=ldap_count_entries(ldap,res); + if(count<1) + { + fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); + fprintf(output,"NAME %s BEGIN\n",getkey); + fprintf(output,"NAME %s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND); + } + else + { + /* There may be more than one result, but we return them all. */ + + each=ldap_first_entry(ldap,res); + while(each!=NULL) + { + char **vals,**certid; + + certid=ldap_get_values(ldap,each,"pgpcertid"); + if(certid!=NULL) + { + build_info(certid[0],each); + + fprintf(output,"NAME %s BEGIN\n",getkey); + + vals=ldap_get_values(ldap,each,pgpkeystr); + if(vals==NULL) + { + int errtag=ldap_to_gpg_err(ldap); + + fprintf(console,"gpgkeys: unable to retrieve key %s " + "from keyserver\n",getkey); + fprintf(output,"NAME %s FAILED %d\n",getkey,errtag); + } + else + { + print_nocr(output,vals[0]); + fprintf(output,"\nNAME %s END\n",getkey); + + ldap_value_free(vals); + } + + ldap_value_free(certid); + } + + each=ldap_next_entry(ldap,each); + } + } + + ret=KEYSERVER_OK; + + ldap_msgfree(res); + + return ret; +} + +static void +printquoted(FILE *stream,char *string,char delim) +{ + while(*string) + { + if(*string==delim || *string=='%') + fprintf(stream,"%%%02x",*string); + else + fputc(*string,stream); + + string++; + } +} + /* Returns 0 on success and -1 on error. Note that key-not-found is not an error! */ static int @@ -1173,9 +1285,9 @@ search_key(const char *searchkey) LDAPMessage *res,*each; int err,count=0; struct keylist *dupelist=NULL; + char *expanded_search; /* The maximum size of the search, including the optional stuff and the trailing \0 */ - char *expanded_search; char search[2+11+3+MAX_LINE+2+15+14+1+1+20]; char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled", "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp", @@ -1794,7 +1906,8 @@ main(int argc,char *argv[]) if(opt->action==KS_SEND) while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n'); - else if(opt->action==KS_GET || opt->action==KS_SEARCH) + else if(opt->action==KS_GET + || opt->action==KS_GETNAME || opt->action==KS_SEARCH) { for(;;) { @@ -2018,6 +2131,20 @@ main(int argc,char *argv[]) keyptr=keyptr->next; } } + else if(opt->action==KS_GETNAME) + { + keyptr=keylist; + + while(keyptr!=NULL) + { + set_timeout(opt->timeout); + + if(get_name(keyptr->str)!=KEYSERVER_OK) + failed++; + + keyptr=keyptr->next; + } + } else if(opt->action==KS_SEND) { int eof=0; diff --git a/keyserver/ksutil.c b/keyserver/ksutil.c index 8ea2a1ab4..8df684ed9 100644 --- a/keyserver/ksutil.c +++ b/keyserver/ksutil.c @@ -140,6 +140,8 @@ parse_ks_options(char *line,struct ks_options *opt) if(strcasecmp(command,"get")==0) opt->action=KS_GET; + else if(strcasecmp(command,"getname")==0) + opt->action=KS_GETNAME; else if(strcasecmp(command,"send")==0) opt->action=KS_SEND; else if(strcasecmp(command,"search")==0) @@ -311,6 +313,7 @@ ks_action_to_string(enum ks_action action) { case KS_UNKNOWN: return "UNKNOWN"; case KS_GET: return "GET"; + case KS_GETNAME: return "GETNAME"; case KS_SEND: return "SEND"; case KS_SEARCH: return "SEARCH"; } diff --git a/keyserver/ksutil.h b/keyserver/ksutil.h index 4dd60a7aa..b5e67bb63 100644 --- a/keyserver/ksutil.h +++ b/keyserver/ksutil.h @@ -36,7 +36,7 @@ strlen("OPAQUE")+1+sizeof_opaque+1 */ #define MAX_LINE (6+1+1024+1) -#define MAX_COMMAND 6 +#define MAX_COMMAND 7 #define MAX_OPTION 256 #define MAX_SCHEME 20 #define MAX_OPAQUE 1024 @@ -72,7 +72,7 @@ struct keylist unsigned int set_timeout(unsigned int seconds); int register_timeout(void); -enum ks_action {KS_UNKNOWN=0,KS_GET,KS_SEND,KS_SEARCH}; +enum ks_action {KS_UNKNOWN=0,KS_GET,KS_GETNAME,KS_SEND,KS_SEARCH}; enum ks_search_type {KS_SEARCH_SUBSTR,KS_SEARCH_EXACT, KS_SEARCH_MAIL,KS_SEARCH_MAILSUB}; |