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