1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-23 10:29:58 +01:00

Clarify the notion of a partial failure. This is possible if more than

one key is being handled in a batch, and one fails while the other
succeeds.  Note that a search that comes up with no results is not a
failure - that is a valid response of "no answer".

Allow GnuPG to send us full v4 fingerprints, long key ids, or short key
ids while fetching. Since the LDAP server doesn't actually handle
fingerprints, chop them down to long key ids for actual use.

When searching for a keyid, search for subkeys as well as primary keys.
This is mostly significant when automatically fetching the key based on
the id in a header (i.e. "signature made by....").  "no-include-subkeys"
disables.
This commit is contained in:
David Shaw 2002-02-23 15:42:15 +00:00
parent 393ba4f8a7
commit 070f1cba5d
2 changed files with 227 additions and 163 deletions

View File

@ -1,3 +1,22 @@
2002-02-23 David Shaw <dshaw@jabberwocky.com>
* gpgkeys_ldap: Clarify the notion of a partial failure. This is
possible if more than one key is being handled in a batch, and one
fails while the other succeeds. Note that a search that comes up
with no results is not a failure - that is a valid response of "no
answer".
* gpgkeys_ldap.c (get_key): Allow GnuPG to send us full v4
fingerprints, long key ids, or short key ids while fetching.
Since the LDAP server doesn't actually handle fingerprints, chop
them down to long key ids for actual use.
* gpgkeys_ldap.c (main, get_key): When searching for a keyid,
search for subkeys as well as primary keys. This is mostly
significant when automatically fetching the key based on the id in
a header (i.e. "signature made by...."). "no-include-subkeys"
disables.
2002-02-14 David Shaw <dshaw@jabberwocky.com>
* gpgkeys_ldap.c: Fix compiler warning.

View File

@ -37,10 +37,11 @@
#define SEARCH 2
#define MAX_LINE 80
int verbose=0,include_disabled=0,include_revoked=0;
int verbose=0,include_disabled=0,include_revoked=0,include_subkeys=1;
char *basekeyspacedn=NULL;
char host[80];
FILE *input=NULL,*output=NULL,*console=NULL;
LDAP *ldap=NULL;
struct keylist
{
@ -49,12 +50,13 @@ struct keylist
};
/* Returns 0 on success, -1 on failure, and 1 on eof */
int send_key(LDAP *ldap,char *keyid)
int send_key(void)
{
int err,gotit=0,keysize=1,ret=-1;
char *dn=NULL;
char line[MAX_LINE];
char *key[2]={0,0};
char keyid[17];
#ifndef __riscos__
LDAPMod mod={LDAP_MOD_ADD,"pgpKeyV2",{key}},*attrs[2]={&mod,NULL};
#else
@ -148,31 +150,61 @@ int send_key(LDAP *ldap,char *keyid)
free(key[0]);
free(dn);
if(ret!=0)
fprintf(output,"KEY %s FAILED\n",keyid);
return ret;
}
int get_key(LDAP *ldap,char *getkey)
/* Returns 0 on success and -1 on failure. Note that key-not-found is
not an error! */
int get_key(char *getkey)
{
char **vals;
LDAPMessage *res,*each;
int ret=-1,err,count;
struct keylist *dupelist=NULL;
char search[29];
char search[62];
char *attrs[]={"pgpKeyV2","pgpuserid","pgpkeyid","pgpcertid","pgprevoked",
"pgpdisabled","pgpkeycreatetime","modifytimestamp",
"pgpkeysize","pgpkeytype",NULL};
/* Build the search string */
if(strncmp(getkey,"0x00000000",10)==0)
/* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3
or v4 short key id */
if(strncmp(getkey,"0x",2)==0)
getkey+=2;
if(strlen(getkey)>16)
{
getkey+=10;
sprintf(search,"(pgpkeyid=%.8s)",getkey);
char *offset=&getkey[strlen(getkey)-16];
/* fingerprint. Take the last 16 characters and treat it like a
long key id */
if(include_subkeys)
sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
offset,offset);
else
sprintf(search,"(pgpcertid=%.16s)",offset);
}
else if(strlen(getkey)>8)
{
/* long key id */
if(include_subkeys)
sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
getkey,getkey);
else
sprintf(search,"(pgpcertid=%.16s)",getkey);
}
else
{
getkey+=2;
sprintf(search,"(pgpcertid=%.16s)",getkey);
/* short key id */
sprintf(search,"(pgpkeyid=%.8s)",getkey);
}
fprintf(output,"KEY 0x%s BEGIN\n",getkey);
@ -183,7 +215,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 0x%s from LDAP keyserver %s\n",
getkey,host);
err=ldap_search_s(ldap,basekeyspacedn,
@ -200,149 +232,151 @@ 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);
goto fail;
}
/* 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)
else
{
struct keylist *keyptr=dupelist;
/* 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). */
/* 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,each,"pgpcertid");
if(vals!=NULL)
each=ldap_first_entry(ldap,res);
while(each!=NULL)
{
while(keyptr!=NULL)
struct keylist *keyptr=dupelist;
/* 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,each,"pgpcertid");
if(vals!=NULL)
{
if(strcasecmp(keyptr->str,vals[0])==0)
break;
keyptr=keyptr->next;
}
if(!keyptr)
{
/* it's not a duplicate, so add it */
keyptr=malloc(sizeof(struct keylist));
if(keyptr==NULL)
while(keyptr!=NULL)
{
fprintf(console,"gpgkeys: out of memory when deduping "
"key list\n");
goto fail;
if(strcasecmp(keyptr->str,vals[0])==0)
break;
keyptr=keyptr->next;
}
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)
{
vals=ldap_get_values(ldap,each,"pgpuserid");
if(vals!=NULL)
if(!keyptr)
{
/* 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);
/* 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;
}
strncpy(keyptr->str,vals[0],MAX_LINE);
keyptr->str[MAX_LINE-1]='\0';
keyptr->next=dupelist;
dupelist=keyptr;
keyptr=NULL;
}
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,each,"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);
ldap_value_free(vals);
}
}
each=ldap_next_entry(ldap,each);
if(!keyptr) /* it's not a duplicate */
{
if(verbose)
{
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,each,"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);
ldap_value_free(vals);
}
}
each=ldap_next_entry(ldap,each);
}
}
ret=0;
@ -398,7 +432,9 @@ void printquoted(FILE *stream,char *string,char delim)
}
}
int search_key(LDAP *ldap,char *searchkey)
/* Returns 0 on success and -1 on error. Note that key-not-found is
not an error! */
int search_key(char *searchkey)
{
char **vals;
LDAPMessage *res,*each;
@ -549,10 +585,9 @@ int search_key(LDAP *ldap,char *searchkey)
int main(int argc,char *argv[])
{
LDAP *ldap=NULL;
int port=0,arg,err,action=-1,ret=KEYSERVER_INTERNAL_ERROR;
char line[MAX_LINE],**vals;
int version;
int version,failed=0;
char *attrs[]={"basekeyspacedn","version","software",NULL};
LDAPMessage *res;
struct keylist *keylist=NULL,*keyptr=NULL;
@ -688,6 +723,13 @@ int main(int argc,char *argv[])
else
include_revoked=1;
}
else if(strcasecmp(start,"include-subkeys")==0)
{
if(no)
include_subkeys=0;
else
include_subkeys=1;
}
continue;
}
@ -832,27 +874,24 @@ int main(int argc,char *argv[])
while(keyptr!=NULL)
{
struct keylist *current=keyptr;
if(get_key(keyptr->str)==-1)
failed++;
get_key(ldap,current->str);
keyptr=current->next;
/* Free it as we go */
free(current);
keyptr=keyptr->next;
}
break;
case SEND:
{
char keyid[17]="????";
int ret;
while((ret=send_key(ldap,keyid))!=1)
do
{
if(ret!=0)
fprintf(output,"KEY %s FAILED\n",keyid);
ret=send_key();
if(ret==-1)
failed++;
}
while(ret!=1);
}
break;
@ -882,21 +921,19 @@ int main(int argc,char *argv[])
keyptr=keylist;
while(keyptr!=NULL)
{
struct keylist *current=keyptr;
strcat(searchkey,current->str);
strcat(searchkey,keyptr->str);
strcat(searchkey,"*");
keyptr=current->next;
/* Free it as we go */
free(current);
keyptr=keyptr->next;
}
/* Nail that last "*" */
searchkey[strlen(searchkey)-1]='\0';
if(search_key(ldap,searchkey)==-1)
fprintf(output,"SEARCH %s FAILED\n",searchkey);
if(search_key(searchkey)==-1)
{
fprintf(output,"SEARCH %s FAILED\n",searchkey);
failed++;
}
free(searchkey);
}
@ -904,10 +941,18 @@ int main(int argc,char *argv[])
break;
}
ret=KEYSERVER_OK;
if(!failed)
ret=KEYSERVER_OK;
fail:
while(keylist!=NULL)
{
struct keylist *current=keylist;
keylist=keylist->next;
free(current);
}
if(input!=stdin)
fclose(input);