1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-26 01:52:45 +02:00

* gpgkeys_ldap.c (key_in_keylist, add_key_to_keylist, free_keylist,

get_key, search_key): The LDAP keyserver doesn't remove duplicates, so
remove them locally.  Do not include the key modification time in the
search response.
This commit is contained in:
David Shaw 2002-11-05 22:08:02 +00:00
parent 6920513cb4
commit ec0d9a416e
2 changed files with 309 additions and 215 deletions

View File

@ -1,3 +1,10 @@
2002-11-05 David Shaw <dshaw@jabberwocky.com>
* gpgkeys_ldap.c (key_in_keylist, add_key_to_keylist,
free_keylist, get_key, search_key): The LDAP keyserver doesn't
remove duplicates, so remove them locally. Do not include the key
modification time in the search response.
2002-11-04 David Shaw <dshaw@jabberwocky.com> 2002-11-04 David Shaw <dshaw@jabberwocky.com>
* gpgkeys_hkp.c (send_key), gpgkeys_ldap.c (send_key): Properly * gpgkeys_hkp.c (send_key), gpgkeys_ldap.c (send_key): Properly

View File

@ -106,6 +106,54 @@ ldap_to_gpg_err(LDAP *ld)
#endif #endif
} }
int
key_in_keylist(const char *key,struct keylist *list)
{
struct keylist *keyptr=list;
while(keyptr!=NULL)
{
if(strcasecmp(key,keyptr->str)==0)
return 1;
keyptr=keyptr->next;
}
return 0;
}
int
add_key_to_keylist(const char *key,struct keylist **list)
{
struct keylist *keyptr=malloc(sizeof(struct keylist));
if(keyptr==NULL)
{
fprintf(console,"gpgkeys: out of memory when deduping "
"key list\n");
return KEYSERVER_NO_MEMORY;
}
strncpy(keyptr->str,key,MAX_LINE);
keyptr->str[MAX_LINE-1]='\0';
keyptr->next=*list;
*list=keyptr;
return 0;
}
void
free_keylist(struct keylist *list)
{
while(list!=NULL)
{
struct keylist *keyptr=list;
list=keyptr->next;
free(keyptr);
}
}
int int
send_key(int *eof) send_key(int *eof)
{ {
@ -220,7 +268,6 @@ send_key(int *eof)
int int
get_key(char *getkey) get_key(char *getkey)
{ {
char **vals;
LDAPMessage *res,*each; LDAPMessage *res,*each;
int ret=KEYSERVER_INTERNAL_ERROR,err,count; int ret=KEYSERVER_INTERNAL_ERROR,err,count;
struct keylist *dupelist=NULL; struct keylist *dupelist=NULL;
@ -316,55 +363,32 @@ get_key(char *getkey)
each=ldap_first_entry(ldap,res); each=ldap_first_entry(ldap,res);
while(each!=NULL) while(each!=NULL)
{ {
struct keylist *keyptr=dupelist; char **vals,**certid;
/* Use the long keyid to remove duplicates. The LDAP server /* Use the long keyid to remove duplicates. The LDAP server
returns the same keyid more than once if there are returns the same keyid more than once if there are
multiple user IDs on the key. Note that this does NOT multiple user IDs on the key. Note that this does NOT
mean that a keyid that exists multiple times on the mean that a keyid that exists multiple times on the
keyserver will not be fetched. It means that each KEY, keyserver will not be fetched. It means that each KEY,
no matter how many user IDs share it's keyid, will be no matter how many user IDs share its keyid, will be
fetched only once. If a keyid that belongs to more than fetched only once. If a keyid that belongs to more than
one key is fetched, the server quite properly responds one key is fetched, the server quite properly responds
with all matching keys. -ds */ with all matching keys. -ds */
vals=ldap_get_values(ldap,each,"pgpcertid"); certid=ldap_get_values(ldap,each,"pgpcertid");
if(vals!=NULL) if(certid!=NULL)
{ {
while(keyptr!=NULL) if(!key_in_keylist(certid[0],dupelist))
{
if(strcasecmp(keyptr->str,vals[0])==0)
break;
keyptr=keyptr->next;
}
if(!keyptr)
{ {
/* it's not a duplicate, so add it */ /* it's not a duplicate, so add it */
keyptr=malloc(sizeof(struct keylist)); int rc=add_key_to_keylist(vals[0],&dupelist);
if(keyptr==NULL) if(rc)
{ {
fprintf(console,"gpgkeys: out of memory when deduping " ret=rc;
"key list\n");
ret=KEYSERVER_NO_MEMORY;
goto fail; goto fail;
} }
strncpy(keyptr->str,vals[0],MAX_LINE);
keyptr->str[MAX_LINE-1]='\0';
keyptr->next=dupelist;
dupelist=keyptr;
keyptr=NULL;
}
ldap_value_free(vals);
}
if(!keyptr) /* it's not a duplicate */
{
if(verbose) if(verbose)
{ {
vals=ldap_get_values(ldap,each,"pgpuserid"); vals=ldap_get_values(ldap,each,"pgpuserid");
@ -401,12 +425,7 @@ get_key(char *getkey)
ldap_value_free(vals); ldap_value_free(vals);
} }
vals=ldap_get_values(ldap,each,"pgpcertid"); fprintf(console,"Long key ID:\t%s\n",certid[0]);
if(vals!=NULL)
{
fprintf(console,"Long key ID:\t%s\n",vals[0]);
ldap_value_free(vals);
}
/* YYYYMMDDHHmmssZ */ /* YYYYMMDDHHmmssZ */
@ -461,6 +480,9 @@ get_key(char *getkey)
} }
} }
ldap_value_free(certid);
}
each=ldap_next_entry(ldap,each); each=ldap_next_entry(ldap,each);
} }
} }
@ -469,15 +491,7 @@ get_key(char *getkey)
fail: fail:
ldap_msgfree(res); ldap_msgfree(res);
free_keylist(dupelist);
/* free up the dupe checker */
while(dupelist!=NULL)
{
struct keylist *keyptr=dupelist;
dupelist=keyptr->next;
free(keyptr);
}
return ret; return ret;
} }
@ -527,7 +541,8 @@ search_key(char *searchkey)
{ {
char **vals; char **vals;
LDAPMessage *res,*each; LDAPMessage *res,*each;
int err,count; int err,count=0;
struct keylist *dupelist=NULL;
/* The maxium size of the search, including the optional stuff and /* The maxium size of the search, including the optional stuff and
the trailing \0 */ the trailing \0 */
char search[2+12+MAX_LINE+2+15+14+1+1]; char search[2+12+MAX_LINE+2+15+14+1+1];
@ -563,7 +578,34 @@ search_key(char *searchkey)
return errtag; return errtag;
} }
count=ldap_count_entries(ldap,res); /* The LDAP server doesn't return a real count of unique keys, so we
can't use ldap_count_entries here. */
each=ldap_first_entry(ldap,res);
while(each!=NULL)
{
char **certid=ldap_get_values(ldap,each,"pgpcertid");
if(certid!=NULL)
{
if(!key_in_keylist(certid[0],dupelist))
{
int rc=add_key_to_keylist(certid[0],&dupelist);
if(rc!=0)
{
fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
free_keylist(dupelist);
return rc;
}
count++;
}
}
each=ldap_next_entry(ldap,each);
}
free_keylist(dupelist);
dupelist=NULL;
if(count<1) if(count<1)
fprintf(output,"info:1:0\n"); fprintf(output,"info:1:0\n");
@ -574,21 +616,33 @@ search_key(char *searchkey)
each=ldap_first_entry(ldap,res); each=ldap_first_entry(ldap,res);
while(each!=NULL) while(each!=NULL)
{ {
fprintf(output,"pub:"); char **certid;
vals=ldap_get_values(ldap,each,"pgpcertid"); certid=ldap_get_values(ldap,each,"pgpcertid");
if(vals!=NULL) if(certid!=NULL)
{ {
fprintf(output,"%s",vals[0]); LDAPMessage *uids;
ldap_value_free(vals);
/* Have we seen this certid before? */
if(!key_in_keylist(certid[0],dupelist))
{
int rc=add_key_to_keylist(certid[0],&dupelist);
if(rc)
{
fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
free_keylist(dupelist);
ldap_value_free(certid);
ldap_msgfree(res);
return rc;
} }
fputc(':',output); fprintf(output,"pub:%s:",certid[0]);
vals=ldap_get_values(ldap,each,"pgpkeytype"); vals=ldap_get_values(ldap,each,"pgpkeytype");
if(vals!=NULL) if(vals!=NULL)
{ {
/* The LDAP server doesn't exactly handle this well. */ /* The LDAP server doesn't exactly handle this
well. */
if(strcasecmp(vals[0],"RSA")==0) if(strcasecmp(vals[0],"RSA")==0)
fprintf(output,"1"); fprintf(output,"1");
else if(strcasecmp(vals[0],"DSS/DH")==0) else if(strcasecmp(vals[0],"DSS/DH")==0)
@ -601,8 +655,9 @@ search_key(char *searchkey)
vals=ldap_get_values(ldap,each,"pgpkeysize"); vals=ldap_get_values(ldap,each,"pgpkeysize");
if(vals!=NULL) if(vals!=NULL)
{ {
/* Not sure why, but some keys are listed with a key size of /* Not sure why, but some keys are listed with a
0. Treat that like an unknown. */ key size of 0. Treat that like an
unknown. */
if(atoi(vals[0])>0) if(atoi(vals[0])>0)
fprintf(output,"%d",atoi(vals[0])); fprintf(output,"%d",atoi(vals[0]));
ldap_value_free(vals); ldap_value_free(vals);
@ -615,7 +670,8 @@ search_key(char *searchkey)
vals=ldap_get_values(ldap,each,"pgpkeycreatetime"); vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
if(vals!=NULL && strlen(vals[0])==15) if(vals!=NULL && strlen(vals[0])==15)
{ {
fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0])); fprintf(output,"%u",
(unsigned int)ldap2epochtime(vals[0]));
ldap_value_free(vals); ldap_value_free(vals);
} }
@ -624,7 +680,8 @@ search_key(char *searchkey)
vals=ldap_get_values(ldap,each,"pgpkeyexpiretime"); vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
if(vals!=NULL && strlen(vals[0])==15) if(vals!=NULL && strlen(vals[0])==15)
{ {
fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0])); fprintf(output,"%u",
(unsigned int)ldap2epochtime(vals[0]));
ldap_value_free(vals); ldap_value_free(vals);
} }
@ -646,32 +703,62 @@ search_key(char *searchkey)
ldap_value_free(vals); ldap_value_free(vals);
} }
#if 0
/* This is not yet specified in the keyserver
protocol, but may be someday. */
fputc(':',output); fputc(':',output);
vals=ldap_get_values(ldap,each,"modifytimestamp"); vals=ldap_get_values(ldap,each,"modifytimestamp");
if(vals!=NULL && strlen(vals[0])==15) if(vals!=NULL && strlen(vals[0])==15)
{ {
fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0])); fprintf(output,"%u",
(unsigned int)ldap2epochtime(vals[0]));
ldap_value_free(vals); ldap_value_free(vals);
} }
#endif
fprintf(output,"\nuid:"); fprintf(output,"\n");
vals=ldap_get_values(ldap,each,"pgpuserid"); /* Now print all the uids that have this certid */
uids=ldap_first_entry(ldap,res);
while(uids!=NULL)
{
vals=ldap_get_values(ldap,uids,"pgpcertid");
if(vals!=NULL) if(vals!=NULL)
{
if(strcasecmp(certid[0],vals[0])==0)
{
char **uidvals;
fprintf(output,"uid:");
uidvals=ldap_get_values(ldap,uids,"pgpuserid");
if(uidvals!=NULL)
{ {
/* Need to escape any colons */ /* Need to escape any colons */
printquoted(output,vals[0],':'); printquoted(output,uidvals[0],':');
ldap_value_free(vals); ldap_value_free(uidvals);
} }
fprintf(output,"\n"); fprintf(output,"\n");
}
ldap_value_free(vals);
}
uids=ldap_next_entry(ldap,uids);
}
}
ldap_value_free(certid);
}
each=ldap_next_entry(ldap,each); each=ldap_next_entry(ldap,each);
} }
} }
ldap_msgfree(res); ldap_msgfree(res);
free_keylist(dupelist);
fprintf(output,"SEARCH %s END\n",searchkey); fprintf(output,"SEARCH %s END\n",searchkey);