diff options
author | David Shaw <[email protected]> | 2001-12-20 19:59:36 +0000 |
---|---|---|
committer | David Shaw <[email protected]> | 2001-12-20 19:59:36 +0000 |
commit | fe4d663d333439bede78053faecae87c053daef2 (patch) | |
tree | f00161f1cef0f4e05e29040eb70b1d595e1b3436 | |
parent | Only gpg (not gpgv) needs mkdtemp (diff) | |
download | gnupg-fe4d663d333439bede78053faecae87c053daef2.tar.gz gnupg-fe4d663d333439bede78053faecae87c053daef2.zip |
Handle multiple keys with the same key id (rare)
Some minor other tweaks
-rw-r--r-- | keyserver/ChangeLog | 11 | ||||
-rw-r--r-- | keyserver/gpgkeys_ldap.c | 236 |
2 files changed, 167 insertions, 80 deletions
diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog index 993f2abeb..99ad7c5d0 100644 --- a/keyserver/ChangeLog +++ b/keyserver/ChangeLog @@ -1,3 +1,14 @@ +2001-12-20 David Shaw <[email protected]> + + * Properly free the LDAP response when we're done with it. + + * Now that we handle multiple keys, we must remove duplicates as + the LDAP keyserver returns keys with multiple user IDs multiple + times. + + * Properly handle multiple keys with the same key ID (it's really + rare, so fetch "0xDEADBEEF" to test this). + 2001-12-17 David Shaw <[email protected]> * gpgkeys_ldap.c, gpgkeys_mailto.in: Fix GNU capitalization diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c index 1ce6dda61..4e8467b04 100644 --- a/keyserver/gpgkeys_ldap.c +++ b/keyserver/gpgkeys_ldap.c @@ -40,12 +40,13 @@ int verbose=0,include_disabled=0,include_revoked=0; char *basekeyspacedn=NULL; char host[80]; +FILE *input=NULL,*output=NULL,*console=NULL; + struct keylist { char *keystr; struct keylist *next; }; -FILE *input=NULL,*output=NULL,*console=NULL; /* Returns 0 on success, -1 on failure, and 1 on eof */ int send_key(LDAP *ldap,char *keyid) @@ -152,8 +153,9 @@ int send_key(LDAP *ldap,char *keyid) int get_key(LDAP *ldap,char *getkey) { char **vals; - LDAPMessage *res; - int err,count,i; + LDAPMessage *res,*each; + int ret=-1,err,count; + struct keylist *dupelist=NULL; char search[29]; char *attrs[]={"pgpKeyV2","pgpuserid","pgpkeyid","pgpcertid","pgprevoked", "pgpdisabled","pgpkeycreatetime","modifytimestamp", @@ -180,8 +182,7 @@ int get_key(LDAP *ldap,char *getkey) if(!verbose) attrs[1]=NULL; - fprintf(console, - "gpgkeys: requesting key %s from LDAP keyserver %s\n", + fprintf(console,"gpgkeys: requesting key %s from LDAP keyserver %s\n", getkey,host); err=ldap_search_s(ldap,basekeyspacedn, @@ -198,104 +199,172 @@ int get_key(LDAP *ldap,char *getkey) { fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); fprintf(output,"KEY 0x%s FAILED\n",getkey); - return -1; + goto fail; } - /* There may be more than one result for a given keyID, so we should - fetch them all. */ - for(i=0;i<count;i++) + /* There may be more than one unique result for a given keyID, so we + should fetch them all (test this by fetching short key id + 0xDEADBEEF). */ + + each=ldap_first_entry(ldap,res); + while(each!=NULL) { - if(verbose) - { - vals=ldap_get_values(ldap,res,"pgpuserid"); - if(vals!=NULL) - { - /* This is wrong, as the user ID is UTF8. A better way to - handle this would be to send it over to gpg and display - it on that side of the pipe. */ - fprintf(console,"\nUser ID:\t%s\n",vals[0]); - ldap_value_free(vals); - } + struct keylist *keyptr=dupelist; - vals=ldap_get_values(ldap,res,"pgprevoked"); - if(vals!=NULL) - { - if(atoi(vals[0])==1) - fprintf(console,"\t\t** KEY REVOKED **\n"); - ldap_value_free(vals); - } + /* Use the long keyid to remove duplicates. The LDAP server + returns the same keyid more than once if there are multiple + user IDs on the key. */ - vals=ldap_get_values(ldap,res,"pgpdisabled"); - if(vals!=NULL) + vals=ldap_get_values(ldap,each,"pgpcertid"); + if(vals!=NULL) + { + while(keyptr!=NULL) { - if(atoi(vals[0])==1) - fprintf(console,"\t\t** KEY DISABLED **\n"); - ldap_value_free(vals); - } + if(strcasecmp(keyptr->keystr,vals[0])==0) + break; - vals=ldap_get_values(ldap,res,"pgpkeyid"); - if(vals!=NULL) - { - fprintf(console,"Short key ID:\t%s\n",vals[0]); - ldap_value_free(vals); + keyptr=keyptr->next; } - vals=ldap_get_values(ldap,res,"pgpcertid"); - if(vals!=NULL) + if(!keyptr) { - fprintf(console,"Long key ID:\t%s\n",vals[0]); - ldap_value_free(vals); + /* it's not a duplicate, so add it */ + + keyptr=malloc(sizeof(struct keylist)); + if(keyptr==NULL) + { + fprintf(console,"gpgkeys: out of memory when deduping " + "key list\n"); + goto fail; + } + + keyptr->keystr=strdup(vals[0]); + if(keyptr->keystr==NULL) + { + fprintf(console,"gpgkeys: out of memory when deduping " + "key list\n"); + goto fail; + } + + keyptr->next=dupelist; + dupelist=keyptr; + keyptr=NULL; } - /* YYYYMMDDHHmmssZ */ + ldap_value_free(vals); + } - vals=ldap_get_values(ldap,res,"pgpkeycreatetime"); - if(vals!=NULL && strlen(vals[0])==15) + if(!keyptr) /* it's not a duplicate */ + { + if(verbose) { - fprintf(console,"Key created:\t%.2s/%.2s/%.4s\n", - &vals[0][4],&vals[0][6],vals[0]); - ldap_value_free(vals); + vals=ldap_get_values(ldap,each,"pgpuserid"); + if(vals!=NULL) + { + /* This is wrong, as the user ID is UTF8. A better way to + handle this would be to send it over to gpg and display + it on that side of the pipe. */ + fprintf(console,"\nUser ID:\t%s\n",vals[0]); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"pgprevoked"); + if(vals!=NULL) + { + if(atoi(vals[0])==1) + fprintf(console,"\t\t** KEY REVOKED **\n"); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"pgpdisabled"); + if(vals!=NULL) + { + if(atoi(vals[0])==1) + fprintf(console,"\t\t** KEY DISABLED **\n"); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"pgpkeyid"); + if(vals!=NULL) + { + fprintf(console,"Short key ID:\t%s\n",vals[0]); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"pgpcertid"); + if(vals!=NULL) + { + fprintf(console,"Long key ID:\t%s\n",vals[0]); + ldap_value_free(vals); + } + + /* YYYYMMDDHHmmssZ */ + + vals=ldap_get_values(ldap,each,"pgpkeycreatetime"); + if(vals!=NULL && strlen(vals[0])==15) + { + fprintf(console,"Key created:\t%.2s/%.2s/%.4s\n", + &vals[0][4],&vals[0][6],vals[0]); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"modifytimestamp"); + if(vals!=NULL && strlen(vals[0])==15) + { + fprintf(console,"Key modified:\t%.2s/%.2s/%.4s\n", + &vals[0][4],&vals[0][6],vals[0]); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"pgpkeysize"); + if(vals!=NULL) + { + fprintf(console,"Key size:\t%d\n",atoi(vals[0])); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"pgpkeytype"); + if(vals!=NULL) + { + fprintf(console,"Key type:\t%s\n",vals[0]); + ldap_value_free(vals); + } } - vals=ldap_get_values(ldap,res,"modifytimestamp"); - if(vals!=NULL && strlen(vals[0])==15) + vals=ldap_get_values(ldap,each,"pgpKeyV2"); + if(vals==NULL) { - fprintf(console,"Key modified:\t%.2s/%.2s/%.4s\n", - &vals[0][4],&vals[0][6],vals[0]); - ldap_value_free(vals); + fprintf(console,"gpgkeys: unable to retrieve key %s " + "from keyserver\n",getkey); + fprintf(output,"KEY 0x%s FAILED\n",getkey); } - - vals=ldap_get_values(ldap,res,"pgpkeysize"); - if(vals!=NULL) + else { - fprintf(console,"Key size:\t%d\n",atoi(vals[0])); - ldap_value_free(vals); - } + fprintf(output,"%sKEY 0x%s END\n",vals[0],getkey); - vals=ldap_get_values(ldap,res,"pgpkeytype"); - if(vals!=NULL) - { - fprintf(console,"Key type:\t%s\n",vals[0]); ldap_value_free(vals); } } - vals=ldap_get_values(ldap,res,"pgpKeyV2"); - if(vals==NULL) - { - fprintf(console, - "gpgkeys: unable to retrieve key %s from keyserver\n",getkey); - fprintf(output,"KEY 0x%s FAILED\n",getkey); - } - else - { - fprintf(output,"%sKEY 0x%s END\n",vals[0],getkey); + each=ldap_next_entry(ldap,each); + } - ldap_value_free(vals); - } + ret=0; + + fail: + ldap_msgfree(res); + + /* free up the dupe checker */ + while(dupelist!=NULL) + { + struct keylist *keyptr=dupelist; + + dupelist=keyptr->next; + free(keyptr->keystr); + free(keyptr); } - return 0; + return ret; } time_t ldap2epochtime(const char *timestr) @@ -476,6 +545,8 @@ int search_key(LDAP *ldap,char *searchkey) } } + ldap_msgfree(res); + fprintf(output,"SEARCH %s END\n",searchkey); return 0; @@ -669,7 +740,8 @@ int main(int argc,char *argv[]) keyptr->next=malloc(sizeof(struct keylist)); if(keyptr->next==NULL) { - fprintf(console,"gpgkeys: out of memory when building key list\n"); + fprintf(console,"gpgkeys: out of memory when " + "building key list\n"); goto fail; } @@ -679,7 +751,8 @@ int main(int argc,char *argv[]) keyptr->keystr=malloc(MAX_LINE); if(keyptr->keystr==NULL) { - fprintf(console,"gpgkeys: out of memory when building key list\n"); + fprintf(console,"gpgkeys: out of memory when " + "building key list\n"); goto fail; } } @@ -699,7 +772,7 @@ int main(int argc,char *argv[]) { fprintf(console,"Host:\t\t%s\n",host); if(port) - fprintf(console,"Port:\t%d\n",port); + fprintf(console,"Port:\t\t%d\n",port); fprintf(console,"Command:\t%s\n",action==GET?"GET": action==SEND?"SEND":"SEARCH"); } @@ -762,13 +835,16 @@ int main(int argc,char *argv[]) basekeyspacedn=strdup(vals[0]); if(basekeyspacedn==NULL) { - fprintf(console,"gpgkeys: can't allocate string space for LDAP base\n"); + fprintf(console,"gpgkeys: can't allocate string space " + "for LDAP base\n"); goto fail; } ldap_value_free(vals); } + ldap_msgfree(res); + switch(action) { case GET: |