mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
* keyserver-internal.h, keyserver.c (print_keyrec, parse_keyrec,
show_prompt, keyserver_search_prompt, keyserver_spawn): Go to version 1 of the keyserver protocol. This is a better design, similar to --with-colons, that allows for keys with multiple user IDs rather than using multiple keys. It also matches the machine readable pksd format. Also use a prettier --search-keys listing format that can fill different size windows (currently set at 24 lines).
This commit is contained in:
parent
a94053810c
commit
da1c9e820c
@ -1,3 +1,14 @@
|
|||||||
|
2002-10-14 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* keyserver-internal.h, keyserver.c (print_keyrec, parse_keyrec,
|
||||||
|
show_prompt, keyserver_search_prompt, keyserver_spawn): Go to
|
||||||
|
version 1 of the keyserver protocol. This is a better design,
|
||||||
|
similar to --with-colons, that allows for keys with multiple user
|
||||||
|
IDs rather than using multiple keys. It also matches the machine
|
||||||
|
readable pksd format. Also use a prettier --search-keys listing
|
||||||
|
format that can fill different size windows (currently set at 24
|
||||||
|
lines).
|
||||||
|
|
||||||
2002-10-12 Werner Koch <wk@gnupg.org>
|
2002-10-12 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* keygen.c (print_status_key_created): New.
|
* keygen.c (print_status_key_created): New.
|
||||||
|
@ -17,6 +17,5 @@ int keyserver_import_fprint(const byte *fprint,size_t fprint_len);
|
|||||||
int keyserver_import_keyid(u32 *keyid);
|
int keyserver_import_keyid(u32 *keyid);
|
||||||
int keyserver_refresh(STRLIST users);
|
int keyserver_refresh(STRLIST users);
|
||||||
int keyserver_search(STRLIST tokens);
|
int keyserver_search(STRLIST tokens);
|
||||||
void keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr);
|
|
||||||
|
|
||||||
#endif /* !_KEYSERVER_INTERNAL_H_ */
|
#endif /* !_KEYSERVER_INTERNAL_H_ */
|
||||||
|
630
g10/keyserver.c
630
g10/keyserver.c
@ -32,17 +32,26 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "iobuf.h"
|
#include "iobuf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "ttyio.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "keyserver-internal.h"
|
#include "keyserver-internal.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define KEYSERVER_PROTO_VERSION 0
|
|
||||||
|
|
||||||
#define GET 0
|
#define GET 0
|
||||||
#define SEND 1
|
#define SEND 1
|
||||||
#define SEARCH 2
|
#define SEARCH 2
|
||||||
|
|
||||||
|
struct keyrec
|
||||||
|
{
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
time_t createtime,expiretime;
|
||||||
|
int size,flags;
|
||||||
|
byte type;
|
||||||
|
IOBUF uidbuf;
|
||||||
|
int lines;
|
||||||
|
};
|
||||||
|
|
||||||
struct kopts
|
struct kopts
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
@ -61,6 +70,9 @@ struct kopts
|
|||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int keyserver_work(int action,STRLIST list,
|
||||||
|
KEYDB_SEARCH_DESC *desc,int count);
|
||||||
|
|
||||||
void
|
void
|
||||||
parse_keyserver_options(char *options)
|
parse_keyserver_options(char *options)
|
||||||
{
|
{
|
||||||
@ -218,119 +230,412 @@ parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unquote only the delimiter character and backslashes (\x5C) */
|
static void
|
||||||
static void
|
print_keyrec(int number,struct keyrec *keyrec)
|
||||||
printunquoted(char *string,char delim)
|
|
||||||
{
|
{
|
||||||
char *ch=string;
|
int i;
|
||||||
|
|
||||||
while(*ch)
|
iobuf_writebyte(keyrec->uidbuf,0);
|
||||||
|
iobuf_flush_temp(keyrec->uidbuf);
|
||||||
|
printf("(%d)\t%s ",number,iobuf_get_temp_buffer(keyrec->uidbuf));
|
||||||
|
|
||||||
|
if(keyrec->size>0)
|
||||||
|
printf("%d bit ",keyrec->size);
|
||||||
|
|
||||||
|
if(keyrec->type)
|
||||||
{
|
{
|
||||||
if(*ch=='\\')
|
const char *str=pubkey_algo_to_string(keyrec->type);
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
sscanf(ch,"\\x%02x",&c);
|
if(str)
|
||||||
if(c==delim)
|
printf("%s ",str);
|
||||||
{
|
|
||||||
printf("%c",c);
|
|
||||||
ch+=3;
|
|
||||||
}
|
|
||||||
else if(c=='\\')
|
|
||||||
{
|
|
||||||
fputc('\\',stdout);
|
|
||||||
ch+=3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fputc(*ch,stdout);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
fputc(*ch,stdout);
|
printf("unknown ");
|
||||||
|
|
||||||
ch++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
switch(keyrec->desc.mode)
|
||||||
print_keyinfo(int count,char *keystring,KEYDB_SEARCH_DESC *desc)
|
{
|
||||||
{
|
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||||
char *certid,*userid,*keytype,*tok;
|
printf("key %08lX",(ulong)keyrec->desc.u.kid[1]);
|
||||||
int flags,keysize=0;
|
break;
|
||||||
time_t createtime=0,expiretime=0,modifytime=0;
|
|
||||||
|
|
||||||
if((certid=strsep(&keystring,":"))==NULL)
|
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||||
return -1;
|
printf("key %08lX%08lX",(ulong)keyrec->desc.u.kid[0],
|
||||||
|
(ulong)keyrec->desc.u.kid[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
classify_user_id (certid, desc);
|
case KEYDB_SEARCH_MODE_FPR16:
|
||||||
if(desc->mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
|
printf("key ");
|
||||||
desc->mode!=KEYDB_SEARCH_MODE_LONG_KID &&
|
for(i=0;i<16;i++)
|
||||||
desc->mode!=KEYDB_SEARCH_MODE_FPR16 &&
|
printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]);
|
||||||
desc->mode!=KEYDB_SEARCH_MODE_FPR20)
|
break;
|
||||||
return -1;
|
|
||||||
|
|
||||||
if((tok=strsep(&keystring,":"))==NULL)
|
case KEYDB_SEARCH_MODE_FPR20:
|
||||||
return -1;
|
printf("key ");
|
||||||
|
for(i=0;i<20;i++)
|
||||||
|
printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
userid=utf8_to_native(tok,strlen(tok),0);
|
default:
|
||||||
|
BUG();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if((tok=strsep(&keystring,":"))==NULL)
|
if(keyrec->createtime>0)
|
||||||
goto fail;
|
printf(", created %s",strtimestamp(keyrec->createtime));
|
||||||
|
|
||||||
flags=atoi(tok);
|
if(keyrec->expiretime>0)
|
||||||
|
printf(", expires %s",strtimestamp(keyrec->expiretime));
|
||||||
|
|
||||||
if((tok=strsep(&keystring,":"))==NULL)
|
if(keyrec->flags&1)
|
||||||
goto fail;
|
printf(" (%s)",("revoked"));
|
||||||
|
if(keyrec->flags&2)
|
||||||
createtime=atoi(tok);
|
printf(" (%s)",("disabled"));
|
||||||
|
if(keyrec->flags&4)
|
||||||
if((tok=strsep(&keystring,":"))==NULL)
|
printf(" (%s)",("expired"));
|
||||||
goto fail;
|
|
||||||
|
|
||||||
expiretime=atoi(tok);
|
|
||||||
|
|
||||||
if((tok=strsep(&keystring,":"))==NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
modifytime=atoi(tok);
|
|
||||||
|
|
||||||
if((keytype=strsep(&keystring,":"))==NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* The last one */
|
|
||||||
if(keystring!=NULL)
|
|
||||||
keysize=atoi(keystring);
|
|
||||||
|
|
||||||
printf("(%d)\t",count);
|
|
||||||
|
|
||||||
/* No need to check for control characters, as utf8_to_native does
|
|
||||||
this for us. */
|
|
||||||
printunquoted(userid,':');
|
|
||||||
|
|
||||||
if(flags&1)
|
|
||||||
printf(" (revoked)");
|
|
||||||
if(flags&2)
|
|
||||||
printf(" (disabled)");
|
|
||||||
|
|
||||||
printf("\n\t ");
|
|
||||||
|
|
||||||
if(keysize>0)
|
|
||||||
printf("%d bit ",keysize);
|
|
||||||
|
|
||||||
if(keytype[0])
|
|
||||||
printf("%s ",keytype);
|
|
||||||
|
|
||||||
printf("key %s, created %s",certid,strtimestamp(createtime));
|
|
||||||
|
|
||||||
if(expiretime>0)
|
|
||||||
printf(", expires %s",strtimestamp(expiretime));
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a keyrec (which must be freed) once a key is complete, and
|
||||||
|
NULL otherwise. Call with a NULL keystring once key parsing is
|
||||||
|
complete to return any unfinished keys. */
|
||||||
|
static struct keyrec *
|
||||||
|
parse_keyrec(char *keystring)
|
||||||
|
{
|
||||||
|
static struct keyrec *work=NULL;
|
||||||
|
struct keyrec *ret=NULL;
|
||||||
|
char *record,*tok;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(keystring==NULL)
|
||||||
|
{
|
||||||
|
if(work==NULL)
|
||||||
|
return NULL;
|
||||||
|
else if(work->desc.mode==KEYDB_SEARCH_MODE_NONE)
|
||||||
|
{
|
||||||
|
m_free(work);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret=work;
|
||||||
|
work=NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(work==NULL)
|
||||||
|
{
|
||||||
|
work=m_alloc_clear(sizeof(struct keyrec));
|
||||||
|
work->uidbuf=iobuf_temp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove trailing whitespace */
|
||||||
|
for(i=strlen(keystring);i>0;i--)
|
||||||
|
if(isspace(keystring[i-1]))
|
||||||
|
keystring[i-1]='\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if((record=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if(ascii_strcasecmp("pub",record)==0)
|
||||||
|
{
|
||||||
|
if(work->desc.mode)
|
||||||
|
{
|
||||||
|
ret=work;
|
||||||
|
work=m_alloc_clear(sizeof(struct keyrec));
|
||||||
|
work->uidbuf=iobuf_temp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
classify_user_id(tok,&work->desc);
|
||||||
|
if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
|
&& work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID
|
||||||
|
&& work->desc.mode!=KEYDB_SEARCH_MODE_FPR16
|
||||||
|
&& work->desc.mode!=KEYDB_SEARCH_MODE_FPR20)
|
||||||
|
{
|
||||||
|
work->desc.mode=KEYDB_SEARCH_MODE_NONE;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note all items after this are optional. This allows us to
|
||||||
|
have a pub line as simple as pub:keyid and nothing else. */
|
||||||
|
|
||||||
|
work->lines++;
|
||||||
|
|
||||||
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
work->type=atoi(tok);
|
||||||
|
|
||||||
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
work->size=atoi(tok);
|
||||||
|
|
||||||
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
work->createtime=atoi(tok);
|
||||||
|
|
||||||
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
work->expiretime=atoi(tok);
|
||||||
|
|
||||||
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
while(*tok)
|
||||||
|
switch(*tok++)
|
||||||
|
{
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
work->flags|=1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
work->flags|=2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
work->flags|=4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(work->expiretime && work->expiretime<=make_timestamp())
|
||||||
|
work->flags|=4;
|
||||||
|
}
|
||||||
|
else if(ascii_strcasecmp("uid",record)==0 && work->desc.mode)
|
||||||
|
{
|
||||||
|
char *userid,*tok,*decoded;
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
if((tok=strsep(&keystring,":"))==NULL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if(strlen(tok)==0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
userid=tok;
|
||||||
|
|
||||||
|
/* By definition, de-%-encoding is always smaller than the
|
||||||
|
original string so we can decode in place. */
|
||||||
|
|
||||||
|
while(*tok)
|
||||||
|
if(tok[0]=='%' && tok[1] && tok[2])
|
||||||
|
{
|
||||||
|
if((userid[i]=hextobyte(&tok[1]))==-1)
|
||||||
|
userid[i]='?';
|
||||||
|
|
||||||
|
i++;
|
||||||
|
tok+=3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
userid[i++]=*tok++;
|
||||||
|
|
||||||
|
/* We don't care about the other info provided in the uid: line
|
||||||
|
since no keyserver supports marking userids with timestamps
|
||||||
|
or revoked/expired/disabled yet. */
|
||||||
|
|
||||||
|
/* No need to check for control characters, as utf8_to_native
|
||||||
|
does this for us. */
|
||||||
|
|
||||||
|
decoded=utf8_to_native(userid,i,0);
|
||||||
|
iobuf_writestr(work->uidbuf,decoded);
|
||||||
|
m_free(decoded);
|
||||||
|
iobuf_writestr(work->uidbuf,"\n\t");
|
||||||
|
work->lines++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore any records other than "pri" and "uid" for easy future
|
||||||
|
growth. */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: do this as a list sent to keyserver_work rather than calling
|
||||||
|
it once for each key to get the correct counts after the import
|
||||||
|
(cosmetics, really) and to better take advantage of the keyservers
|
||||||
|
that can do multiple fetches in one go (LDAP). */
|
||||||
|
static int
|
||||||
|
show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
|
||||||
|
{
|
||||||
|
char *answer;
|
||||||
|
|
||||||
|
if(count)
|
||||||
|
{
|
||||||
|
static int from=1;
|
||||||
|
tty_printf("Keys %d-%d of %d for \"%s\". ",from,numdesc,count,search);
|
||||||
|
from=numdesc+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
answer=cpr_get_no_help("keysearch.prompt",
|
||||||
|
_("Enter number(s), N)ext, or Q)uit > "));
|
||||||
|
/* control-d */
|
||||||
|
if(answer[0]=='\x04')
|
||||||
|
{
|
||||||
|
printf("Q\n");
|
||||||
|
answer[0]='q';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(answer[0]=='q' || answer[0]=='Q')
|
||||||
|
{
|
||||||
|
m_free(answer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if(atoi(answer)>=1 && atoi(answer)<=numdesc)
|
||||||
|
{
|
||||||
|
char *split=answer,*num;
|
||||||
|
|
||||||
|
while((num=strsep(&split," ,"))!=NULL)
|
||||||
|
if(atoi(num)>=1 && atoi(num)<=numdesc)
|
||||||
|
keyserver_work(GET,NULL,&desc[atoi(num)-1],1);
|
||||||
|
|
||||||
|
m_free(answer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fail:
|
/* Count and searchstr are just for cosmetics. If the count is too
|
||||||
m_free (userid);
|
small, it will grow safely. If negative it disables the "Key x-y
|
||||||
return -1;
|
of z" messages. */
|
||||||
|
static void
|
||||||
|
keyserver_search_prompt(IOBUF buffer,const char *searchstr)
|
||||||
|
{
|
||||||
|
int i=0,validcount=0,started=0,count=1;
|
||||||
|
unsigned int maxlen,buflen;
|
||||||
|
KEYDB_SEARCH_DESC *desc;
|
||||||
|
byte *line=NULL;
|
||||||
|
/* TODO: Something other than 23? That's 24-1 (the prompt). */
|
||||||
|
int maxlines=23,numlines=0;
|
||||||
|
|
||||||
|
desc=m_alloc(count*sizeof(KEYDB_SEARCH_DESC));
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
struct keyrec *keyrec;
|
||||||
|
int rl;
|
||||||
|
|
||||||
|
maxlen=1024;
|
||||||
|
rl=iobuf_read_line(buffer,&line,&buflen,&maxlen);
|
||||||
|
|
||||||
|
/* Look for an info: line. The only current info: values
|
||||||
|
defined are the version and key count. */
|
||||||
|
if(!started && rl>0 && ascii_strncasecmp("info:",line,5)==0)
|
||||||
|
{
|
||||||
|
char *tok,*str=&line[5];
|
||||||
|
|
||||||
|
if((tok=strsep(&str,":"))!=NULL)
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
|
||||||
|
if(sscanf(tok,"%d",&version)!=1)
|
||||||
|
version=1;
|
||||||
|
|
||||||
|
if(version!=1)
|
||||||
|
{
|
||||||
|
log_error(_("invalid keyserver protocol "
|
||||||
|
"(us %d!=handler %d)\n"),1,version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((tok=strsep(&str,":"))!=NULL && sscanf(tok,"%d",&count)==1)
|
||||||
|
{
|
||||||
|
if(count==0)
|
||||||
|
goto notfound;
|
||||||
|
else if(count<0)
|
||||||
|
count=10;
|
||||||
|
else
|
||||||
|
validcount=1;
|
||||||
|
|
||||||
|
desc=m_realloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
|
||||||
|
}
|
||||||
|
|
||||||
|
started=1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rl==0)
|
||||||
|
{
|
||||||
|
keyrec=parse_keyrec(NULL);
|
||||||
|
|
||||||
|
if(keyrec==NULL)
|
||||||
|
{
|
||||||
|
if(i==0)
|
||||||
|
{
|
||||||
|
count=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i!=count)
|
||||||
|
validcount=0;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(show_prompt(desc,i,validcount?count:0,searchstr))
|
||||||
|
break;
|
||||||
|
validcount=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
keyrec=parse_keyrec(line);
|
||||||
|
|
||||||
|
if(i==count)
|
||||||
|
{
|
||||||
|
/* keyserver helper sent more keys than they claimed in the
|
||||||
|
info: line. */
|
||||||
|
count+=10;
|
||||||
|
desc=m_realloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
|
||||||
|
validcount=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keyrec)
|
||||||
|
{
|
||||||
|
desc[i]=keyrec->desc;
|
||||||
|
|
||||||
|
if(numlines+keyrec->lines>maxlines)
|
||||||
|
{
|
||||||
|
if(show_prompt(desc,i,validcount?count:0,searchstr))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
numlines=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_keyrec(i+1,keyrec);
|
||||||
|
numlines+=keyrec->lines;
|
||||||
|
iobuf_close(keyrec->uidbuf);
|
||||||
|
m_free(keyrec);
|
||||||
|
|
||||||
|
started=1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_free(desc);
|
||||||
|
m_free(line);
|
||||||
|
|
||||||
|
notfound:
|
||||||
|
if(count==0)
|
||||||
|
{
|
||||||
|
if(searchstr)
|
||||||
|
log_info(_("key \"%s\" not found on keyserver\n"),searchstr);
|
||||||
|
else
|
||||||
|
log_info(_("key not found on keyserver\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
|
#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
|
||||||
@ -549,8 +854,8 @@ keyserver_spawn(int action,STRLIST list,
|
|||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
char *ptr;
|
|
||||||
int plen;
|
int plen;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
maxlen=1024;
|
maxlen=1024;
|
||||||
if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0)
|
if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0)
|
||||||
@ -628,19 +933,7 @@ keyserver_spawn(int action,STRLIST list,
|
|||||||
|
|
||||||
case SEARCH:
|
case SEARCH:
|
||||||
{
|
{
|
||||||
/* Look for the COUNT line */
|
keyserver_search_prompt(spawn->fromchild,searchstr);
|
||||||
do
|
|
||||||
{
|
|
||||||
maxlen=1024;
|
|
||||||
if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0)
|
|
||||||
{
|
|
||||||
ret=G10ERR_READ_FILE;
|
|
||||||
goto fail; /* i.e. EOF */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(sscanf(line,"COUNT %d\n",&i)!=1);
|
|
||||||
|
|
||||||
keyserver_search_prompt(spawn->fromchild,i,searchstr);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -693,6 +986,12 @@ keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc,int count)
|
|||||||
action==GET?"get":action==SEND?"send":
|
action==GET?"get":action==SEND?"send":
|
||||||
action==SEARCH?"search":"unknown",
|
action==SEARCH?"search":"unknown",
|
||||||
opt.keyserver_scheme);
|
opt.keyserver_scheme);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEYSERVER_VERSION_ERROR:
|
||||||
|
log_error(_("gpgkeys_%s does not support handler version %d\n"),
|
||||||
|
opt.keyserver_scheme,KEYSERVER_PROTO_VERSION);
|
||||||
|
break;
|
||||||
|
|
||||||
case KEYSERVER_INTERNAL_ERROR:
|
case KEYSERVER_INTERNAL_ERROR:
|
||||||
default:
|
default:
|
||||||
@ -963,114 +1262,3 @@ keyserver_search(STRLIST tokens)
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count and searchstr are just for cosmetics. If the count is too
|
|
||||||
small, it will grow safely. If negative it disables the "Key x-y
|
|
||||||
of z" messages. */
|
|
||||||
|
|
||||||
/* TODO: do this as a list sent to keyserver_work rather than calling
|
|
||||||
it once for each key to get the correct counts after the import
|
|
||||||
(cosmetics, really) and to better take advantage of the keyservers
|
|
||||||
that can do multiple fetches in one go (LDAP). */
|
|
||||||
void
|
|
||||||
keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
|
|
||||||
{
|
|
||||||
int i=0,validcount=1;
|
|
||||||
unsigned int maxlen,buflen;
|
|
||||||
KEYDB_SEARCH_DESC *desc;
|
|
||||||
byte *line=NULL;
|
|
||||||
char *answer;
|
|
||||||
|
|
||||||
if(count==0)
|
|
||||||
goto notfound;
|
|
||||||
|
|
||||||
if(count<0)
|
|
||||||
{
|
|
||||||
validcount=0;
|
|
||||||
count=10;
|
|
||||||
}
|
|
||||||
|
|
||||||
desc=m_alloc(count*sizeof(KEYDB_SEARCH_DESC));
|
|
||||||
|
|
||||||
/* Read each line and show it to the user */
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
int rl;
|
|
||||||
|
|
||||||
if(validcount && i%10==0)
|
|
||||||
{
|
|
||||||
printf("Keys %d-%d of %d",i+1,(i+10<count)?i+10:count,count);
|
|
||||||
if(searchstr)
|
|
||||||
printf(" for \"%s\"",searchstr);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
maxlen=1024;
|
|
||||||
rl=iobuf_read_line(buffer,&line,&buflen,&maxlen);
|
|
||||||
if(rl>0)
|
|
||||||
{
|
|
||||||
if(print_keyinfo(i+1,line,&desc[i])==0)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if(i==count)
|
|
||||||
{
|
|
||||||
count+=10;
|
|
||||||
desc=m_realloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
|
|
||||||
validcount=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rl==0 && i==0)
|
|
||||||
{
|
|
||||||
count=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i%10==0 || rl==0)
|
|
||||||
{
|
|
||||||
answer=cpr_get_no_help("keysearch.prompt",
|
|
||||||
_("Enter number(s), N)ext, or Q)uit > "));
|
|
||||||
/* control-d */
|
|
||||||
if(answer[0]=='\x04')
|
|
||||||
{
|
|
||||||
printf("Q\n");
|
|
||||||
answer[0]='q';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(answer[0]=='q' || answer[0]=='Q')
|
|
||||||
{
|
|
||||||
m_free(answer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(atoi(answer)>=1 && atoi(answer)<=i)
|
|
||||||
{
|
|
||||||
char *split=answer,*num;
|
|
||||||
|
|
||||||
while((num=strsep(&split," ,"))!=NULL)
|
|
||||||
if(atoi(num)>=1 && atoi(num)<=i)
|
|
||||||
keyserver_work(GET,NULL,&desc[atoi(num)-1],1);
|
|
||||||
|
|
||||||
m_free(answer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_free(desc);
|
|
||||||
m_free(line);
|
|
||||||
|
|
||||||
notfound:
|
|
||||||
if(count==0)
|
|
||||||
{
|
|
||||||
if(searchstr)
|
|
||||||
log_info(_("key \"%s\" not found on keyserver\n"),searchstr);
|
|
||||||
else
|
|
||||||
log_info(_("key not found on keyserver\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user