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