* options.h, g10.c (main), keyserver.c (keyserver_refresh): Maintain and
[gnupg.git] / g10 / keyserver.c
1 /* keyserver.c - generic keyserver code
2  * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26
27 #include "filter.h"
28 #include "keydb.h"
29 #include "status.h"
30 #include "exec.h"
31 #include "main.h"
32 #include "i18n.h"
33 #include "hkp.h"
34 #include "iobuf.h"
35 #include "memory.h"
36 #include "options.h"
37 #include "packet.h"
38 #include "keyserver-internal.h"
39 #include "util.h"
40
41 #define KEYSERVER_PROTO_VERSION 0
42
43 #define GET    0
44 #define SEND   1
45 #define SEARCH 2
46
47 struct kopts
48 {
49   char *name;
50   int tell; /* tell remote process about this one */
51   int *flag;
52 } keyserver_opts[]=
53 {
54   {"include-revoked",1,&opt.keyserver_options.include_revoked},
55   {"include-disabled",1,&opt.keyserver_options.include_disabled},
56   {"include-subkeys",1,&opt.keyserver_options.include_subkeys},
57   {"keep-temp-files",0,&opt.keyserver_options.keep_temp_files},
58   {"honor-http-proxy",1,&opt.keyserver_options.honor_http_proxy},
59   {"broken-http-proxy",1,&opt.keyserver_options.broken_http_proxy},
60   {"refresh-add-fake-v3-keyids",0,&opt.keyserver_options.fake_v3_keyids},
61   {"auto-key-retrieve",0,&opt.keyserver_options.auto_key_retrieve},
62   {NULL}
63 };
64
65 void 
66 parse_keyserver_options(char *options)
67 {
68   char *tok="";
69
70   do
71     {
72       struct kopts *kopts=keyserver_opts;
73       int i,hit=0;
74
75       for(i=0,kopts=keyserver_opts;kopts[i].name;i++)
76         {
77           if(ascii_strcasecmp(tok,kopts[i].name)==0)
78             {
79               *(kopts[i].flag)=1;
80               hit=1;
81               break;
82             }
83           else if(ascii_memcasecmp("no-",tok,3)==0 && strlen(tok)>3 &&
84                   ascii_strcasecmp(&tok[3],kopts[i].name)==0)
85             {
86               *(kopts[i].flag)=0;
87               hit=1;
88               break;
89             }
90         }
91
92       /* These options need more than just a flag */
93       if(!hit)
94         {
95           if(ascii_strcasecmp(tok,"verbose")==0)
96             opt.keyserver_options.verbose++;
97           else if(ascii_strcasecmp(tok,"no-verbose")==0)
98             opt.keyserver_options.verbose--;
99 #ifdef EXEC_TEMPFILE_ONLY
100           else if(ascii_strcasecmp(tok,"use-temp-files")==0 ||
101                   ascii_strcasecmp(tok,"no-use-temp-files")==0)
102             log_info(_("Warning: keyserver option \"%s\" is not used "
103                        "on this platform\n"),tok);
104 #else
105           else if(ascii_strcasecmp(tok,"use-temp-files")==0)
106             opt.keyserver_options.use_temp_files=1;
107           else if(ascii_strcasecmp(tok,"no-use-temp-files")==0)
108             opt.keyserver_options.use_temp_files=0;
109 #endif
110           else if(strlen(tok)>0)
111             add_to_strlist(&opt.keyserver_options.other,tok);
112         }
113
114       tok=strsep(&options," ,");
115     }
116     while(tok!=NULL);
117 }
118
119 int 
120 parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
121 {
122   /* Get the scheme */
123
124   opt.keyserver_scheme=strsep(&uri,":");
125   if(uri==NULL)
126     {
127       uri=opt.keyserver_scheme;
128       opt.keyserver_scheme="hkp";
129     }
130
131   if(ascii_strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0)
132     {
133       deprecated_warning(configname,configlineno,"x-broken-hkp",
134                          "--keyserver-options ","broken-http-proxy");
135       opt.keyserver_scheme="hkp";
136       opt.keyserver_options.broken_http_proxy=1;
137     }
138   else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0)
139     {
140       /* Canonicalize this to "hkp" so it works with both the internal
141          and external keyserver interface. */
142       opt.keyserver_scheme="hkp";
143     }
144
145   /* Skip the "//", if any */
146   if(strlen(uri)>2 && uri[0]=='/' && uri[1]=='/')
147     uri+=2;
148
149   /* Get the host */
150   opt.keyserver_host=strsep(&uri,":/");
151   if(uri==NULL)
152     opt.keyserver_port="0";
153   else
154     {
155       char *ch;
156
157       /* Get the port */
158       opt.keyserver_port=strsep(&uri,"/");
159
160       /* Ports are digits only */
161       ch=opt.keyserver_port;
162       while(*ch!='\0')
163         {
164           if(!isdigit(*ch))
165             return G10ERR_BAD_URI;
166
167           ch++;
168         }
169
170       if(strlen(opt.keyserver_port)==0 ||
171          atoi(opt.keyserver_port)<1 || atoi(opt.keyserver_port)>65535)
172         return G10ERR_BAD_URI;
173     }
174
175   /* (any path part of the URI is discarded for now as no keyserver
176      uses it) */
177
178   if(opt.keyserver_scheme[0]=='\0' || opt.keyserver_host[0]=='\0')
179     return G10ERR_BAD_URI;
180
181   return 0;
182 }
183
184 /* Unquote only the delimiter character and backslashes (\x5C) */
185 static void 
186 printunquoted(char *string,char delim)
187 {
188   char *ch=string;
189
190   while(*ch)
191     {
192       if(*ch=='\\')
193         {
194           int c;
195
196           sscanf(ch,"\\x%02x",&c);
197           if(c==delim)
198             {
199               printf("%c",c);
200               ch+=3;
201             }
202           else if(c=='\\')
203             {
204               fputc('\\',stdout);
205               ch+=3;
206             }
207           else
208             fputc(*ch,stdout);
209         }
210       else
211         fputc(*ch,stdout);
212
213       ch++;
214     }
215 }
216
217 static int 
218 print_keyinfo(int count,char *keystring,KEYDB_SEARCH_DESC *desc)
219 {
220   char *certid,*userid,*keytype,*tok;
221   int flags,keysize=0;
222   time_t createtime=0,expiretime=0,modifytime=0;
223
224   if((certid=strsep(&keystring,":"))==NULL)
225     return -1;
226
227   classify_user_id (certid, desc);
228   if(desc->mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
229      desc->mode!=KEYDB_SEARCH_MODE_LONG_KID &&
230      desc->mode!=KEYDB_SEARCH_MODE_FPR16 &&
231      desc->mode!=KEYDB_SEARCH_MODE_FPR20)
232     return -1;
233
234   if((tok=strsep(&keystring,":"))==NULL)
235     return -1;
236
237   userid=utf8_to_native(tok,strlen(tok),0);
238
239   if((tok=strsep(&keystring,":"))==NULL)
240     return -1;
241
242   flags=atoi(tok);
243
244   if((tok=strsep(&keystring,":"))==NULL)
245     return -1;
246
247   createtime=atoi(tok);
248
249   if((tok=strsep(&keystring,":"))==NULL)
250     return -1;
251
252   expiretime=atoi(tok);
253
254   if((tok=strsep(&keystring,":"))==NULL)
255     return -1;
256
257   modifytime=atoi(tok);
258
259   if((keytype=strsep(&keystring,":"))==NULL)
260     return -1;
261
262   /* The last one */
263   if(keystring!=NULL)
264     keysize=atoi(keystring);
265
266   printf("(%d)\t",count);
267
268   /* No need to check for control characters, as utf8_to_native does
269      this for us. */
270   printunquoted(userid,':');
271
272   if(flags&1)
273     printf(" (revoked)");
274   if(flags&2)
275     printf(" (disabled)");
276
277   if(keytype[0])
278     printf(" %s",keytype);
279
280   if(keysize>0)
281     printf(" %d",keysize);
282
283   printf("\n\t  created %s,",strtimestamp(createtime));
284
285   if(expiretime>0)
286     printf(" expires %s,",strtimestamp(expiretime));
287
288   printf(" key %s\n",certid);
289
290   return 0;
291 }
292
293 #define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
294 #define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
295
296 static int 
297 keyserver_spawn(int action,STRLIST list,
298                 KEYDB_SEARCH_DESC *desc,int count,int *prog)
299 {
300   int ret=0,i,gotversion=0,outofband=0;
301   STRLIST temp;
302   unsigned int maxlen=256,buflen;
303   char *command=NULL,*searchstr=NULL;
304   byte *line=NULL;
305   struct kopts *kopts;
306   struct exec_info *spawn;
307
308 #ifdef EXEC_TEMPFILE_ONLY
309   opt.keyserver_options.use_temp_files=1;
310 #endif
311
312   /* Build the filename for the helper to execute */
313
314   command=m_alloc(strlen("gpgkeys_")+strlen(opt.keyserver_scheme)+1);
315   strcpy(command,"gpgkeys_");
316   strcat(command,opt.keyserver_scheme);
317
318   if(opt.keyserver_options.use_temp_files)
319     {
320       if(opt.keyserver_options.keep_temp_files)
321         {
322           command=m_realloc(command,strlen(command)+
323                             strlen(KEYSERVER_ARGS_KEEP)+1);
324           strcat(command,KEYSERVER_ARGS_KEEP);
325         }
326       else
327         {
328           command=m_realloc(command,strlen(command)+
329                             strlen(KEYSERVER_ARGS_NOKEEP)+1);
330           strcat(command,KEYSERVER_ARGS_NOKEEP);  
331         }
332
333       ret=exec_write(&spawn,NULL,command,NULL,0,0);
334     }
335   else
336     ret=exec_write(&spawn,command,NULL,NULL,0,0);
337
338   if(ret)
339     return ret;
340
341   fprintf(spawn->tochild,"# This is a gpg keyserver communications file\n");
342   fprintf(spawn->tochild,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
343   fprintf(spawn->tochild,"PROGRAM %s\n",VERSION);
344   fprintf(spawn->tochild,"HOST %s\n",opt.keyserver_host);
345
346   if(atoi(opt.keyserver_port)>0)
347     fprintf(spawn->tochild,"PORT %s\n",opt.keyserver_port);
348
349   /* Write options */
350
351   for(i=0,kopts=keyserver_opts;kopts[i].name;i++)
352     if(*(kopts[i].flag) && kopts[i].tell)
353       fprintf(spawn->tochild,"OPTION %s\n",kopts[i].name);
354
355   for(i=0;i<opt.keyserver_options.verbose;i++)
356     fprintf(spawn->tochild,"OPTION verbose\n");
357
358   temp=opt.keyserver_options.other;
359
360   for(;temp;temp=temp->next)
361     fprintf(spawn->tochild,"OPTION %s\n",temp->d);
362
363   switch(action)
364     {
365     case GET:
366       {
367         fprintf(spawn->tochild,"COMMAND GET\n\n");
368
369         /* Which keys do we want? */
370
371         for(i=0;i<count;i++)
372           {
373             if(desc[i].mode==KEYDB_SEARCH_MODE_FPR20)
374               {
375                 int f;
376
377                 fprintf(spawn->tochild,"0x");
378
379                 for(f=0;f<MAX_FINGERPRINT_LEN;f++)
380                   fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]);
381
382                 fprintf(spawn->tochild,"\n");
383               }
384             else if(desc[i].mode==KEYDB_SEARCH_MODE_FPR16)
385               {
386                 int f;
387
388                 fprintf(spawn->tochild,"0x");
389
390                 for(f=0;f<16;f++)
391                   fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]);
392
393                 fprintf(spawn->tochild,"\n");
394               }
395             else if(desc[i].mode==KEYDB_SEARCH_MODE_LONG_KID)
396               fprintf(spawn->tochild,"0x%08lX%08lX\n",
397                       (ulong)desc[i].u.kid[0],
398                       (ulong)desc[i].u.kid[1]);
399             else
400               fprintf(spawn->tochild,"0x%08lX\n",
401                       (ulong)desc[i].u.kid[1]);
402           }
403
404         fprintf(spawn->tochild,"\n");
405
406         break;
407       }
408
409     case SEND:
410       {
411         STRLIST key;
412
413         /* Note the extra \n here to send an empty keylist block */
414         fprintf(spawn->tochild,"COMMAND SEND\n\n\n");
415
416         for(key=list;key!=NULL;key=key->next)
417           {
418             armor_filter_context_t afx;
419             IOBUF buffer=iobuf_temp();
420
421             temp=NULL;
422             add_to_strlist(&temp,key->d);
423
424             memset(&afx,0,sizeof(afx));
425             afx.what=1;
426             iobuf_push_filter(buffer,armor_filter,&afx);
427
428             if(export_pubkeys_stream(buffer,temp,1)==-1)
429               iobuf_close(buffer);
430             else
431               {
432                 iobuf_flush_temp(buffer);
433
434                 fprintf(spawn->tochild,"KEY %s BEGIN\n",key->d);
435                 fwrite(iobuf_get_temp_buffer(buffer),
436                        iobuf_get_temp_length(buffer),1,spawn->tochild);
437                 fprintf(spawn->tochild,"KEY %s END\n",key->d);
438
439                 iobuf_close(buffer);
440               }
441
442             free_strlist(temp);
443           }
444
445         break;
446       }
447
448     case SEARCH:
449       {
450         STRLIST key;
451
452         fprintf(spawn->tochild,"COMMAND SEARCH\n\n");
453
454         /* Which keys do we want?  Remember that the gpgkeys_ program
455            is going to lump these together into a search string. */
456
457         for(key=list;key!=NULL;key=key->next)
458           {
459             fprintf(spawn->tochild,"%s\n",key->d);
460             if(key!=list)
461               {
462                 searchstr=m_realloc(searchstr,
463                                     strlen(searchstr)+strlen(key->d)+2);
464                 strcat(searchstr," ");
465               }
466             else
467               {
468                 searchstr=m_alloc(strlen(key->d)+1);
469                 searchstr[0]='\0';
470               }
471
472             strcat(searchstr,key->d);
473           }
474
475         fprintf(spawn->tochild,"\n");
476
477         break;
478       }
479
480     default:
481       log_fatal(_("no keyserver action!\n"));
482       break;
483     }
484
485   /* Done sending, so start reading. */
486   ret=exec_read(spawn);
487   if(ret)
488     goto fail;
489
490   /* Now handle the response */
491
492   for(;;)
493     {
494       char *ptr;
495
496       if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0)
497         {
498           ret=G10ERR_READ_FILE;
499           goto fail; /* i.e. EOF */
500         }
501
502       ptr=line;
503
504       if(*ptr=='\r')
505         ptr++;
506
507       if(*ptr=='\n')
508         ptr++;
509
510       if(*ptr=='\0')
511         break;
512
513       if(ascii_memcasecmp(ptr,"VERSION ",8)==0)
514         {
515           gotversion=1;
516
517           if(atoi(&ptr[8])!=KEYSERVER_PROTO_VERSION)
518             {
519               log_error(_("invalid keyserver protocol (us %d!=handler %d)\n"),
520                         KEYSERVER_PROTO_VERSION,atoi(&ptr[8]));
521               goto fail;
522             }
523         }
524       else if(ascii_memcasecmp(ptr,"PROGRAM ",8)==0)
525         {
526           if(ascii_memcasecmp(&ptr[8],VERSION,strlen(VERSION))!=0)
527             log_info(_("Warning: keyserver handler from a different "
528                        "version of GnuPG (%s)\n"),&ptr[8]);
529         }
530       else if(ascii_memcasecmp(ptr,"OPTION OUTOFBAND",16)==0)
531         outofband=1; /* Currently the only OPTION */
532     }
533
534   m_free(line);
535
536   if(!gotversion)
537     {
538       log_error(_("keyserver did not send VERSION\n"));
539       goto fail;
540     }
541
542   if(!outofband)
543     switch(action)
544       {
545       case GET:
546         {
547           void *stats_handle;
548
549           stats_handle=import_new_stats_handle();
550
551           /* Slurp up all the key data.  In the future, it might be nice
552              to look for KEY foo OUTOFBAND and FAILED indicators.  It's
553              harmless to ignore them, but ignoring them does make gpg
554              complain about "no valid OpenPGP data found".  One way to
555              do this could be to continue parsing this line-by-line and
556              make a temp iobuf for each key. */
557
558           import_keys_stream(spawn->fromchild,0,stats_handle);
559
560           import_print_stats(stats_handle);
561           import_release_stats_handle(stats_handle);
562
563           break;
564         }
565
566         /* Nothing to do here */
567       case SEND:
568         break;
569
570       case SEARCH:
571         {
572           line=NULL;
573           buflen = 0;
574           maxlen = 80;
575           /* Look for the COUNT line */
576           do
577             {
578               if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0)
579                 {
580                   ret=G10ERR_READ_FILE;
581                   goto fail; /* i.e. EOF */
582                 }
583             }
584           while(sscanf(line,"COUNT %d\n",&i)!=1);
585
586           keyserver_search_prompt(spawn->fromchild,i,searchstr);
587
588           break;
589         }
590
591       default:
592         log_fatal(_("no keyserver action!\n"));
593         break;
594       }
595
596  fail:
597   *prog=exec_finish(spawn);
598
599   return ret;
600 }
601
602 static int 
603 keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc,int count)
604 {
605   int rc=0,ret=0;
606
607   if(opt.keyserver_scheme==NULL ||
608      opt.keyserver_host==NULL ||
609      opt.keyserver_port==NULL)
610     {
611       log_error(_("no keyserver known (use option --keyserver)\n"));
612       return G10ERR_BAD_URI;
613     }
614
615 #ifndef USE_EXTERNAL_HKP
616   /* Use the internal HKP code */
617   if(ascii_strcasecmp(opt.keyserver_scheme,"hkp")==0)
618     {
619       void *stats_handle = import_new_stats_handle ();
620
621       switch(action)
622         {
623         case GET:
624           for(count--;count>=0;count--)
625             if(hkp_ask_import(&desc[count],stats_handle))
626               log_inc_errorcount();
627           break;
628         case SEND:
629           return hkp_export(list);
630         case SEARCH:
631           return hkp_search(list);
632         }
633
634       import_print_stats (stats_handle);
635       import_release_stats_handle (stats_handle);
636
637       return 0;
638     }
639 #endif
640
641   /* It's not the internal HKP code, so try and spawn a handler for it */
642
643   rc=keyserver_spawn(action,list,desc,count,&ret);
644   if(ret)
645     {
646       switch(ret)
647         {
648         case KEYSERVER_SCHEME_NOT_FOUND:
649           log_error(_("no handler for keyserver scheme \"%s\"\n"),
650                     opt.keyserver_scheme);
651           break;
652
653         case KEYSERVER_NOT_SUPPORTED:
654           log_error(_("action \"%s\" not supported with keyserver "
655                       "scheme \"%s\"\n"),
656                     action==GET?"get":action==SEND?"send":
657                     action==SEARCH?"search":"unknown",
658                     opt.keyserver_scheme);
659
660         case KEYSERVER_INTERNAL_ERROR:
661         default:
662           log_error(_("keyserver internal error\n"));
663           break;
664         }
665
666       return G10ERR_KEYSERVER;
667     }
668
669   if(rc)
670     {
671       log_error(_("keyserver communications error: %s\n"),g10_errstr(rc));
672
673       return rc;
674     }
675
676   return 0;
677 }
678
679 int 
680 keyserver_export(STRLIST users)
681 {
682   /* We better ask for confirmation when the user entered --send-keys
683      without arguments.  Sending all keys might not be the thing he
684      intended to do */
685   if (users || opt.batch || opt.answer_yes)
686     ;
687   else if ( !cpr_get_answer_is_yes
688             ("keyserver_export.send_all",
689              _("Do you really want to send all your "
690                "public keys to the keyserver? (y/N) ")))
691     return -1;
692
693   return keyserver_work(SEND,users,NULL,0);
694 }
695
696 int 
697 keyserver_import(STRLIST users)
698 {
699   KEYDB_SEARCH_DESC *desc;
700   int num=100,count=0;
701   int rc=0;
702
703   /* Build a list of key ids */
704   desc=m_alloc(sizeof(KEYDB_SEARCH_DESC)*num);
705
706   for(;users;users=users->next)
707     {
708       classify_user_id (users->d, &desc[count]);
709       if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
710          desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID &&
711          desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 &&
712          desc[count].mode!=KEYDB_SEARCH_MODE_FPR20)
713         {
714           log_error(_("skipping invalid key ID \"%s\"\n"),users->d);
715           continue;
716         }
717
718       count++;
719       if(count==num)
720         {
721           num+=100;
722           desc=m_realloc(desc,sizeof(KEYDB_SEARCH_DESC)*num);
723         }
724     }
725
726   if(count>0)
727     rc=keyserver_work(GET,NULL,desc,count);
728
729   m_free(desc);
730
731   return rc;
732 }
733
734 int
735 keyserver_import_fprint(const byte *fprint,size_t fprint_len)
736 {
737   KEYDB_SEARCH_DESC desc;
738
739   memset(&desc,0,sizeof(desc));
740
741   if(fprint_len==16)
742     desc.mode=KEYDB_SEARCH_MODE_FPR16;
743   else if(fprint_len==20)
744     desc.mode=KEYDB_SEARCH_MODE_FPR20;
745   else
746     return -1;
747
748   memcpy(desc.u.fpr,fprint,fprint_len);
749
750   return keyserver_work(GET,NULL,&desc,1);
751 }
752
753 int 
754 keyserver_import_keyid(u32 *keyid)
755 {
756   KEYDB_SEARCH_DESC desc;
757
758   memset(&desc,0,sizeof(desc));
759
760   desc.mode=KEYDB_SEARCH_MODE_LONG_KID;
761   desc.u.kid[0]=keyid[0];
762   desc.u.kid[1]=keyid[1];
763
764   return keyserver_work(GET,NULL,&desc,1);
765 }
766
767 /* code mostly stolen from do_export_stream */
768 static int 
769 keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
770 {
771   int rc=0,ndesc,num=100;
772   KBNODE keyblock=NULL,node;
773   KEYDB_HANDLE kdbhd;
774   KEYDB_SEARCH_DESC *desc;
775   STRLIST sl;
776
777   *count=0;
778
779   *klist=m_alloc(sizeof(KEYDB_SEARCH_DESC)*num);
780
781   kdbhd=keydb_new(0);
782
783   if(!users)
784     {
785       ndesc = 1;
786       desc = m_alloc_clear ( ndesc * sizeof *desc);
787       desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
788     }
789   else
790     {
791       for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) 
792         ;
793       desc = m_alloc ( ndesc * sizeof *desc);
794         
795       for (ndesc=0, sl=users; sl; sl = sl->next)
796         {
797           if(classify_user_id (sl->d, desc+ndesc))
798             ndesc++;
799           else
800             log_error (_("key `%s' not found: %s\n"),
801                        sl->d, g10_errstr (G10ERR_INV_USER_ID));
802         }
803     }
804
805   while (!(rc = keydb_search (kdbhd, desc, ndesc)))
806     {
807       if (!users) 
808         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
809
810       /* read the keyblock */
811       rc = keydb_get_keyblock (kdbhd, &keyblock );
812       if( rc )
813         {
814           log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
815           goto leave;
816         }
817
818       if((node=find_kbnode(keyblock,PKT_PUBLIC_KEY)))
819         {
820           /* This is to work around a bug in some keyservers (pksd and
821              OKS) that calculate v4 RSA keyids as if they were v3 RSA.
822              The answer is to refresh both the correct v4 keyid
823              (e.g. 99242560) and the fake v3 keyid (e.g. 68FDDBC7).
824              This only happens for key refresh using the HKP scheme
825              and if the refresh-add-fake-v3-keyids keyserver option is
826              set. */
827           if(fakev3 && is_RSA(node->pkt->pkt.public_key->pubkey_algo) &&
828              node->pkt->pkt.public_key->version>=4)
829             {
830               (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
831               mpi_get_keyid(node->pkt->pkt.public_key->pkey[0],
832                             (*klist)[*count].u.kid);
833               (*count)++;
834
835               if(*count==num)
836                 {
837                   num+=100;
838                   *klist=m_realloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
839                 }
840             }
841
842           /* v4 keys get full fingerprints.  v3 keys get long keyids.
843              This is because it's easy to calculate any sort of key id
844              from a v4 fingerprint, but not a v3 fingerprint. */
845
846           if(node->pkt->pkt.public_key->version<4)
847             {
848               (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
849               keyid_from_pk(node->pkt->pkt.public_key,
850                             (*klist)[*count].u.kid);
851             }
852           else
853             {
854               size_t dummy;
855
856               (*klist)[*count].mode=KEYDB_SEARCH_MODE_FPR20;
857               fingerprint_from_pk(node->pkt->pkt.public_key,
858                                   (*klist)[*count].u.fpr,&dummy);
859             }
860
861           (*count)++;
862
863           if(*count==num)
864             {
865               num+=100;
866               *klist=m_realloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
867             }
868         }
869     }
870
871   if(rc==-1)
872     rc=0;
873   
874  leave:
875   m_free(desc);
876   keydb_release(kdbhd);
877   release_kbnode(keyblock);
878
879   return rc;
880 }
881
882 /* Note this is different than the original HKP refresh.  It allows
883    usernames to refresh only part of the keyring. */
884
885 int 
886 keyserver_refresh(STRLIST users)
887 {
888   int rc,count,fakev3=0;
889   KEYDB_SEARCH_DESC *desc;
890
891   /* We switch merge_only on during a refresh, as 'refresh' should
892      never import new keys, even if their keyids match.  Is it worth
893      preserving the old merge_only value here? */
894   opt.merge_only=1;
895
896   /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO
897      scheme, then enable fake v3 keyid generation. */
898   if(opt.keyserver_options.fake_v3_keyids && opt.keyserver_scheme &&
899      (ascii_strcasecmp(opt.keyserver_scheme,"hkp")==0 ||
900       ascii_strcasecmp(opt.keyserver_scheme,"mailto")==0))
901     fakev3=1;
902
903   rc=keyidlist(users,&desc,&count,fakev3);
904   if(rc)
905     return rc;
906
907   if(count==1)
908     log_info(_("refreshing 1 key from %s\n"),opt.keyserver_uri);
909   else
910     log_info(_("refreshing %d keys from %s\n"),count,opt.keyserver_uri);
911
912   if(count>0)
913     rc=keyserver_work(GET,NULL,desc,count);
914
915   m_free(desc);
916
917   return 0;
918 }
919
920 int 
921 keyserver_search(STRLIST tokens)
922 {
923   if(tokens)
924     return keyserver_work(SEARCH,tokens,NULL,0);
925   else
926     return 0;
927 }
928
929 /* Count and searchstr are just for cosmetics.  If the count is too
930    small, it will grow safely.  If negative it disables the "Key x-y
931    of z" messages. */
932 void 
933 keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
934 {
935   int i=0,validcount=1;
936   unsigned int maxlen=256,buflen=0;
937   KEYDB_SEARCH_DESC *desc;
938   byte *line=NULL;
939   char *answer;
940
941   if(count==0)
942     goto notfound;
943
944   if(count<0)
945     {
946       validcount=0;
947       count=10;
948     }
949
950   desc=m_alloc(count*sizeof(KEYDB_SEARCH_DESC));
951
952   /* Read each line and show it to the user */
953
954   for(;;)
955     {
956       int rl;
957
958       if(validcount && i%10==0)
959         {
960           printf("Keys %d-%d of %d",i+1,(i+10<count)?i+10:count,count);
961           if(searchstr)
962             printf(" for \"%s\"",searchstr);
963           printf("\n");
964         }
965
966       maxlen=1024;
967       rl=iobuf_read_line(buffer,&line,&buflen,&maxlen);
968       if(rl>0)
969         {
970           if(print_keyinfo(i+1,line,&desc[i])==0)
971             {
972               i++;
973
974               if(i==count)
975                 {
976                   count+=10;
977                   desc=m_realloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
978                   validcount=0;
979                 }
980             }
981           else
982             continue;
983         }
984
985       if(rl==0 && i==0)
986         {
987           count=0;
988           break;
989         }
990
991       if(i%10==0 || rl==0)
992         {
993           answer=cpr_get_no_help("keysearch.prompt",
994                                  _("Enter number(s), N)ext, or Q)uit > "));
995           /* control-d */
996           if(answer[0]=='\x04')
997             {
998               printf("Q\n");
999               answer[0]='q';
1000             }
1001
1002           if(answer[0]=='q' || answer[0]=='Q')
1003             {
1004               m_free(answer);
1005               break;
1006             }
1007           else if(atoi(answer)>=1 && atoi(answer)<=i)
1008             {
1009               char *split=answer,*num;
1010
1011               while((num=strsep(&split," ,"))!=NULL)
1012                 if(atoi(num)>=1 && atoi(num)<=i)
1013                   keyserver_work(GET,NULL,&desc[atoi(num)-1],1);
1014
1015               m_free(answer);
1016               break;
1017             }
1018         }
1019     }
1020
1021   m_free(desc);
1022   m_free(line);
1023
1024  notfound:
1025   if(count==0)
1026     {
1027       if(searchstr)
1028         log_info(_("key \"%s\" not found on keyserver\n"),searchstr);
1029       else
1030         log_info(_("key not found on keyserver\n"));
1031       return;
1032     }
1033 }