mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
* 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.
This commit is contained in:
parent
7f13d486b0
commit
da9a10d2b0
@ -1,3 +1,11 @@
|
|||||||
|
2005-12-23 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* 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 <dshaw@jabberwocky.com>
|
2005-12-19 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* ksutil.h, ksutil.c (curl_armor_writer, curl_writer,
|
* ksutil.h, ksutil.c (curl_armor_writer, curl_writer,
|
||||||
|
@ -284,12 +284,91 @@ get_key(char *getkey)
|
|||||||
return KEYSERVER_OK;
|
return KEYSERVER_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
search_key(const char *searchkey)
|
search_key(const char *searchkey)
|
||||||
{
|
{
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
char *request=NULL;
|
char *request=NULL;
|
||||||
char *searchkey_encoded=NULL;
|
char *searchkey_encoded;
|
||||||
int ret=KEYSERVER_INTERNAL_ERROR;
|
int ret=KEYSERVER_INTERNAL_ERROR;
|
||||||
enum ks_search_type search_type;
|
enum ks_search_type search_type;
|
||||||
|
|
||||||
@ -570,7 +649,8 @@ main(int argc,char *argv[])
|
|||||||
|
|
||||||
if(opt->action==KS_SEND)
|
if(opt->action==KS_SEND)
|
||||||
while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
|
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(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
@ -642,6 +722,20 @@ main(int argc,char *argv[])
|
|||||||
if(get_key(keyptr->str)!=KEYSERVER_OK)
|
if(get_key(keyptr->str)!=KEYSERVER_OK)
|
||||||
failed++;
|
failed++;
|
||||||
|
|
||||||
|
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;
|
keyptr=keyptr->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1116,20 +1116,6 @@ get_key(char *getkey)
|
|||||||
return ret;
|
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 "*()\\"
|
#define LDAP_ESCAPE_CHARS "*()\\"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1164,6 +1150,132 @@ ldap_quote(char *buffer,const char *string)
|
|||||||
return count;
|
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
|
/* Returns 0 on success and -1 on error. Note that key-not-found is
|
||||||
not an error! */
|
not an error! */
|
||||||
static int
|
static int
|
||||||
@ -1173,9 +1285,9 @@ search_key(const char *searchkey)
|
|||||||
LDAPMessage *res,*each;
|
LDAPMessage *res,*each;
|
||||||
int err,count=0;
|
int err,count=0;
|
||||||
struct keylist *dupelist=NULL;
|
struct keylist *dupelist=NULL;
|
||||||
|
char *expanded_search;
|
||||||
/* The maximum size of the search, including the optional stuff and
|
/* The maximum size of the search, including the optional stuff and
|
||||||
the trailing \0 */
|
the trailing \0 */
|
||||||
char *expanded_search;
|
|
||||||
char search[2+11+3+MAX_LINE+2+15+14+1+1+20];
|
char search[2+11+3+MAX_LINE+2+15+14+1+1+20];
|
||||||
char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
|
char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
|
||||||
"pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
|
"pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
|
||||||
@ -1794,7 +1906,8 @@ main(int argc,char *argv[])
|
|||||||
|
|
||||||
if(opt->action==KS_SEND)
|
if(opt->action==KS_SEND)
|
||||||
while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
|
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(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
@ -2015,6 +2128,20 @@ main(int argc,char *argv[])
|
|||||||
if(get_key(keyptr->str)!=KEYSERVER_OK)
|
if(get_key(keyptr->str)!=KEYSERVER_OK)
|
||||||
failed++;
|
failed++;
|
||||||
|
|
||||||
|
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;
|
keyptr=keyptr->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,6 +140,8 @@ parse_ks_options(char *line,struct ks_options *opt)
|
|||||||
|
|
||||||
if(strcasecmp(command,"get")==0)
|
if(strcasecmp(command,"get")==0)
|
||||||
opt->action=KS_GET;
|
opt->action=KS_GET;
|
||||||
|
else if(strcasecmp(command,"getname")==0)
|
||||||
|
opt->action=KS_GETNAME;
|
||||||
else if(strcasecmp(command,"send")==0)
|
else if(strcasecmp(command,"send")==0)
|
||||||
opt->action=KS_SEND;
|
opt->action=KS_SEND;
|
||||||
else if(strcasecmp(command,"search")==0)
|
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_UNKNOWN: return "UNKNOWN";
|
||||||
case KS_GET: return "GET";
|
case KS_GET: return "GET";
|
||||||
|
case KS_GETNAME: return "GETNAME";
|
||||||
case KS_SEND: return "SEND";
|
case KS_SEND: return "SEND";
|
||||||
case KS_SEARCH: return "SEARCH";
|
case KS_SEARCH: return "SEARCH";
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
strlen("OPAQUE")+1+sizeof_opaque+1 */
|
strlen("OPAQUE")+1+sizeof_opaque+1 */
|
||||||
#define MAX_LINE (6+1+1024+1)
|
#define MAX_LINE (6+1+1024+1)
|
||||||
|
|
||||||
#define MAX_COMMAND 6
|
#define MAX_COMMAND 7
|
||||||
#define MAX_OPTION 256
|
#define MAX_OPTION 256
|
||||||
#define MAX_SCHEME 20
|
#define MAX_SCHEME 20
|
||||||
#define MAX_OPAQUE 1024
|
#define MAX_OPAQUE 1024
|
||||||
@ -72,7 +72,7 @@ struct keylist
|
|||||||
unsigned int set_timeout(unsigned int seconds);
|
unsigned int set_timeout(unsigned int seconds);
|
||||||
int register_timeout(void);
|
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,
|
enum ks_search_type {KS_SEARCH_SUBSTR,KS_SEARCH_EXACT,
|
||||||
KS_SEARCH_MAIL,KS_SEARCH_MAILSUB};
|
KS_SEARCH_MAIL,KS_SEARCH_MAILSUB};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user