* gpgkeys_ldap.c (ldap2epochtime): We can always rely on timegm() being
[gnupg.git] / keyserver / gpgkeys_ldap.c
1 /* gpgkeys_ldap.c - talk to a LDAP keyserver
2  * Copyright (C) 2001, 2002, 2004 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 #ifdef HAVE_GETOPT_H
27 #include <getopt.h>
28 #endif
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <ldap.h>
32 #include "util.h"
33 #include "keyserver.h"
34
35 #ifdef __riscos__
36 #include "util.h"
37 #endif
38
39 extern char *optarg;
40 extern int optind;
41
42 #define GET    0
43 #define SEND   1
44 #define SEARCH 2
45 #define MAX_LINE 256
46
47 static int verbose=0,include_disabled=0,include_revoked=0,include_subkeys=0;
48 static int real_ldap=0;
49 static char *basekeyspacedn=NULL;
50 static char host[80]={'\0'};
51 static char portstr[10]={'\0'};
52 static char *pgpkeystr="pgpKey";
53 static FILE *input=NULL,*output=NULL,*console=NULL;
54 static LDAP *ldap=NULL;
55
56 #ifndef HAVE_TIMEGM
57 time_t timegm(struct tm *tm);
58 #endif
59
60 struct keylist
61 {
62   char str[MAX_LINE];
63   struct keylist *next;
64 };
65
66 static int
67 ldap_err_to_gpg_err(int err)
68 {
69   int ret;
70
71   switch(err)
72     {
73     case LDAP_ALREADY_EXISTS:
74       ret=KEYSERVER_KEY_EXISTS;
75       break;
76
77     case LDAP_SERVER_DOWN:
78       ret=KEYSERVER_UNREACHABLE;
79       break;
80
81     default:
82       ret=KEYSERVER_GENERAL_ERROR;
83       break;
84     }
85
86   return ret;
87 }
88
89 static int
90 ldap_to_gpg_err(LDAP *ld)
91 {
92 #if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
93
94   int err;
95
96   if(ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&err)==0)
97     return ldap_err_to_gpg_err(err);
98   else
99     return KEYSERVER_GENERAL_ERROR;
100
101 #elif defined(HAVE_LDAP_LD_ERRNO)
102
103   return ldap_err_to_gpg_err(ld->ld_errno);
104
105 #else
106
107   /* We should never get here since the LDAP library should always
108      have either ldap_get_option or ld_errno, but just in case... */
109   return KEYSERVER_GENERAL_ERROR;
110
111 #endif
112 }
113
114 static int
115 key_in_keylist(const char *key,struct keylist *list)
116 {
117   struct keylist *keyptr=list;
118
119   while(keyptr!=NULL)
120     {
121       if(strcasecmp(key,keyptr->str)==0)
122         return 1;
123
124       keyptr=keyptr->next;
125     }
126
127   return 0;
128 }
129
130 static int
131 add_key_to_keylist(const char *key,struct keylist **list)
132 {
133   struct keylist *keyptr=malloc(sizeof(struct keylist));
134
135   if(keyptr==NULL)
136     {
137       fprintf(console,"gpgkeys: out of memory when deduping "
138               "key list\n");
139       return KEYSERVER_NO_MEMORY;
140     }
141
142   strncpy(keyptr->str,key,MAX_LINE);
143   keyptr->str[MAX_LINE-1]='\0';
144   keyptr->next=*list;
145   *list=keyptr;
146
147   return 0;
148 }
149
150 static void
151 free_keylist(struct keylist *list)
152 {
153   while(list!=NULL)
154     {
155       struct keylist *keyptr=list;
156
157       list=keyptr->next;
158       free(keyptr);
159     }
160 }
161
162 static time_t
163 ldap2epochtime(const char *timestr)
164 {
165   struct tm pgptime;
166   time_t answer;
167
168   memset(&pgptime,0,sizeof(pgptime));
169
170   /* YYYYMMDDHHmmssZ */
171
172   sscanf(timestr,"%4d%2d%2d%2d%2d%2d",
173          &pgptime.tm_year,
174          &pgptime.tm_mon,
175          &pgptime.tm_mday,
176          &pgptime.tm_hour,
177          &pgptime.tm_min,
178          &pgptime.tm_sec);
179
180   pgptime.tm_year-=1900;
181   pgptime.tm_isdst=-1;
182   pgptime.tm_mon--;
183
184   /* mktime() takes the timezone into account, so we use timegm() */
185
186   answer=timegm(&pgptime);
187
188   return answer;
189 }
190
191 /* Caller must free */
192 static char *
193 epoch2ldaptime(time_t stamp)
194 {
195   struct tm *ldaptime;
196   char buf[16];
197
198   ldaptime=gmtime(&stamp);
199
200   ldaptime->tm_year+=1900;
201   ldaptime->tm_mon++;
202
203   /* YYYYMMDDHHmmssZ */
204
205   sprintf(buf,"%04d%02d%02d%02d%02d%02dZ",
206           ldaptime->tm_year,
207           ldaptime->tm_mon,
208           ldaptime->tm_mday,
209           ldaptime->tm_hour,
210           ldaptime->tm_min,
211           ldaptime->tm_sec);
212
213   return strdup(buf);
214 }
215
216 /* Passing a NULL for value effectively deletes that attribute.  This
217    doesn't mean "delete" in the sense of removing something from the
218    modlist, but "delete" in the LDAP sense of adding a modlist item
219    that specifies LDAP_MOD_REPLACE and a null attribute for the given
220    attribute.  LDAP_MOD_DELETE doesn't work here as we don't know if
221    the attribute in question exists or not. */
222
223 static int
224 make_one_attr(LDAPMod ***modlist,int unique,char *attr,const char *value)
225 {
226   LDAPMod **m;
227   int nummods=0;
228
229   /* Search modlist for the attribute we're playing with. */
230   for(m=*modlist;*m;m++)
231     {
232       if(strcasecmp((*m)->mod_type,attr)==0)
233         {
234           char **ptr=(*m)->mod_values;
235           int numvalues=0;
236
237           /* We have this attribute already, so when the REPLACE
238              happens, the server attributes will be replaced
239              anyway. */
240           if(!value)
241             return 1;
242
243           if(ptr)
244             for(ptr=(*m)->mod_values;*ptr;ptr++)
245               {
246                 if(unique && strcmp(*ptr,value)==0)
247                   return 1;
248                 numvalues++;
249               }
250
251           ptr=realloc((*m)->mod_values,sizeof(char *)*(numvalues+2));
252           if(!ptr)
253             return 0;
254
255           (*m)->mod_values=ptr;
256           ptr[numvalues]=strdup(value);
257           if(!ptr[numvalues])
258             return 0;
259
260           ptr[numvalues+1]=NULL;
261           break;
262         }
263
264       nummods++;
265     }
266
267   /* We didn't find the attr, so make one and add it to the end */
268   if(!*m)
269     {
270       LDAPMod **grow;
271
272       grow=realloc(*modlist,sizeof(LDAPMod *)*(nummods+2));
273       if(!grow)
274         return 0;
275
276       *modlist=grow;
277       grow[nummods]=malloc(sizeof(LDAPMod));
278       if(!grow[nummods])
279         return 0;
280       grow[nummods]->mod_op=LDAP_MOD_REPLACE;
281       grow[nummods]->mod_type=attr;
282       if(value)
283         {
284           grow[nummods]->mod_values=malloc(sizeof(char *)*2);
285           if(!grow[nummods]->mod_values)
286             {
287               grow[nummods]=NULL;
288               return 0;
289             }
290
291           /* Is this the right thing?  Can a UTF8-encoded user ID have
292              embedded nulls? */
293           grow[nummods]->mod_values[0]=strdup(value);
294           if(!grow[nummods]->mod_values[0])
295             {
296               free(grow[nummods]->mod_values);
297               grow[nummods]=NULL;
298               return 0;
299             }
300
301           grow[nummods]->mod_values[1]=NULL;
302         }
303       else
304         grow[nummods]->mod_values=NULL;
305
306       grow[nummods+1]=NULL;
307     }
308
309   return 1;
310 }
311
312 static void
313 build_attrs(LDAPMod ***modlist,char *line)
314 {
315   char *record;
316   int i;
317
318   /* Remove trailing whitespace */
319   for(i=strlen(line);i>0;i--)
320     if(ascii_isspace(line[i-1]))
321       line[i-1]='\0';
322     else
323       break;
324
325   if((record=strsep(&line,":"))==NULL)
326     return;
327
328   if(ascii_strcasecmp("pub",record)==0)
329     {
330       char *tok;
331       int disabled=0,revoked=0;
332
333       /* The long keyid */
334       if((tok=strsep(&line,":"))==NULL)
335         return;
336
337       if(strlen(tok)==16)
338         {
339           make_one_attr(modlist,0,"pgpCertID",tok);
340           make_one_attr(modlist,0,"pgpKeyID",&tok[8]);
341         }
342       else
343         return;
344
345       /* The primary pubkey algo */
346       if((tok=strsep(&line,":"))==NULL)
347         return;
348
349       switch(atoi(tok))
350         {
351         case 1:
352           make_one_attr(modlist,0,"pgpKeyType","RSA");
353           break;
354
355         case 17:
356           make_one_attr(modlist,0,"pgpKeyType","DSS/DH");
357           break;
358         }
359
360       /* Size of primary key */
361       if((tok=strsep(&line,":"))==NULL)
362         return;
363
364       if(atoi(tok)>0)
365         {
366           char padded[6];
367           int val=atoi(tok);
368
369           /* We zero pad this on the left to make PGP happy. */
370
371           if(val<99999 && val>0)
372             {
373               sprintf(padded,"%05u",atoi(tok));
374               make_one_attr(modlist,0,"pgpKeySize",padded);
375             }
376         }
377
378       /* pk timestamp */
379       if((tok=strsep(&line,":"))==NULL)
380         return;
381
382       if(atoi(tok)>0)
383         {
384           char *stamp=epoch2ldaptime(atoi(tok));
385           if(stamp)
386             {
387               make_one_attr(modlist,0,"pgpKeyCreateTime",stamp);
388               free(stamp);
389             }
390         }
391
392       /* pk expire */
393       if((tok=strsep(&line,":"))==NULL)
394         return;
395
396       if(atoi(tok)>0)
397         {
398           char *stamp=epoch2ldaptime(atoi(tok));
399           if(stamp)
400             {
401               make_one_attr(modlist,0,"pgpKeyExpireTime",stamp);
402               free(stamp);
403             }
404         }
405
406       /* flags */
407       if((tok=strsep(&line,":"))==NULL)
408         return;
409
410       while(*tok)
411         switch(*tok++)
412           {
413           case 'r':
414           case 'R':
415             revoked=1;
416             break;
417             
418           case 'd':
419           case 'D':
420             disabled=1;
421             break;
422           }
423
424       /*
425         Note that we always create the pgpDisabled and pgpRevoked
426         attributes, regardless of whether the key is disabled/revoked
427         or not.  This is because a very common search is like
428         "(&(pgpUserID=*isabella*)(pgpDisabled=0))"
429       */
430
431       make_one_attr(modlist,0,"pgpDisabled",disabled?"1":"0");
432       make_one_attr(modlist,0,"pgpRevoked",revoked?"1":"0");
433     }
434   else if(ascii_strcasecmp("uid",record)==0)
435     {
436       char *userid,*tok;
437
438       /* The user ID string */
439       if((tok=strsep(&line,":"))==NULL)
440         return;
441
442       if(strlen(tok)==0)
443         return;
444
445       userid=tok;
446
447       /* By definition, de-%-encoding is always smaller than the
448          original string so we can decode in place. */
449
450       i=0;
451
452       while(*tok)
453         if(tok[0]=='%' && tok[1] && tok[2])
454           {
455             if((userid[i]=hextobyte(&tok[1]))==-1)
456               userid[i]='?';
457
458             i++;
459             tok+=3;
460           }
461         else
462           userid[i++]=*tok++;
463
464       /* We don't care about the other info provided in the uid: line
465          since the LDAP schema doesn't need it. */
466
467       make_one_attr(modlist,0,"pgpUserID",userid);
468     }
469   else if(ascii_strcasecmp("sig",record)==0)
470     {
471       char *tok;
472
473       if((tok=strsep(&line,":"))==NULL)
474         return;
475
476       if(strlen(tok)==16)
477         make_one_attr(modlist,1,"pgpSignerID",tok);
478     }
479 }
480
481 static void
482 free_mod_values(LDAPMod *mod)
483 {
484   char **ptr;
485
486   if(!mod->mod_values)
487     return;
488
489   for(ptr=mod->mod_values;*ptr;ptr++)
490     free(*ptr);
491
492   free(mod->mod_values);
493 }
494
495 static int
496 send_key(int *eof)
497 {
498   int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
499   char *dn=NULL,line[MAX_LINE],*key=NULL;
500   char keyid[17];
501   LDAPMod **modlist,**ml;
502
503   modlist=malloc(sizeof(LDAPMod *));
504   if(!modlist)
505     {
506       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
507       ret=KEYSERVER_NO_MEMORY;
508       goto fail;
509     }
510
511   *modlist=NULL;
512
513   /* Going on the assumption that modify operations are more frequent
514      than adds, I'm setting up the modify operations here first. */
515   make_one_attr(&modlist,0,"pgpDisabled",NULL);
516   make_one_attr(&modlist,0,"pgpKeyID",NULL);
517   make_one_attr(&modlist,0,"pgpKeyType",NULL);
518   make_one_attr(&modlist,0,"pgpUserID",NULL);
519   make_one_attr(&modlist,0,"pgpKeyCreateTime",NULL);
520   make_one_attr(&modlist,0,"pgpSignerID",NULL);
521   make_one_attr(&modlist,0,"pgpRevoked",NULL);
522   make_one_attr(&modlist,0,"pgpSubKeyID",NULL);
523   make_one_attr(&modlist,0,"pgpKeySize",NULL);
524   make_one_attr(&modlist,0,"pgpKeyExpireTime",NULL);
525   make_one_attr(&modlist,0,"pgpCertID",NULL);
526   /* Note the count of these deleted attributes.  They're to be used
527      later. */
528
529   /* Assemble the INFO stuff into LDAP attributes */
530
531   while(fgets(line,MAX_LINE,input)!=NULL)
532     if(sscanf(line,"INFO %16s BEGIN\n",keyid)==1)
533       {
534         begin=1;
535         break;
536       }
537
538   if(!begin)
539     {
540       /* i.e. eof before the INFO BEGIN was found.  This isn't an
541          error. */
542       *eof=1;
543       ret=KEYSERVER_OK;
544       goto fail;
545     }
546
547   if(strlen(keyid)!=16)
548     {
549       *eof=1;
550       ret=KEYSERVER_KEY_INCOMPLETE;
551       goto fail;
552     }
553
554   dn=malloc(strlen("pgpCertID=")+16+1+strlen(basekeyspacedn)+1);
555   if(dn==NULL)
556     {
557       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
558       ret=KEYSERVER_NO_MEMORY;
559       goto fail;
560     }
561
562   sprintf(dn,"pgpCertID=%s,%s",keyid,basekeyspacedn);
563
564   key=malloc(1);
565   if(!key)
566     {
567       fprintf(console,"gpgkeys: unable to allocate memory for key\n");
568       ret=KEYSERVER_NO_MEMORY;
569       goto fail;
570     }
571
572   key[0]='\0';
573
574   /* Now parse each line until we see the END */
575
576   while(fgets(line,MAX_LINE,input)!=NULL)
577     if(sscanf(line,"INFO %16s END\n",keyid)==1)
578       {
579         end=1;
580         break;
581       }
582     else
583       build_attrs(&modlist,line);
584
585   if(!end)
586     {
587       fprintf(console,"gpgkeys: no INFO %s END found\n",keyid);
588       *eof=1;
589       ret=KEYSERVER_KEY_INCOMPLETE;
590       goto fail;
591     }
592
593   begin=end=0;
594
595   /* Read and throw away stdin until we see the BEGIN */
596
597   while(fgets(line,MAX_LINE,input)!=NULL)
598     if(sscanf(line,"KEY %16s BEGIN\n",keyid)==1)
599       {
600         begin=1;
601         break;
602       }
603
604   if(!begin)
605     {
606       /* i.e. eof before the KEY BEGIN was found.  This isn't an
607          error. */
608       *eof=1;
609       ret=KEYSERVER_OK;
610       goto fail;
611     }
612
613   /* Now slurp up everything until we see the END */
614
615   while(fgets(line,MAX_LINE,input)!=NULL)
616     if(sscanf(line,"KEY %16s END\n",keyid)==1)
617       {
618         end=1;
619         break;
620       }
621     else
622       {
623         char *tempkey;
624         keysize+=strlen(line);
625         tempkey=realloc(key,keysize);
626         if(tempkey==NULL)
627           {
628             fprintf(console,"gpgkeys: unable to reallocate for key\n");
629             ret=KEYSERVER_NO_MEMORY;
630             goto fail;
631           }
632         else
633           key=tempkey;
634
635         strcat(key,line);
636       }
637
638   if(!end)
639     {
640       fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
641       *eof=1;
642       ret=KEYSERVER_KEY_INCOMPLETE;
643       goto fail;
644     }
645
646   make_one_attr(&modlist,0,"objectClass","pgpKeyInfo");
647   make_one_attr(&modlist,0,"pgpKey",key);
648
649   /* If it's not there, we just turn around and send an add command
650      for the same key.  Otherwise, the modify brings the server copy
651      into compliance with our copy.  Note that unlike the LDAP
652      keyserver (and really, any other keyserver) this does NOT merge
653      signatures, but replaces the whole key.  This should make some
654      people very happy. */
655
656   err=ldap_modify_s(ldap,dn,modlist);
657   if(err==LDAP_NO_SUCH_OBJECT)
658     {
659       /* This [11] is the deleted count from earlier */
660       LDAPMod **addlist=&modlist[11];
661       err=ldap_add_s(ldap,dn,addlist);
662     }
663
664   if(err!=LDAP_SUCCESS)
665     {
666       fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
667               keyid,ldap_err2string(err));
668       ret=ldap_err_to_gpg_err(err);
669       goto fail;
670     }
671
672   ret=KEYSERVER_OK;
673
674  fail:
675   /* Unwind and free the whole modlist structure */
676   for(ml=modlist;*ml;ml++)
677     {
678       free_mod_values(*ml);
679       free(*ml);
680     }
681
682   free(modlist);
683   free(dn);
684
685   if(ret!=0 && begin)
686     fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
687
688   return ret;
689 }
690
691 static int
692 send_key_keyserver(int *eof)
693 {
694   int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
695   char *dn=NULL,line[MAX_LINE],*key[2]={NULL,NULL};
696   char keyid[17];
697   LDAPMod mod, *attrs[2];
698
699   memset(&mod,0,sizeof(mod));
700   mod.mod_op=LDAP_MOD_ADD;
701   mod.mod_type=pgpkeystr;
702   mod.mod_values=key;
703   attrs[0]=&mod;
704   attrs[1]=NULL;
705
706   dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1);
707   if(dn==NULL)
708     {
709       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
710       ret=KEYSERVER_NO_MEMORY;
711       goto fail;
712     }
713
714   strcpy(dn,"pgpCertid=virtual,");
715   strcat(dn,basekeyspacedn);
716
717   key[0]=malloc(1);
718   if(key[0]==NULL)
719     {
720       fprintf(console,"gpgkeys: unable to allocate memory for key\n");
721       ret=KEYSERVER_NO_MEMORY;
722       goto fail;
723     }
724
725   key[0][0]='\0';
726
727   /* Read and throw away stdin until we see the BEGIN */
728
729   while(fgets(line,MAX_LINE,input)!=NULL)
730     if(sscanf(line,"KEY %16s BEGIN\n",keyid)==1)
731       {
732         begin=1;
733         break;
734       }
735
736   if(!begin)
737     {
738       /* i.e. eof before the KEY BEGIN was found.  This isn't an
739          error. */
740       *eof=1;
741       ret=KEYSERVER_OK;
742       goto fail;
743     }
744
745   /* Now slurp up everything until we see the END */
746
747   while(fgets(line,MAX_LINE,input)!=NULL)
748     if(sscanf(line,"KEY %16s END\n",keyid)==1)
749       {
750         end=1;
751         break;
752       }
753     else
754       {
755         keysize+=strlen(line);
756         key[0]=realloc(key[0],keysize);
757         if(key[0]==NULL)
758           {
759             fprintf(console,"gpgkeys: unable to reallocate for key\n");
760             ret=KEYSERVER_NO_MEMORY;
761             goto fail;
762           }
763
764         strcat(key[0],line);
765       }
766
767   if(!end)
768     {
769       fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
770       *eof=1;
771       ret=KEYSERVER_KEY_INCOMPLETE;
772       goto fail;
773     }
774
775   err=ldap_add_s(ldap,dn,attrs);
776   if(err!=LDAP_SUCCESS)
777     {
778       fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
779               keyid,ldap_err2string(err));
780       ret=ldap_err_to_gpg_err(err);
781       goto fail;
782     }
783
784   ret=KEYSERVER_OK;
785
786  fail:
787
788   free(key[0]);
789   free(dn);
790
791   if(ret!=0 && begin)
792     fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
793
794   /* Not a fatal error */
795   if(ret==KEYSERVER_KEY_EXISTS)
796     ret=KEYSERVER_OK;
797
798   return ret;
799 }
800
801 /* Note that key-not-found is not a fatal error */
802 static int
803 get_key(char *getkey)
804 {
805   LDAPMessage *res,*each;
806   int ret=KEYSERVER_INTERNAL_ERROR,err,count;
807   struct keylist *dupelist=NULL;
808   char search[62];
809   /* This ordering is significant - specifically, "pgpcertid" needs to
810      be the second item in the list, since everything after it may be
811      discarded if the user isn't in verbose mode. */
812   char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
813                  "pgpdisabled","pgpkeycreatetime","modifytimestamp",
814                  "pgpkeysize","pgpkeytype",NULL};
815   attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
816                          array initializers. */
817
818   /* Build the search string */
819
820   /* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3
821      or v4 short key id */
822
823   if(strncmp(getkey,"0x",2)==0)
824     getkey+=2;
825
826   if(strlen(getkey)==32)
827     {
828       fprintf(console,
829               "gpgkeys: LDAP keyservers do not support v3 fingerprints\n");
830       fprintf(output,"KEY 0x%s BEGIN\n",getkey);
831       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED);
832       return KEYSERVER_NOT_SUPPORTED;
833     }
834
835   if(strlen(getkey)>16)
836     {
837       char *offset=&getkey[strlen(getkey)-16];
838
839       /* fingerprint.  Take the last 16 characters and treat it like a
840          long key id */
841
842       if(include_subkeys)
843         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
844                 offset,offset);
845       else
846         sprintf(search,"(pgpcertid=%.16s)",offset);
847     }
848   else if(strlen(getkey)>8)
849     {
850       /* long key id */
851
852       if(include_subkeys)
853         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
854                 getkey,getkey);
855       else
856         sprintf(search,"(pgpcertid=%.16s)",getkey);
857     }
858   else
859     {
860       /* short key id */
861     
862       sprintf(search,"(pgpkeyid=%.8s)",getkey);
863     }
864
865   fprintf(output,"KEY 0x%s BEGIN\n",getkey);
866
867   if(verbose>2)
868     fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
869
870   if(!verbose)
871     attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
872
873   if(verbose)
874     fprintf(console,"gpgkeys: requesting key 0x%s from ldap://%s%s%s\n",
875             getkey,host,portstr[0]?":":"",portstr[0]?portstr:"");
876
877   err=ldap_search_s(ldap,basekeyspacedn,
878                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
879   if(err!=0)
880     {
881       int errtag=ldap_err_to_gpg_err(err);
882
883       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
884       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
885       return errtag;
886     }
887
888   count=ldap_count_entries(ldap,res);
889   if(count<1)
890     {
891       fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
892       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
893     }
894   else
895     {
896       /* There may be more than one unique result for a given keyID,
897          so we should fetch them all (test this by fetching short key
898          id 0xDEADBEEF). */
899
900       each=ldap_first_entry(ldap,res);
901       while(each!=NULL)
902         {
903           char **vals,**certid;
904
905           /* Use the long keyid to remove duplicates.  The LDAP server
906              returns the same keyid more than once if there are
907              multiple user IDs on the key.  Note that this does NOT
908              mean that a keyid that exists multiple times on the
909              keyserver will not be fetched.  It means that each KEY,
910              no matter how many user IDs share its keyid, will be
911              fetched only once.  If a keyid that belongs to more than
912              one key is fetched, the server quite properly responds
913              with all matching keys. -ds */
914
915           certid=ldap_get_values(ldap,each,"pgpcertid");
916           if(certid!=NULL)
917             {
918               if(!key_in_keylist(certid[0],dupelist))
919                 {
920                   /* it's not a duplicate, so add it */
921
922                   int rc=add_key_to_keylist(certid[0],&dupelist);
923                   if(rc)
924                     {
925                       ret=rc;
926                       goto fail;
927                     }
928
929                   if(verbose)
930                     {
931                       vals=ldap_get_values(ldap,each,"pgpuserid");
932                       if(vals!=NULL)
933                         {
934                           /* This is wrong, as the user ID is UTF8.  A
935                              better way to handle this would be to send it
936                              over to gpg and display it on that side of
937                              the pipe. */
938                           fprintf(console,"\nUser ID:\t%s\n",vals[0]);
939                           ldap_value_free(vals);
940                         }
941
942                       vals=ldap_get_values(ldap,each,"pgprevoked");
943                       if(vals!=NULL)
944                         {
945                           if(atoi(vals[0])==1)
946                             fprintf(console,"\t\t** KEY REVOKED **\n");
947                           ldap_value_free(vals);
948                         }
949
950                       vals=ldap_get_values(ldap,each,"pgpdisabled");
951                       if(vals!=NULL)
952                         {
953                           if(atoi(vals[0])==1)
954                             fprintf(console,"\t\t** KEY DISABLED **\n");
955                           ldap_value_free(vals);
956                         }
957
958                       vals=ldap_get_values(ldap,each,"pgpkeyid");
959                       if(vals!=NULL)
960                         {
961                           fprintf(console,"Short key ID:\t%s\n",vals[0]);
962                           ldap_value_free(vals);
963                         }
964
965                       fprintf(console,"Long key ID:\t%s\n",certid[0]);
966
967                       /* YYYYMMDDHHmmssZ */
968
969                       vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
970                       if(vals!=NULL)
971                         {
972                           if(strlen(vals[0])==15)
973                             fprintf(console,"Key created:\t%.2s/%.2s/%.4s\n",
974                                     &vals[0][4],&vals[0][6],vals[0]);
975                           ldap_value_free(vals);
976                         }
977
978                       vals=ldap_get_values(ldap,each,"modifytimestamp");
979                       if(vals!=NULL)
980                         {
981                           if(strlen(vals[0])==15)
982                             fprintf(console,"Key modified:\t%.2s/%.2s/%.4s\n",
983                                     &vals[0][4],&vals[0][6],vals[0]);
984                           ldap_value_free(vals);
985                         }
986
987                       vals=ldap_get_values(ldap,each,"pgpkeysize");
988                       if(vals!=NULL)
989                         {
990                           if(atoi(vals[0])>0)
991                             fprintf(console,"Key size:\t%d\n",atoi(vals[0]));
992                           ldap_value_free(vals);
993                         }
994
995                       vals=ldap_get_values(ldap,each,"pgpkeytype");
996                       if(vals!=NULL)
997                         {
998                           fprintf(console,"Key type:\t%s\n",vals[0]);
999                           ldap_value_free(vals);
1000                         }
1001                     }
1002
1003                   vals=ldap_get_values(ldap,each,pgpkeystr);
1004                   if(vals==NULL)
1005                     {
1006                       int errtag=ldap_to_gpg_err(ldap);
1007
1008                       fprintf(console,"gpgkeys: unable to retrieve key %s "
1009                               "from keyserver\n",getkey);
1010                       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
1011                     }
1012                   else
1013                     {
1014                       fprintf(output,"%sKEY 0x%s END\n",vals[0],getkey);
1015
1016                       ldap_value_free(vals);
1017                     }
1018                 }
1019
1020               ldap_value_free(certid);
1021             }
1022
1023           each=ldap_next_entry(ldap,each);
1024         }
1025     }
1026
1027   ret=KEYSERVER_OK;
1028
1029  fail:
1030   ldap_msgfree(res);
1031   free_keylist(dupelist);
1032
1033   return ret;
1034 }
1035
1036 static void
1037 printquoted(FILE *stream,char *string,char delim)
1038 {
1039   while(*string)
1040     {
1041       if(*string==delim || *string=='%')
1042         fprintf(stream,"%%%02x",*string);
1043       else
1044         fputc(*string,stream);
1045
1046       string++;
1047     }
1048 }
1049
1050 /* Returns 0 on success and -1 on error.  Note that key-not-found is
1051    not an error! */
1052 static int
1053 search_key(char *searchkey)
1054 {
1055   char **vals;
1056   LDAPMessage *res,*each;
1057   int err,count=0;
1058   struct keylist *dupelist=NULL;
1059   /* The maximum size of the search, including the optional stuff and
1060      the trailing \0 */
1061   char search[2+12+MAX_LINE+2+15+14+1+1];
1062   char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
1063                  "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
1064                  "pgpkeysize","pgpkeytype",NULL};
1065
1066   fprintf(output,"SEARCH %s BEGIN\n",searchkey);
1067
1068   /* Build the search string */
1069
1070   sprintf(search,"%s(pgpuserid=*%s*)%s%s%s",
1071           (!(include_disabled&&include_revoked))?"(&":"",
1072           searchkey,
1073           include_disabled?"":"(pgpdisabled=0)",
1074           include_revoked?"":"(pgprevoked=0)",
1075           !(include_disabled&&include_revoked)?")":"");
1076
1077   if(verbose>2)
1078     fprintf(console,"gpgkeys: LDAP search for: %s\n",search);
1079
1080   fprintf(console,("gpgkeys: searching for \"%s\" from LDAP server %s\n"),
1081           searchkey,host);
1082
1083   err=ldap_search_s(ldap,basekeyspacedn,
1084                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
1085   if(err!=LDAP_SUCCESS && err!=LDAP_SIZELIMIT_EXCEEDED)
1086     {
1087       int errtag=ldap_err_to_gpg_err(err);
1088
1089       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,errtag);
1090       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
1091       return errtag;
1092     }
1093
1094   /* The LDAP server doesn't return a real count of unique keys, so we
1095      can't use ldap_count_entries here. */
1096   each=ldap_first_entry(ldap,res);
1097   while(each!=NULL)
1098     {
1099       char **certid=ldap_get_values(ldap,each,"pgpcertid");
1100
1101       if(certid!=NULL)
1102         {
1103           if(!key_in_keylist(certid[0],dupelist))
1104             {
1105               int rc=add_key_to_keylist(certid[0],&dupelist);
1106               if(rc!=0)
1107                 {
1108                   fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
1109                   free_keylist(dupelist);
1110                   return rc;
1111                 }
1112
1113               count++;
1114             }
1115         }
1116
1117       each=ldap_next_entry(ldap,each);
1118     }
1119
1120   if(err==LDAP_SIZELIMIT_EXCEEDED)
1121     fprintf(console,"gpgkeys: search results exceeded server limit.  First %d results shown.\n",count);
1122
1123   free_keylist(dupelist);
1124   dupelist=NULL;
1125
1126   if(count<1)
1127     fprintf(output,"info:1:0\n");
1128   else
1129     {
1130       fprintf(output,"info:1:%d\n",count);
1131
1132       each=ldap_first_entry(ldap,res);
1133       while(each!=NULL)
1134         {
1135           char **certid;
1136
1137           certid=ldap_get_values(ldap,each,"pgpcertid");
1138           if(certid!=NULL)
1139             {
1140               LDAPMessage *uids;
1141
1142               /* Have we seen this certid before? */
1143               if(!key_in_keylist(certid[0],dupelist))
1144                 {
1145                   int rc=add_key_to_keylist(certid[0],&dupelist);
1146                   if(rc)
1147                     {
1148                       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
1149                       free_keylist(dupelist);
1150                       ldap_value_free(certid);
1151                       ldap_msgfree(res);
1152                       return rc;
1153                     }
1154
1155                   fprintf(output,"pub:%s:",certid[0]);
1156
1157                   vals=ldap_get_values(ldap,each,"pgpkeytype");
1158                   if(vals!=NULL)
1159                     {
1160                       /* The LDAP server doesn't exactly handle this
1161                          well. */
1162                       if(strcasecmp(vals[0],"RSA")==0)
1163                         fprintf(output,"1");
1164                       else if(strcasecmp(vals[0],"DSS/DH")==0)
1165                         fprintf(output,"17");
1166                       ldap_value_free(vals);
1167                     }
1168
1169                   fputc(':',output);
1170
1171                   vals=ldap_get_values(ldap,each,"pgpkeysize");
1172                   if(vals!=NULL)
1173                     {
1174                       /* Not sure why, but some keys are listed with a
1175                          key size of 0.  Treat that like an
1176                          unknown. */
1177                       if(atoi(vals[0])>0)
1178                         fprintf(output,"%d",atoi(vals[0]));
1179                       ldap_value_free(vals);
1180                     }
1181
1182                   fputc(':',output);
1183
1184                   /* YYYYMMDDHHmmssZ */
1185
1186                   vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
1187                   if(vals!=NULL && strlen(vals[0])==15)
1188                     {
1189                       fprintf(output,"%u",
1190                               (unsigned int)ldap2epochtime(vals[0]));
1191                       ldap_value_free(vals);
1192                     }
1193
1194                   fputc(':',output);
1195
1196                   vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
1197                   if(vals!=NULL && strlen(vals[0])==15)
1198                     {
1199                       fprintf(output,"%u",
1200                               (unsigned int)ldap2epochtime(vals[0]));
1201                       ldap_value_free(vals);
1202                     }
1203
1204                   fputc(':',output);
1205
1206                   vals=ldap_get_values(ldap,each,"pgprevoked");
1207                   if(vals!=NULL)
1208                     {
1209                       if(atoi(vals[0])==1)
1210                         fprintf(output,"r");
1211                       ldap_value_free(vals);
1212                     }
1213
1214                   vals=ldap_get_values(ldap,each,"pgpdisabled");
1215                   if(vals!=NULL)
1216                     {
1217                       if(atoi(vals[0])==1)
1218                         fprintf(output,"d");
1219                       ldap_value_free(vals);
1220                     }
1221
1222 #if 0
1223                   /* This is not yet specified in the keyserver
1224                      protocol, but may be someday. */
1225                   fputc(':',output);
1226
1227                   vals=ldap_get_values(ldap,each,"modifytimestamp");
1228                   if(vals!=NULL && strlen(vals[0])==15)
1229                     {
1230                       fprintf(output,"%u",
1231                               (unsigned int)ldap2epochtime(vals[0]));
1232                       ldap_value_free(vals);
1233                     }
1234 #endif
1235
1236                   fprintf(output,"\n");
1237
1238                   /* Now print all the uids that have this certid */
1239                   uids=ldap_first_entry(ldap,res);
1240                   while(uids!=NULL)
1241                     {
1242                       vals=ldap_get_values(ldap,uids,"pgpcertid");
1243                       if(vals!=NULL)
1244                         {
1245                           if(strcasecmp(certid[0],vals[0])==0)
1246                             {
1247                               char **uidvals;
1248
1249                               fprintf(output,"uid:");
1250
1251                               uidvals=ldap_get_values(ldap,uids,"pgpuserid");
1252                               if(uidvals!=NULL)
1253                                 {
1254                                   /* Need to escape any colons */
1255                                   printquoted(output,uidvals[0],':');
1256                                   ldap_value_free(uidvals);
1257                                 }
1258
1259                               fprintf(output,"\n");
1260                             }
1261
1262                           ldap_value_free(vals);
1263                         }
1264
1265                       uids=ldap_next_entry(ldap,uids);
1266                     }
1267                 }
1268
1269               ldap_value_free(certid);
1270             }
1271
1272           each=ldap_next_entry(ldap,each);
1273         }
1274     }
1275
1276   ldap_msgfree(res);
1277   free_keylist(dupelist);
1278
1279   fprintf(output,"SEARCH %s END\n",searchkey);
1280
1281   return KEYSERVER_OK;
1282 }
1283
1284 static void
1285 fail_all(struct keylist *keylist,int action,int err)
1286 {
1287   if(!keylist)
1288     return;
1289
1290   if(action==SEARCH)
1291     {
1292       fprintf(output,"SEARCH ");
1293       while(keylist)
1294         {
1295           fprintf(output,"%s ",keylist->str);
1296           keylist=keylist->next;
1297         }
1298       fprintf(output,"FAILED %d\n",err);
1299     }
1300   else
1301     while(keylist)
1302       {
1303         fprintf(output,"KEY %s FAILED %d\n",keylist->str,err);
1304         keylist=keylist->next;
1305       }
1306 }
1307
1308 static int
1309 find_basekeyspacedn(void)
1310 {
1311   int err,i;
1312   char *attr[]={"namingContexts",NULL,NULL,NULL};
1313   LDAPMessage *res;
1314   char **context;
1315
1316   /* Look for namingContexts */
1317   err=ldap_search_s(ldap,"",LDAP_SCOPE_BASE,"(objectClass=*)",attr,0,&res);
1318   if(err==LDAP_SUCCESS)
1319     {
1320       context=ldap_get_values(ldap,res,"namingContexts");
1321       if(context)
1322         {
1323           attr[0]="pgpBaseKeySpaceDN";
1324           attr[1]="pgpVersion";
1325           attr[2]="pgpSoftware";
1326
1327           real_ldap=1;
1328
1329           /* We found some, so try each namingContext as the search base
1330              and look for pgpBaseKeySpaceDN.  Because we found this, we
1331              know we're talking to a regular-ish LDAP server and not a
1332              LDAP keyserver. */
1333
1334           for(i=0;context[i] && !basekeyspacedn;i++)
1335             {
1336               char **vals;
1337               LDAPMessage *si_res;
1338               err=ldap_search_s(ldap,context[i],LDAP_SCOPE_ONELEVEL,
1339                                 "(cn=pgpServerInfo)",attr,0,&si_res);
1340               if(err!=LDAP_SUCCESS)
1341                 return err;
1342
1343               vals=ldap_get_values(ldap,si_res,"pgpBaseKeySpaceDN");
1344               if(vals)
1345                 {
1346                   /* This is always "OU=ACTIVE,O=PGP KEYSPACE,C=US", but
1347                      it might not be in the future. */
1348
1349                   basekeyspacedn=strdup(vals[0]);
1350                   ldap_value_free(vals);
1351                 }
1352
1353               if(verbose>1)
1354                 {
1355                   vals=ldap_get_values(ldap,si_res,"pgpSoftware");
1356                   if(vals)
1357                     {
1358                       fprintf(console,"Server: \t%s\n",vals[0]);
1359                       ldap_value_free(vals);
1360                     }
1361
1362                   vals=ldap_get_values(ldap,si_res,"pgpVersion");
1363                   if(vals)
1364                     {
1365                       fprintf(console,"Version:\t%s\n",vals[0]);
1366                       ldap_value_free(vals);
1367                     }
1368                 }
1369
1370               ldap_msgfree(si_res);
1371             }
1372
1373           ldap_value_free(context);
1374         }
1375
1376       ldap_msgfree(res);
1377     }
1378   else
1379     {
1380       /* We don't have an answer yet, which means the server might be
1381          a LDAP keyserver. */
1382       char **vals;
1383       LDAPMessage *si_res;
1384
1385       attr[0]="pgpBaseKeySpaceDN";
1386       attr[1]="version";
1387       attr[2]="software";
1388
1389       err=ldap_search_s(ldap,"cn=pgpServerInfo",LDAP_SCOPE_BASE,
1390                         "(objectClass=*)",attr,0,&si_res);
1391       if(err!=LDAP_SUCCESS)
1392         return err;
1393
1394       vals=ldap_get_values(ldap,si_res,"baseKeySpaceDN");
1395       if(vals)
1396         {
1397           basekeyspacedn=strdup(vals[0]);
1398           ldap_value_free(vals);
1399         }
1400
1401       if(verbose>1)
1402         {
1403           vals=ldap_get_values(ldap,si_res,"software");
1404           if(vals)
1405             {
1406               fprintf(console,"Server: \t%s\n",vals[0]);
1407               ldap_value_free(vals);
1408             }
1409         }
1410
1411       vals=ldap_get_values(ldap,si_res,"version");
1412       if(vals)
1413         {
1414           if(verbose>1)
1415             fprintf(console,"Version:\t%s\n",vals[0]);
1416
1417           /* If the version is high enough, use the new pgpKeyV2
1418              attribute.  This design if iffy at best, but it matches how
1419              PGP does it.  I figure the NAI folks assumed that there would
1420              never be a LDAP keyserver vendor with a different numbering
1421              scheme. */
1422           if(atoi(vals[0])>1)
1423             pgpkeystr="pgpKeyV2";
1424
1425           ldap_value_free(vals);
1426         }
1427
1428       ldap_msgfree(si_res);
1429     }   
1430
1431   return LDAP_SUCCESS;
1432 }
1433
1434 int
1435 main(int argc,char *argv[])
1436 {
1437   int port=0,arg,err,action=-1,ret=KEYSERVER_INTERNAL_ERROR;
1438   char line[MAX_LINE];
1439   int version,failed=0,use_ssl=0,use_tls=0;
1440   struct keylist *keylist=NULL,*keyptr=NULL;
1441
1442   console=stderr;
1443
1444   while((arg=getopt(argc,argv,"hVo:"))!=-1)
1445     switch(arg)
1446       {
1447       default:
1448       case 'h':
1449         fprintf(console,"-h\thelp\n");
1450         fprintf(console,"-V\tversion\n");
1451         fprintf(console,"-o\toutput to this file\n");
1452         return KEYSERVER_OK;
1453
1454       case 'V':
1455         fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
1456         return KEYSERVER_OK;
1457
1458       case 'o':
1459         output=fopen(optarg,"w");
1460         if(output==NULL)
1461           {
1462             fprintf(console,"gpgkeys: Cannot open output file \"%s\": %s\n",
1463                     optarg,strerror(errno));
1464             return KEYSERVER_INTERNAL_ERROR;
1465           }
1466
1467         break;
1468       }
1469
1470   if(argc>optind)
1471     {
1472       input=fopen(argv[optind],"r");
1473       if(input==NULL)
1474         {
1475           fprintf(console,"gpgkeys: Cannot open input file \"%s\": %s\n",
1476                   argv[optind],strerror(errno));
1477           return KEYSERVER_INTERNAL_ERROR;
1478         }
1479     }
1480
1481   if(input==NULL)
1482     input=stdin;
1483
1484   if(output==NULL)
1485     output=stdout;
1486
1487   /* Get the command and info block */
1488
1489   while(fgets(line,MAX_LINE,input)!=NULL)
1490     {
1491       char commandstr[7];
1492       char optionstr[30];
1493       char schemestr[80];
1494       char hash;
1495
1496       if(line[0]=='\n')
1497         break;
1498
1499       if(sscanf(line,"%c",&hash)==1 && hash=='#')
1500         continue;
1501
1502       if(sscanf(line,"COMMAND %6s\n",commandstr)==1)
1503         {
1504           commandstr[6]='\0';
1505
1506           if(strcasecmp(commandstr,"get")==0)
1507             action=GET;
1508           else if(strcasecmp(commandstr,"send")==0)
1509             action=SEND;
1510           else if(strcasecmp(commandstr,"search")==0)
1511             action=SEARCH;
1512
1513           continue;
1514         }
1515
1516       if(sscanf(line,"HOST %79s\n",host)==1)
1517         {
1518           host[79]='\0';
1519           continue;
1520         }
1521
1522       if(sscanf(line,"PORT %9s\n",portstr)==1)
1523         {
1524           portstr[9]='\0';
1525           port=atoi(portstr);
1526           continue;
1527         }
1528
1529       if(sscanf(line,"SCHEME %79s\n",schemestr)==1)
1530         {
1531           schemestr[79]='\0';
1532           if(strcasecmp(schemestr,"ldaps")==0)
1533             {
1534               port=636;
1535               use_ssl=1;
1536             }
1537           continue;
1538         }
1539
1540       if(sscanf(line,"VERSION %d\n",&version)==1)
1541         {
1542           if(version!=KEYSERVER_PROTO_VERSION)
1543             {
1544               ret=KEYSERVER_VERSION_ERROR;
1545               goto fail;
1546             }
1547
1548           continue;
1549         }
1550
1551       if(sscanf(line,"OPTION %29s\n",optionstr)==1)
1552         {
1553           int no=0;
1554           char *start=&optionstr[0];
1555
1556           optionstr[29]='\0';
1557
1558           if(strncasecmp(optionstr,"no-",3)==0)
1559             {
1560               no=1;
1561               start=&optionstr[3];
1562             }
1563
1564           if(strcasecmp(start,"verbose")==0)
1565             {
1566               if(no)
1567                 verbose--;
1568               else
1569                 verbose++;
1570             }
1571           else if(strcasecmp(start,"include-disabled")==0)
1572             {
1573               if(no)
1574                 include_disabled=0;
1575               else
1576                 include_disabled=1;
1577             }
1578           else if(strcasecmp(start,"include-revoked")==0)
1579             {
1580               if(no)
1581                 include_revoked=0;
1582               else
1583                 include_revoked=1;
1584             }
1585           else if(strcasecmp(start,"include-subkeys")==0)
1586             {
1587               if(no)
1588                 include_subkeys=0;
1589               else
1590                 include_subkeys=1;
1591             }
1592           else if(strncasecmp(start,"tls",3)==0)
1593             {
1594               if(no)
1595                 use_tls=0;
1596               else if(start[3]=='=')
1597                 {
1598                   if(strcasecmp(&start[4],"no")==0)
1599                     use_tls=0;
1600                   else if(strcasecmp(&start[4],"try")==0)
1601                     use_tls=1;
1602                   else if(strcasecmp(&start[4],"warn")==0)
1603                     use_tls=2;
1604                   else if(strcasecmp(&start[4],"require")==0)
1605                     use_tls=3;
1606                   else
1607                     use_tls=1;
1608                 }
1609               else if(start[3]=='\0')
1610                 use_tls=1;
1611             }
1612
1613           continue;
1614         }
1615     }
1616
1617   /* If it's a GET or a SEARCH, the next thing to come in is the
1618      keyids.  If it's a SEND, then there are no keyids. */
1619
1620   if(action==SEND)
1621     while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
1622   else if(action==GET || action==SEARCH)
1623     {
1624       for(;;)
1625         {
1626           struct keylist *work;
1627
1628           if(fgets(line,MAX_LINE,input)==NULL)
1629             break;
1630           else
1631             {
1632               if(line[0]=='\n' || line[0]=='\0')
1633                 break;
1634
1635               work=malloc(sizeof(struct keylist));
1636               if(work==NULL)
1637                 {
1638                   fprintf(console,"gpgkeys: out of memory while "
1639                           "building key list\n");
1640                   ret=KEYSERVER_NO_MEMORY;
1641                   goto fail;
1642                 }
1643
1644               strcpy(work->str,line);
1645
1646               /* Trim the trailing \n */
1647               work->str[strlen(line)-1]='\0';
1648
1649               work->next=NULL;
1650
1651               /* Always attach at the end to keep the list in proper
1652                  order for searching */
1653               if(keylist==NULL)
1654                 keylist=work;
1655               else
1656                 keyptr->next=work;
1657
1658               keyptr=work;
1659             }
1660         }
1661     }
1662   else
1663     {
1664       fprintf(console,"gpgkeys: no keyserver command specified\n");
1665       goto fail;
1666     }
1667
1668   /* Send the response */
1669
1670   fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
1671   fprintf(output,"PROGRAM %s\n\n",VERSION);
1672
1673   if(verbose>1)
1674     {
1675       fprintf(console,"Host:\t\t%s\n",host);
1676       if(port)
1677         fprintf(console,"Port:\t\t%d\n",port);
1678       fprintf(console,"Command:\t%s\n",action==GET?"GET":
1679               action==SEND?"SEND":"SEARCH");
1680     }
1681
1682   /* Note that this tries all A records on a given host (or at least,
1683      OpenLDAP does). */
1684   ldap=ldap_init(host,port);
1685   if(ldap==NULL)
1686     {
1687       fprintf(console,"gpgkeys: internal LDAP init error: %s\n",
1688               strerror(errno));
1689       fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1690       goto fail;
1691     }
1692
1693   if(use_ssl)
1694     {
1695       if(!real_ldap)
1696         {
1697           fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
1698                   "not supported by the NAI LDAP keyserver");
1699           fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1700           goto fail;
1701         }
1702       else
1703         {
1704 #if defined(LDAP_OPT_X_TLS_HARD) && defined(HAVE_LDAP_SET_OPTION)
1705           int ssl=LDAP_OPT_X_TLS_HARD;
1706           err=ldap_set_option(ldap,LDAP_OPT_X_TLS,&ssl);
1707           if(err!=LDAP_SUCCESS)
1708             {
1709               fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
1710                       ldap_err2string(err));
1711               fail_all(keylist,action,ldap_err_to_gpg_err(err));
1712               goto fail;
1713             }
1714 #else
1715           fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
1716                   "not built with LDAPS support");
1717           fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1718           goto fail;
1719 #endif
1720         }
1721     }
1722
1723   if((err=find_basekeyspacedn()))
1724     {
1725       fprintf(console,"gpgkeys: unable to retrieve LDAP base: %s\n",
1726               ldap_err2string(err));
1727       fail_all(keylist,action,ldap_err_to_gpg_err(err));
1728       goto fail;
1729     }
1730
1731   /* use_tls: 0=don't use, 1=try silently to use, 2=try loudly to use,
1732      3=force use. */
1733   if(use_tls)
1734     {
1735       if(!real_ldap)
1736         {
1737           if(use_tls>=2)
1738             fprintf(console,"gpgkeys: unable to start TLS: %s\n",
1739                     "not supported by the NAI LDAP keyserver");
1740           if(use_tls==3)
1741             {
1742               fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1743               goto fail;
1744             }
1745         }
1746       else
1747         {
1748 #if defined(HAVE_LDAP_START_TLS_S) && defined(HAVE_LDAP_SET_OPTION)
1749           int ver=LDAP_VERSION3;
1750
1751           err=LDAP_SUCCESS;
1752
1753           err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
1754           if(err==LDAP_SUCCESS)
1755             err=ldap_start_tls_s(ldap,NULL,NULL);
1756
1757           if(err!=LDAP_SUCCESS && use_tls>=2)
1758             {
1759               fprintf(console,"gpgkeys: unable to start TLS: %s\n",
1760                       ldap_err2string(err));
1761               /* Are we forcing it? */
1762               if(use_tls==3)
1763                 {
1764                   fail_all(keylist,action,ldap_err_to_gpg_err(err));
1765                   goto fail;
1766                 }
1767             }
1768           else if(verbose>1)
1769             fprintf(console,"gpgkeys: TLS started successfully.\n");
1770 #else
1771           if(use_tls>=2)
1772             fprintf(console,"gpgkeys: unable to start TLS: %s\n",
1773                     "not built with TLS support");
1774           if(use_tls==3)
1775             {
1776               fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1777               goto fail;
1778             }
1779 #endif
1780         }
1781     }
1782
1783   /* The LDAP keyserver doesn't require this, but it might be useful
1784      if someone stores keys on a V2 LDAP server somewhere.  (V3
1785      doesn't require a bind). */
1786
1787   err=ldap_simple_bind_s(ldap,NULL,NULL);
1788   if(err!=0)
1789     {
1790       fprintf(console,"gpgkeys: internal LDAP bind error: %s\n",
1791               ldap_err2string(err));
1792       fail_all(keylist,action,ldap_err_to_gpg_err(err));
1793       goto fail;
1794     }
1795
1796   switch(action)
1797     {
1798     case GET:
1799       keyptr=keylist;
1800
1801       while(keyptr!=NULL)
1802         {
1803           if(get_key(keyptr->str)!=KEYSERVER_OK)
1804             failed++;
1805
1806           keyptr=keyptr->next;
1807         }
1808       break;
1809
1810     case SEND:
1811       {
1812         int eof=0;
1813
1814         do
1815           {
1816             if(real_ldap)
1817               {
1818                 if(send_key(&eof)!=KEYSERVER_OK)
1819                   failed++;
1820               }
1821             else
1822               {
1823                 if(send_key_keyserver(&eof)!=KEYSERVER_OK)
1824                   failed++;
1825               }
1826           }
1827         while(!eof);
1828       }
1829       break;
1830
1831     case SEARCH:
1832       {
1833         char *searchkey=NULL;
1834         int len=0;
1835
1836         /* To search, we stick a * in between each key to search for.
1837            This means that if the user enters words, they'll get
1838            "enters*words".  If the user "enters words", they'll get
1839            "enters words" */
1840
1841         keyptr=keylist;
1842         while(keyptr!=NULL)
1843           {
1844             len+=strlen(keyptr->str)+1;
1845             keyptr=keyptr->next;
1846           }
1847
1848         searchkey=malloc(len+1);
1849         if(searchkey==NULL)
1850           {
1851             ret=KEYSERVER_NO_MEMORY;
1852             fail_all(keylist,action,KEYSERVER_NO_MEMORY);
1853             goto fail;
1854           }
1855
1856         searchkey[0]='\0';
1857
1858         keyptr=keylist;
1859         while(keyptr!=NULL)
1860           {
1861             strcat(searchkey,keyptr->str);
1862             strcat(searchkey,"*");
1863             keyptr=keyptr->next;
1864           }
1865
1866         /* Nail that last "*" */
1867         if(*searchkey)
1868           searchkey[strlen(searchkey)-1]='\0';
1869
1870         if(search_key(searchkey)!=KEYSERVER_OK)
1871           failed++;
1872
1873         free(searchkey);
1874       }
1875
1876       break;
1877     }
1878
1879   if(!failed)
1880     ret=KEYSERVER_OK;
1881
1882  fail:
1883
1884   while(keylist!=NULL)
1885     {
1886       struct keylist *current=keylist;
1887       keylist=keylist->next;
1888       free(current);
1889     }
1890
1891   if(input!=stdin)
1892     fclose(input);
1893
1894   if(output!=stdout)
1895     fclose(output);
1896
1897   if(ldap!=NULL)
1898     ldap_unbind_s(ldap);
1899
1900   free(basekeyspacedn);
1901
1902   return ret;
1903 }