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