* gpgkeys_hkp.c (main), gpgkeys_ldap.c (main): Add -V flag to output
[gnupg.git] / keyserver / gpgkeys_ldap.c
1 /* gpgkeys_ldap.c - talk to a LDAP keyserver
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 <stdio.h>
23 #include <string.h>
24 #include <time.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #ifdef NEED_LBER_H
29 #include <lber.h>
30 #endif
31 #include <ldap.h>
32 #include "keyserver.h"
33
34 #ifdef __riscos__
35 #include "util.h"
36 #endif
37
38 #define GET    0
39 #define SEND   1
40 #define SEARCH 2
41 #define MAX_LINE 80
42
43 int verbose=0,include_disabled=0,include_revoked=0,include_subkeys=0;
44 char *basekeyspacedn=NULL;
45 char host[80]={'\0'};
46 char portstr[10]={'\0'};
47 char *pgpkeystr="pgpKey";
48 FILE *input=NULL,*output=NULL,*console=NULL;
49 LDAP *ldap=NULL;
50
51 struct keylist
52 {
53   char str[MAX_LINE];
54   struct keylist *next;
55 };
56
57 #ifdef __riscos__
58 RISCOS_GLOBAL_STATICS("LDAP Keyfetcher Heap")
59 #endif /* __riscos__ */
60
61 int
62 ldap_err_to_gpg_err(int err)
63 {
64   int ret;
65
66   switch(err)
67     {
68     case LDAP_ALREADY_EXISTS:
69       ret=KEYSERVER_KEY_EXISTS;
70       break;
71
72     case LDAP_SERVER_DOWN:
73       ret=KEYSERVER_UNREACHABLE;
74       break;
75
76     default:
77       ret=KEYSERVER_GENERAL_ERROR;
78       break;
79     }
80
81   return ret;
82 }
83
84 int
85 ldap_to_gpg_err(LDAP *ld)
86 {
87 #if defined(HAVE_LDAP_GET_OPTION)
88
89   int err;
90
91   if(ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&err)==0)
92     return ldap_err_to_gpg_err(err);
93   else
94     return KEYSERVER_GENERAL_ERROR;
95
96 #elif defined(HAVE_LDAP_LD_ERRNO)
97
98   return ldap_err_to_gpg_err(ld->ld_errno);
99
100 #else
101
102   /* We should never get here since the LDAP library should always
103      have either ldap_get_option or ld_errno, but just in case... */
104   return KEYSERVER_GENERAL_ERROR;
105
106 #endif
107 }
108
109 int
110 send_key(int *eof)
111 {
112   int err,gotit=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
113   char *dn=NULL,line[MAX_LINE],*key[2]={NULL,NULL};
114   char keyid[17];
115   LDAPMod mod, *attrs[2];
116
117   memset (&mod, 0, sizeof mod);
118   mod.mod_op      = LDAP_MOD_ADD;
119   mod.mod_type    = pgpkeystr;
120   mod.mod_values  = key;
121   attrs[0]    = &mod;
122   attrs[1]    = NULL;
123
124   dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1);
125   if(dn==NULL)
126     {
127       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
128       ret=KEYSERVER_NO_MEMORY;
129       goto fail;
130     }
131
132   strcpy(dn,"pgpCertid=virtual,");
133   strcat(dn,basekeyspacedn);
134
135   key[0]=malloc(1);
136   if(key[0]==NULL)
137     {
138       fprintf(console,"gpgkeys: unable to allocate memory for key\n");
139       ret=KEYSERVER_NO_MEMORY;
140       goto fail;
141     }
142
143   key[0][0]='\0';
144
145   /* Read and throw away stdin until we see the BEGIN */
146
147   while(fgets(line,MAX_LINE,input)!=NULL)
148     if(sscanf(line,"KEY %16s BEGIN\n",keyid)==1)
149       {
150         gotit=1;
151         break;
152       }
153
154   if(!gotit)
155     {
156       /* i.e. eof before the KEY BEGIN was found.  This isn't an
157          error. */
158       *eof=1;
159       ret=KEYSERVER_OK;
160       goto fail;
161     }
162
163   gotit=0;
164
165   /* Now slurp up everything until we see the END */
166
167   while(fgets(line,MAX_LINE,input)!=NULL)
168     if(sscanf(line,"KEY %16s END\n",keyid)==1)
169       {
170         gotit=1;
171         break;
172       }
173     else
174       {
175         keysize+=strlen(line);
176         key[0]=realloc(key[0],keysize);
177         if(key[0]==NULL)
178           {
179             fprintf(console,"gpgkeys: unable to reallocate for key\n");
180             ret=KEYSERVER_NO_MEMORY;
181             goto fail;
182           }
183
184         strcat(key[0],line);
185       }
186
187   if(!gotit)
188     {
189       fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
190       *eof=1;
191       ret=KEYSERVER_KEY_INCOMPLETE;
192       goto fail;
193     }
194
195   err=ldap_add_s(ldap,dn,attrs);
196   if(err!=LDAP_SUCCESS)
197     {
198       fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
199               keyid,ldap_err2string(err));
200       ret=ldap_err_to_gpg_err(err);
201       goto fail;
202     }
203
204   ret=KEYSERVER_OK;
205
206  fail:
207
208   free(key[0]);
209   free(dn);
210
211   if(ret!=0)
212     fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
213
214   /* Not a fatal error */
215   if(ret==KEYSERVER_KEY_EXISTS)
216     ret=KEYSERVER_OK;
217
218   return ret;
219 }
220
221 /* Note that key-not-found is not a fatal error */
222 int
223 get_key(char *getkey)
224 {
225   char **vals;
226   LDAPMessage *res,*each;
227   int ret=KEYSERVER_INTERNAL_ERROR,err,count;
228   struct keylist *dupelist=NULL;
229   char search[62];
230   char *attrs[]={"replaceme","pgpuserid","pgpkeyid","pgpcertid","pgprevoked",
231                  "pgpdisabled","pgpkeycreatetime","modifytimestamp",
232                  "pgpkeysize","pgpkeytype",NULL};
233   attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
234                          array initializers. */
235
236   /* Build the search string */
237
238   /* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3
239      or v4 short key id */
240
241   if(strncmp(getkey,"0x",2)==0)
242     getkey+=2;
243
244   if(strlen(getkey)==32)
245     {
246       fprintf(console,
247               "gpgkeys: LDAP keyservers do not support v3 fingerprints\n");
248       fprintf(output,"KEY 0x%s BEGIN\n",getkey);
249       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED);
250       return KEYSERVER_NOT_SUPPORTED;
251     }
252
253   if(strlen(getkey)>16)
254     {
255       char *offset=&getkey[strlen(getkey)-16];
256
257       /* fingerprint.  Take the last 16 characters and treat it like a
258          long key id */
259
260       if(include_subkeys)
261         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
262                 offset,offset);
263       else
264         sprintf(search,"(pgpcertid=%.16s)",offset);
265     }
266   else if(strlen(getkey)>8)
267     {
268       /* long key id */
269
270       if(include_subkeys)
271         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
272                 getkey,getkey);
273       else
274         sprintf(search,"(pgpcertid=%.16s)",getkey);
275     }
276   else
277     {
278       /* short key id */
279     
280       sprintf(search,"(pgpkeyid=%.8s)",getkey);
281     }
282
283   fprintf(output,"KEY 0x%s BEGIN\n",getkey);
284
285   if(verbose>2)
286     fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
287
288   if(!verbose)
289     attrs[1]=NULL;
290
291   if(verbose)
292     fprintf(console,"gpgkeys: requesting key 0x%s from ldap://%s%s%s\n",
293             getkey,host,portstr[0]?":":"",portstr[0]?portstr:"");
294
295   err=ldap_search_s(ldap,basekeyspacedn,
296                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
297   if(err!=0)
298     {
299       int errtag=ldap_err_to_gpg_err(err);
300
301       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
302       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
303       return errtag;
304     }
305
306   count=ldap_count_entries(ldap,res);
307   if(count<1)
308     {
309       fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
310       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
311     }
312   else
313     {
314       /* There may be more than one unique result for a given keyID,
315          so we should fetch them all (test this by fetching short key
316          id 0xDEADBEEF). */
317
318       each=ldap_first_entry(ldap,res);
319       while(each!=NULL)
320         {
321           struct keylist *keyptr=dupelist;
322
323           /* Use the long keyid to remove duplicates.  The LDAP server
324              returns the same keyid more than once if there are
325              multiple user IDs on the key.  Note that this does NOT
326              mean that a keyid that exists multiple times on the
327              keyserver will not be fetched.  It means that each KEY,
328              no matter how many user IDs share it's keyid, will be
329              fetched only once.  If a keyid that belongs to more than
330              one key is fetched, the server quite properly responds
331              with all matching keys. -ds */
332
333           vals=ldap_get_values(ldap,each,"pgpcertid");
334           if(vals!=NULL)
335             {
336               while(keyptr!=NULL)
337                 {
338                   if(strcasecmp(keyptr->str,vals[0])==0)
339                     break;
340
341                   keyptr=keyptr->next;
342                 }
343
344               if(!keyptr)
345                 {
346                   /* it's not a duplicate, so add it */
347
348                   keyptr=malloc(sizeof(struct keylist));
349                   if(keyptr==NULL)
350                     {
351                       fprintf(console,"gpgkeys: out of memory when deduping "
352                               "key list\n");
353                       ret=KEYSERVER_NO_MEMORY;
354                       goto fail;
355                     }
356
357                   strncpy(keyptr->str,vals[0],MAX_LINE);
358                   keyptr->str[MAX_LINE-1]='\0';
359
360                   keyptr->next=dupelist;
361                   dupelist=keyptr;
362                   keyptr=NULL;
363                 }
364
365               ldap_value_free(vals);
366             }
367
368           if(!keyptr) /* it's not a duplicate */
369             {
370               if(verbose)
371                 {
372                   vals=ldap_get_values(ldap,each,"pgpuserid");
373                   if(vals!=NULL)
374                     {
375                       /* This is wrong, as the user ID is UTF8.  A
376                          better way to handle this would be to send it
377                          over to gpg and display it on that side of
378                          the pipe. */
379                       fprintf(console,"\nUser ID:\t%s\n",vals[0]);
380                       ldap_value_free(vals);
381                     }
382
383                   vals=ldap_get_values(ldap,each,"pgprevoked");
384                   if(vals!=NULL)
385                     {
386                       if(atoi(vals[0])==1)
387                         fprintf(console,"\t\t** KEY REVOKED **\n");
388                       ldap_value_free(vals);
389                     }
390
391                   vals=ldap_get_values(ldap,each,"pgpdisabled");
392                   if(vals!=NULL)
393                     {
394                       if(atoi(vals[0])==1)
395                         fprintf(console,"\t\t** KEY DISABLED **\n");
396                       ldap_value_free(vals);
397                     }
398
399                   vals=ldap_get_values(ldap,each,"pgpkeyid");
400                   if(vals!=NULL)
401                     {
402                       fprintf(console,"Short key ID:\t%s\n",vals[0]);
403                       ldap_value_free(vals);
404                     }
405
406                   vals=ldap_get_values(ldap,each,"pgpcertid");
407                   if(vals!=NULL)
408                     {
409                       fprintf(console,"Long key ID:\t%s\n",vals[0]);
410                       ldap_value_free(vals);
411                     }
412
413                   /* YYYYMMDDHHmmssZ */
414
415                   vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
416                   if(vals!=NULL)
417                     {
418                       if(strlen(vals[0])==15)
419                         fprintf(console,"Key created:\t%.2s/%.2s/%.4s\n",
420                                 &vals[0][4],&vals[0][6],vals[0]);
421                       ldap_value_free(vals);
422                     }
423
424                   vals=ldap_get_values(ldap,each,"modifytimestamp");
425                   if(vals!=NULL)
426                     {
427                       if(strlen(vals[0])==15)
428                         fprintf(console,"Key modified:\t%.2s/%.2s/%.4s\n",
429                                 &vals[0][4],&vals[0][6],vals[0]);
430                       ldap_value_free(vals);
431                     }
432
433                   vals=ldap_get_values(ldap,each,"pgpkeysize");
434                   if(vals!=NULL)
435                     {
436                       if(atoi(vals[0])>0)
437                         fprintf(console,"Key size:\t%d\n",atoi(vals[0]));
438                       ldap_value_free(vals);
439                     }
440
441                   vals=ldap_get_values(ldap,each,"pgpkeytype");
442                   if(vals!=NULL)
443                     {
444                       fprintf(console,"Key type:\t%s\n",vals[0]);
445                       ldap_value_free(vals);
446                     }
447                 }
448
449               vals=ldap_get_values(ldap,each,pgpkeystr);
450               if(vals==NULL)
451                 {
452                   int errtag=ldap_to_gpg_err(ldap);
453
454                   fprintf(console,"gpgkeys: unable to retrieve key %s "
455                           "from keyserver\n",getkey);
456                   fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
457                 }
458               else
459                 {
460                   fprintf(output,"%sKEY 0x%s END\n",vals[0],getkey);
461
462                   ldap_value_free(vals);
463                 }
464             }
465
466           each=ldap_next_entry(ldap,each);
467         }
468     }
469
470   ret=KEYSERVER_OK;
471
472  fail:
473   ldap_msgfree(res);
474
475   /* free up the dupe checker */
476   while(dupelist!=NULL)
477     {
478       struct keylist *keyptr=dupelist;
479
480       dupelist=keyptr->next;
481       free(keyptr);
482     }
483
484   return ret;
485 }
486
487 time_t
488 ldap2epochtime(const char *timestr)
489 {
490   struct tm pgptime;
491
492   memset(&pgptime,0,sizeof(pgptime));
493
494   /* YYYYMMDDHHmmssZ */
495
496   sscanf(timestr,"%4d%2d%2d%2d%2d%2d",
497          &pgptime.tm_year,
498          &pgptime.tm_mon,
499          &pgptime.tm_mday,
500          &pgptime.tm_hour,
501          &pgptime.tm_min,
502          &pgptime.tm_sec);
503
504   pgptime.tm_year-=1900;
505   pgptime.tm_isdst=-1;
506   pgptime.tm_mon--;
507
508   return mktime(&pgptime);
509 }
510
511 void
512 printquoted(FILE *stream,char *string,char delim)
513 {
514   while(*string)
515     {
516       if(*string==delim || *string=='%')
517         fprintf(stream,"%%%02x",*string);
518       else
519         fputc(*string,stream);
520
521       string++;
522     }
523 }
524
525 /* Returns 0 on success and -1 on error.  Note that key-not-found is
526    not an error! */
527 int
528 search_key(char *searchkey)
529 {
530   char **vals;
531   LDAPMessage *res,*each;
532   int err,count;
533   /* The maxium size of the search, including the optional stuff and
534      the trailing \0 */
535   char search[2+12+MAX_LINE+2+15+14+1+1];
536   char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
537                  "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
538                  "pgpkeysize","pgpkeytype",NULL};
539
540   fprintf(output,"SEARCH %s BEGIN\n",searchkey);
541
542   /* Build the search string */
543
544   sprintf(search,"%s(pgpuserid=*%s*)%s%s%s",
545           (!(include_disabled&&include_revoked))?"(&":"",
546           searchkey,
547           include_disabled?"":"(pgpdisabled=0)",
548           include_revoked?"":"(pgprevoked=0)",
549           !(include_disabled&&include_revoked)?")":"");
550
551   if(verbose>2)
552     fprintf(console,"gpgkeys: LDAP search for: %s\n",search);
553
554   fprintf(console,("gpgkeys: searching for \"%s\" from LDAP server %s\n"),
555           searchkey,host);
556
557   err=ldap_search_s(ldap,basekeyspacedn,
558                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
559   if(err!=0)
560     {
561       int errtag=ldap_err_to_gpg_err(err);
562
563       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,errtag);
564       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
565       return errtag;
566     }
567
568   count=ldap_count_entries(ldap,res);
569
570   if(count<1)
571     fprintf(output,"info:1:0\n");
572   else
573     {
574       fprintf(output,"info:1:%d\n",count);
575
576       each=ldap_first_entry(ldap,res);
577       while(each!=NULL)
578         {
579           fprintf(output,"pub:");
580
581           vals=ldap_get_values(ldap,each,"pgpcertid");
582           if(vals!=NULL)
583             {
584               fprintf(output,"%s",vals[0]);
585               ldap_value_free(vals);
586             }
587
588           fputc(':',output);
589
590           vals=ldap_get_values(ldap,each,"pgpkeytype");
591           if(vals!=NULL)
592             {
593               /* The LDAP server doesn't exactly handle this well. */
594               if(strcasecmp(vals[0],"RSA")==0)
595                 fprintf(output,"1");
596               else if(strcasecmp(vals[0],"DSS/DH")==0)
597                 fprintf(output,"17");
598               ldap_value_free(vals);
599             }
600
601           fputc(':',output);
602
603           vals=ldap_get_values(ldap,each,"pgpkeysize");
604           if(vals!=NULL)
605             {
606               /* Not sure why, but some keys are listed with a key size of
607                  0.  Treat that like an unknown. */
608               if(atoi(vals[0])>0)
609                 fprintf(output,"%d",atoi(vals[0]));
610               ldap_value_free(vals);
611             }
612
613           fputc(':',output);
614
615           /* YYYYMMDDHHmmssZ */
616
617           vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
618           if(vals!=NULL && strlen(vals[0])==15)
619             {
620               fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
621               ldap_value_free(vals);
622             }
623
624           fputc(':',output);
625
626           vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
627           if(vals!=NULL && strlen(vals[0])==15)
628             {
629               fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
630               ldap_value_free(vals);
631             }
632
633           fputc(':',output);
634
635           vals=ldap_get_values(ldap,each,"pgprevoked");
636           if(vals!=NULL)
637             {
638               if(atoi(vals[0])==1)
639                 fprintf(output,"r");
640               ldap_value_free(vals);
641             }
642
643           vals=ldap_get_values(ldap,each,"pgpdisabled");
644           if(vals!=NULL)
645             {
646               if(atoi(vals[0])==1)
647                 fprintf(output,"d");
648               ldap_value_free(vals);
649             }
650
651           fputc(':',output);
652
653           vals=ldap_get_values(ldap,each,"modifytimestamp");
654           if(vals!=NULL && strlen(vals[0])==15)
655             {
656               fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
657               ldap_value_free(vals);
658             }
659
660           fprintf(output,"\nuid:");
661
662           vals=ldap_get_values(ldap,each,"pgpuserid");
663           if(vals!=NULL)
664             {
665               /* Need to escape any colons */
666               printquoted(output,vals[0],':');
667               ldap_value_free(vals);
668             }
669
670           fprintf(output,"\n");
671
672           each=ldap_next_entry(ldap,each);
673         }
674     }
675
676   ldap_msgfree(res);
677
678   fprintf(output,"SEARCH %s END\n",searchkey);
679
680   return KEYSERVER_OK;
681 }
682
683 void
684 fail_all(struct keylist *keylist,int action,int err)
685 {
686   if(!keylist)
687     return;
688
689   if(action==SEARCH)
690     {
691       fprintf(output,"SEARCH ");
692       while(keylist)
693         {
694           fprintf(output,"%s ",keylist->str);
695           keylist=keylist->next;
696         }
697       fprintf(output,"FAILED %d\n",err);
698     }
699   else
700     while(keylist)
701       {
702         fprintf(output,"KEY %s FAILED %d\n",keylist->str,err);
703         keylist=keylist->next;
704       }
705 }
706
707 int
708 main(int argc,char *argv[])
709 {
710   int port=0,arg,err,action=-1,ret=KEYSERVER_INTERNAL_ERROR;
711   char line[MAX_LINE],**vals;
712   int version,failed=0;
713   char *attrs[]={"basekeyspacedn","version","software",NULL};
714   LDAPMessage *res;
715   struct keylist *keylist=NULL,*keyptr=NULL;
716
717 #ifdef __riscos__
718   riscos_global_defaults();
719 #endif
720
721   console=stderr;
722
723   while((arg=getopt(argc,argv,"hVo:"))!=-1)
724     switch(arg)
725       {
726       default:
727       case 'h':
728         fprintf(console,"-h\thelp\n");
729         fprintf(console,"-V\tversion\n");
730         fprintf(console,"-o\toutput to this file\n");
731         return KEYSERVER_OK;
732
733       case 'V':
734         fprintf(stdout,"0\n%s\n",VERSION);
735         return KEYSERVER_OK;
736
737       case 'o':
738         output=fopen(optarg,"w");
739         if(output==NULL)
740           {
741             fprintf(console,"gpgkeys: Cannot open output file \"%s\": %s\n",
742                     optarg,strerror(errno));
743             return KEYSERVER_INTERNAL_ERROR;
744           }
745
746         break;
747       }
748
749   if(argc>optind)
750     {
751       input=fopen(argv[optind],"r");
752       if(input==NULL)
753         {
754           fprintf(console,"gpgkeys: Cannot open input file \"%s\": %s\n",
755                   argv[optind],strerror(errno));
756           return KEYSERVER_INTERNAL_ERROR;
757         }
758     }
759
760   if(input==NULL)
761     input=stdin;
762
763   if(output==NULL)
764     output=stdout;
765
766   /* Get the command and info block */
767
768   while(fgets(line,MAX_LINE,input)!=NULL)
769     {
770       char commandstr[7];
771       char optionstr[30];
772       char hash;
773
774       if(line[0]=='\n')
775         break;
776
777       if(sscanf(line,"%c",&hash)==1 && hash=='#')
778         continue;
779
780       if(sscanf(line,"COMMAND %6s\n",commandstr)==1)
781         {
782           commandstr[6]='\0';
783
784           if(strcasecmp(commandstr,"get")==0)
785             action=GET;
786           else if(strcasecmp(commandstr,"send")==0)
787             action=SEND;
788           else if(strcasecmp(commandstr,"search")==0)
789             action=SEARCH;
790
791           continue;
792         }
793
794       if(sscanf(line,"HOST %79s\n",host)==1)
795         {
796           host[79]='\0';
797           continue;
798         }
799
800       if(sscanf(line,"PORT %9s\n",portstr)==1)
801         {
802           portstr[9]='\0';
803           port=atoi(portstr);
804           continue;
805         }
806
807       if(sscanf(line,"VERSION %d\n",&version)==1)
808         {
809           if(version!=KEYSERVER_PROTO_VERSION)
810             {
811               ret=KEYSERVER_VERSION_ERROR;
812               goto fail;
813             }
814
815           continue;
816         }
817
818       if(sscanf(line,"OPTION %29s\n",optionstr)==1)
819         {
820           int no=0;
821           char *start=&optionstr[0];
822
823           optionstr[29]='\0';
824
825           if(strncasecmp(optionstr,"no-",3)==0)
826             {
827               no=1;
828               start=&optionstr[3];
829             }
830
831           if(strcasecmp(start,"verbose")==0)
832             {
833               if(no)
834                 verbose--;
835               else
836                 verbose++;
837             }
838           else if(strcasecmp(start,"include-disabled")==0)
839             {
840               if(no)
841                 include_disabled=0;
842               else
843                 include_disabled=1;
844             }
845           else if(strcasecmp(start,"include-revoked")==0)
846             {
847               if(no)
848                 include_revoked=0;
849               else
850                 include_revoked=1;
851             }
852           else if(strcasecmp(start,"include-subkeys")==0)
853             {
854               if(no)
855                 include_subkeys=0;
856               else
857                 include_subkeys=1;
858             }
859
860           continue;
861         }
862     }
863
864   /* If it's a GET or a SEARCH, the next thing to come in is the
865      keyids.  If it's a SEND, then there are no keyids. */
866
867   if(action==SEND)
868     while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
869   else if(action==GET || action==SEARCH)
870     {
871       for(;;)
872         {
873           struct keylist *work;
874
875           if(fgets(line,MAX_LINE,input)==NULL)
876             break;
877           else
878             {
879               if(line[0]=='\n')
880                 break;
881
882               work=malloc(sizeof(struct keylist));
883               if(work==NULL)
884                 {
885                   fprintf(console,"gpgkeys: out of memory while "
886                           "building key list\n");
887                   ret=KEYSERVER_NO_MEMORY;
888                   goto fail;
889                 }
890
891               strcpy(work->str,line);
892
893               /* Trim the trailing \n */
894               work->str[strlen(line)-1]='\0';
895
896               work->next=NULL;
897
898               /* Always attach at the end to keep the list in proper
899                  order for searching */
900               if(keylist==NULL)
901                 keylist=work;
902               else
903                 keyptr->next=work;
904
905               keyptr=work;
906             }
907         }
908     }
909   else
910     {
911       fprintf(console,"gpgkeys: no keyserver command specified\n");
912       goto fail;
913     }
914
915   /* Send the response */
916
917   fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
918   fprintf(output,"PROGRAM %s\n\n",VERSION);
919
920   if(verbose>1)
921     {
922       fprintf(console,"Host:\t\t%s\n",host);
923       if(port)
924         fprintf(console,"Port:\t\t%d\n",port);
925       fprintf(console,"Command:\t%s\n",action==GET?"GET":
926               action==SEND?"SEND":"SEARCH");
927     }
928
929   /* Note that this tries all A records on a given host (or at least,
930      OpenLDAP does). */
931   ldap=ldap_init(host,port);
932   if(ldap==NULL)
933     {
934       fprintf(console,"gpgkeys: internal LDAP init error: %s\n",
935               strerror(errno));
936       fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
937       goto fail;
938     }
939
940   err=ldap_simple_bind_s(ldap,NULL,NULL);
941   if(err!=0)
942     {
943       fprintf(console,"gpgkeys: internal LDAP bind error: %s\n",
944               ldap_err2string(err));
945       fail_all(keylist,action,ldap_err_to_gpg_err(err));
946       goto fail;
947     }
948
949   /* Get the magic info record */
950
951   err=ldap_search_s(ldap,"cn=PGPServerInfo",LDAP_SCOPE_BASE,
952                     "(objectclass=*)",attrs,0,&res);
953   if(err!=0)
954     {
955       fprintf(console,"gpgkeys: error retrieving LDAP server info: %s\n",
956               ldap_err2string(err));
957       fail_all(keylist,action,ldap_err_to_gpg_err(err));
958       goto fail;
959     }
960
961   if(ldap_count_entries(ldap,res)!=1)
962     {
963       fprintf(console,"gpgkeys: more than one serverinfo record\n");
964       fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
965       goto fail;
966     }
967
968   if(verbose>1)
969     {
970       vals=ldap_get_values(ldap,res,"software");
971       if(vals!=NULL)
972         {
973           fprintf(console,"Server: \t%s\n",vals[0]);
974           ldap_value_free(vals);
975         }
976     }
977
978   vals=ldap_get_values(ldap,res,"version");
979   if(vals!=NULL)
980     {
981       if(verbose>1)
982         fprintf(console,"Version:\t%s\n",vals[0]);
983
984       /* If the version is high enough, use the new pgpKeyV2
985          attribute.  This design if iffy at best, but it matches how
986          PGP does it.  I figure the NAI folks assumed that there would
987          never be a LDAP keyserver vendor with a different numbering
988          scheme. */
989       if(atoi(vals[0])>1)
990         pgpkeystr="pgpKeyV2";
991
992       ldap_value_free(vals);
993     }
994
995   /* This is always "OU=ACTIVE,O=PGP KEYSPACE,C=US", but it might not
996      be in the future. */
997
998   vals=ldap_get_values(ldap,res,"basekeyspacedn");
999   if(vals!=NULL)
1000     {
1001       basekeyspacedn=strdup(vals[0]);
1002       ldap_value_free(vals);
1003       if(basekeyspacedn==NULL)
1004         {
1005           fprintf(console,"gpgkeys: can't allocate string space "
1006                   "for LDAP base\n");
1007           fail_all(keylist,action,KEYSERVER_NO_MEMORY);
1008           goto fail;
1009         }
1010     }
1011
1012   ldap_msgfree(res);
1013
1014   switch(action)
1015     {
1016     case GET:
1017       keyptr=keylist;
1018
1019       while(keyptr!=NULL)
1020         {
1021           if(get_key(keyptr->str)!=KEYSERVER_OK)
1022             failed++;
1023
1024           keyptr=keyptr->next;
1025         }
1026       break;
1027
1028     case SEND:
1029       {
1030         int eof=0;
1031
1032         do
1033           {
1034             if(send_key(&eof)!=KEYSERVER_OK)
1035               failed++;
1036           }
1037         while(!eof);
1038       }
1039       break;
1040
1041     case SEARCH:
1042       {
1043         char *searchkey=NULL;
1044         int len=0;
1045
1046         /* To search, we stick a * in between each key to search for.
1047            This means that if the user enters words, they'll get
1048            "enters*words".  If the user "enters words", they'll get
1049            "enters words" */
1050
1051         keyptr=keylist;
1052         while(keyptr!=NULL)
1053           {
1054             len+=strlen(keyptr->str)+1;
1055             keyptr=keyptr->next;
1056           }
1057
1058         searchkey=malloc(len+1);
1059         if(searchkey==NULL)
1060           {
1061             ret=KEYSERVER_NO_MEMORY;
1062             fail_all(keylist,action,KEYSERVER_NO_MEMORY);
1063             goto fail;
1064           }
1065
1066         searchkey[0]='\0';
1067
1068         keyptr=keylist;
1069         while(keyptr!=NULL)
1070           {
1071             strcat(searchkey,keyptr->str);
1072             strcat(searchkey,"*");
1073             keyptr=keyptr->next;
1074           }
1075
1076         /* Nail that last "*" */
1077         searchkey[strlen(searchkey)-1]='\0';
1078
1079         if(search_key(searchkey)!=KEYSERVER_OK)
1080           failed++;
1081
1082         free(searchkey);
1083       }
1084
1085       break;
1086     }
1087
1088   if(!failed)
1089     ret=KEYSERVER_OK;
1090
1091  fail:
1092
1093   while(keylist!=NULL)
1094     {
1095       struct keylist *current=keylist;
1096       keylist=keylist->next;
1097       free(current);
1098     }
1099
1100   if(input!=stdin)
1101     fclose(input);
1102
1103   if(output!=stdout)
1104     fclose(output);
1105
1106   if(ldap!=NULL)
1107     ldap_unbind_s(ldap);
1108
1109   free(basekeyspacedn);
1110
1111   return ret;
1112 }