* gpgkeys_ldap.c: Fix build warning with mozldap.
[gnupg.git] / keyserver / gpgkeys_ldap.c
1 /* gpgkeys_ldap.c - talk to a LDAP keyserver
2  * Copyright (C) 2001, 2002, 2004, 2005, 2006,
3  *               2007 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  *
22  * In addition, as a special exception, the Free Software Foundation
23  * gives permission to link the code of the keyserver helper tools:
24  * gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
25  * project's "OpenSSL" library (or with modified versions of it that
26  * use the same license as the "OpenSSL" library), and distribute the
27  * linked executables.  You must obey the GNU General Public License
28  * in all respects for all of the code used other than "OpenSSL".  If
29  * you modify this file, you may extend this exception to your version
30  * of the file, but you are not obligated to do so.  If you do not
31  * wish to do so, delete this exception statement from your version.
32  */
33
34 #include <config.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <time.h>
38 #include <unistd.h>
39 #ifdef HAVE_GETOPT_H
40 #include <getopt.h>
41 #endif
42 #include <stdlib.h>
43 #include <errno.h>
44 #include <assert.h>
45
46 #ifdef _WIN32
47 #include <winsock2.h>
48 #include <winldap.h>
49 #else
50 #ifdef NEED_LBER_H
51 #include <lber.h>
52 #endif
53 /* For OpenLDAP, to enable the API that we're using. */
54 #define LDAP_DEPRECATED 1
55 #include <ldap.h>
56 #endif
57
58 /* For mozldap */
59 #ifdef HAVE_LDAP_SSL_H
60 #include <ldap_ssl.h>
61 #endif
62
63 #include "compat.h"
64 #include "keyserver.h"
65 #include "ksutil.h"
66
67 #ifdef __riscos__
68 #include "util.h"
69 #endif
70
71 extern char *optarg;
72 extern int optind;
73
74 static int real_ldap=0;
75 static char *basekeyspacedn=NULL;
76 static char *pgpkeystr="pgpKey";
77 static FILE *input=NULL,*output=NULL,*console=NULL;
78 static LDAP *ldap=NULL;
79 static struct ks_options *opt;
80
81 #ifndef HAVE_TIMEGM
82 time_t timegm(struct tm *tm);
83 #endif
84
85 static int
86 ldap_err_to_gpg_err(int err)
87 {
88   int ret;
89
90   switch(err)
91     {
92     case LDAP_ALREADY_EXISTS:
93       ret=KEYSERVER_KEY_EXISTS;
94       break;
95
96     case LDAP_SERVER_DOWN:
97       ret=KEYSERVER_UNREACHABLE;
98       break;
99
100     default:
101       ret=KEYSERVER_GENERAL_ERROR;
102       break;
103     }
104
105   return ret;
106 }
107
108 static int
109 ldap_to_gpg_err(LDAP *ld)
110 {
111 #if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
112
113   int err;
114
115   if(ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&err)==0)
116     return ldap_err_to_gpg_err(err);
117   else
118     return KEYSERVER_GENERAL_ERROR;
119
120 #elif defined(HAVE_LDAP_LD_ERRNO)
121
122   return ldap_err_to_gpg_err(ld->ld_errno);
123
124 #else
125
126   /* We should never get here since the LDAP library should always
127      have either ldap_get_option or ld_errno, but just in case... */
128   return KEYSERVER_GENERAL_ERROR;
129
130 #endif
131 }
132
133 static int
134 key_in_keylist(const char *key,struct keylist *list)
135 {
136   struct keylist *keyptr=list;
137
138   while(keyptr!=NULL)
139     {
140       if(ascii_strcasecmp(key,keyptr->str)==0)
141         return 1;
142
143       keyptr=keyptr->next;
144     }
145
146   return 0;
147 }
148
149 static int
150 add_key_to_keylist(const char *key,struct keylist **list)
151 {
152   struct keylist *keyptr=malloc(sizeof(struct keylist));
153
154   if(keyptr==NULL)
155     {
156       fprintf(console,"gpgkeys: out of memory when deduping "
157               "key list\n");
158       return KEYSERVER_NO_MEMORY;
159     }
160
161   strncpy(keyptr->str,key,MAX_LINE);
162   keyptr->str[MAX_LINE-1]='\0';
163   keyptr->next=*list;
164   *list=keyptr;
165
166   return 0;
167 }
168
169 static void
170 free_keylist(struct keylist *list)
171 {
172   while(list!=NULL)
173     {
174       struct keylist *keyptr=list;
175
176       list=keyptr->next;
177       free(keyptr);
178     }
179 }
180
181 static time_t
182 ldap2epochtime(const char *timestr)
183 {
184   struct tm pgptime;
185   time_t answer;
186
187   memset(&pgptime,0,sizeof(pgptime));
188
189   /* YYYYMMDDHHmmssZ */
190
191   sscanf(timestr,"%4d%2d%2d%2d%2d%2d",
192          &pgptime.tm_year,
193          &pgptime.tm_mon,
194          &pgptime.tm_mday,
195          &pgptime.tm_hour,
196          &pgptime.tm_min,
197          &pgptime.tm_sec);
198
199   pgptime.tm_year-=1900;
200   pgptime.tm_isdst=-1;
201   pgptime.tm_mon--;
202
203   /* mktime() takes the timezone into account, so we use timegm() */
204
205   answer=timegm(&pgptime);
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 /* Append two onto the end of one.  Two is not freed, but its pointers
236    are now part of one.  Make sure you don't free them both! */
237 static int
238 join_two_modlists(LDAPMod ***one,LDAPMod **two)
239 {
240   int i,one_count=0,two_count=0;
241   LDAPMod **grow;
242
243   for(grow=*one;*grow;grow++)
244     one_count++;
245
246   for(grow=two;*grow;grow++)
247     two_count++;
248
249   grow=realloc(*one,sizeof(LDAPMod *)*(one_count+two_count+1));
250   if(!grow)
251     return 0;
252
253   for(i=0;i<two_count;i++)
254     grow[one_count+i]=two[i];
255
256   grow[one_count+i]=NULL;
257
258   *one=grow;
259
260   return 1;
261 }
262
263 /* Passing a NULL for value effectively deletes that attribute.  This
264    doesn't mean "delete" in the sense of removing something from the
265    modlist, but "delete" in the LDAP sense of adding a modlist item
266    that specifies LDAP_MOD_REPLACE and a null attribute for the given
267    attribute.  LDAP_MOD_DELETE doesn't work here as we don't know if
268    the attribute in question exists or not. */
269
270 static int
271 make_one_attr(LDAPMod ***modlist,char *attr,const char *value)
272 {
273   LDAPMod **m;
274   int nummods=0;
275
276   /* Search modlist for the attribute we're playing with. */
277   for(m=*modlist;*m;m++)
278     {
279       if(ascii_strcasecmp((*m)->mod_type,attr)==0)
280         {
281           char **ptr=(*m)->mod_values;
282           int numvalues=0;
283
284           /* We have this attribute already, so when the REPLACE
285              happens, the server attributes will be replaced
286              anyway. */
287           if(!value)
288             return 1;
289
290           if(ptr)
291             for(ptr=(*m)->mod_values;*ptr;ptr++)
292               {
293                 /* Duplicate value */
294                 if(strcmp(*ptr,value)==0)
295                   return 1;
296                 numvalues++;
297               }
298
299           ptr=realloc((*m)->mod_values,sizeof(char *)*(numvalues+2));
300           if(!ptr)
301             return 0;
302
303           (*m)->mod_values=ptr;
304           ptr[numvalues]=strdup(value);
305           if(!ptr[numvalues])
306             return 0;
307
308           ptr[numvalues+1]=NULL;
309           break;
310         }
311
312       nummods++;
313     }
314
315   /* We didn't find the attr, so make one and add it to the end */
316   if(!*m)
317     {
318       LDAPMod **grow;
319
320       grow=realloc(*modlist,sizeof(LDAPMod *)*(nummods+2));
321       if(!grow)
322         return 0;
323
324       *modlist=grow;
325       grow[nummods]=malloc(sizeof(LDAPMod));
326       if(!grow[nummods])
327         return 0;
328       grow[nummods]->mod_op=LDAP_MOD_REPLACE;
329       grow[nummods]->mod_type=attr;
330       if(value)
331         {
332           grow[nummods]->mod_values=malloc(sizeof(char *)*2);
333           if(!grow[nummods]->mod_values)
334             {
335               grow[nummods]=NULL;
336               return 0;
337             }
338
339           /* Is this the right thing?  Can a UTF8-encoded user ID have
340              embedded nulls? */
341           grow[nummods]->mod_values[0]=strdup(value);
342           if(!grow[nummods]->mod_values[0])
343             {
344               free(grow[nummods]->mod_values);
345               grow[nummods]=NULL;
346               return 0;
347             }
348
349           grow[nummods]->mod_values[1]=NULL;
350         }
351       else
352         grow[nummods]->mod_values=NULL;
353
354       grow[nummods+1]=NULL;
355     }
356
357   return 1;
358 }
359
360 static void
361 build_attrs(LDAPMod ***modlist,char *line)
362 {
363   char *record;
364   int i;
365
366   /* Remove trailing whitespace */
367   for(i=strlen(line);i>0;i--)
368     if(ascii_isspace(line[i-1]))
369       line[i-1]='\0';
370     else
371       break;
372
373   if((record=strsep(&line,":"))==NULL)
374     return;
375
376   if (strcmp("pub",record)==0)
377     {
378       char *tok;
379       int disabled=0,revoked=0;
380
381       /* The long keyid */
382       if((tok=strsep(&line,":"))==NULL)
383         return;
384
385       if(strlen(tok)==16)
386         {
387           make_one_attr(modlist,"pgpCertID",tok);
388           make_one_attr(modlist,"pgpKeyID",&tok[8]);
389         }
390       else
391         return;
392
393       /* The primary pubkey algo */
394       if((tok=strsep(&line,":"))==NULL)
395         return;
396
397       switch(atoi(tok))
398         {
399         case 1:
400           make_one_attr(modlist,"pgpKeyType","RSA");
401           break;
402
403         case 17:
404           make_one_attr(modlist,"pgpKeyType","DSS/DH");
405           break;
406         }
407
408       /* Size of primary key */
409       if((tok=strsep(&line,":"))==NULL)
410         return;
411
412       if(atoi(tok)>0)
413         {
414           char padded[6];
415           int val=atoi(tok);
416
417           /* We zero pad this on the left to make PGP happy. */
418
419           if(val<99999 && val>0)
420             {
421               sprintf(padded,"%05u",atoi(tok));
422               make_one_attr(modlist,"pgpKeySize",padded);
423             }
424         }
425
426       /* pk timestamp */
427       if((tok=strsep(&line,":"))==NULL)
428         return;
429
430       if(atoi(tok)>0)
431         {
432           char *stamp=epoch2ldaptime(atoi(tok));
433           if(stamp)
434             {
435               make_one_attr(modlist,"pgpKeyCreateTime",stamp);
436               free(stamp);
437             }
438         }
439
440       /* pk expire */
441       if((tok=strsep(&line,":"))==NULL)
442         return;
443
444       if(atoi(tok)>0)
445         {
446           char *stamp=epoch2ldaptime(atoi(tok));
447           if(stamp)
448             {
449               make_one_attr(modlist,"pgpKeyExpireTime",stamp);
450               free(stamp);
451             }
452         }
453
454       /* flags */
455       if((tok=strsep(&line,":"))==NULL)
456         return;
457
458       while(*tok)
459         switch(*tok++)
460           {
461           case 'r':
462           case 'R':
463             revoked=1;
464             break;
465             
466           case 'd':
467           case 'D':
468             disabled=1;
469             break;
470           }
471
472       /*
473         Note that we always create the pgpDisabled and pgpRevoked
474         attributes, regardless of whether the key is disabled/revoked
475         or not.  This is because a very common search is like
476         "(&(pgpUserID=*isabella*)(pgpDisabled=0))"
477       */
478
479       make_one_attr(modlist,"pgpDisabled",disabled?"1":"0");
480       make_one_attr(modlist,"pgpRevoked",revoked?"1":"0");
481     }
482   else if (strcmp("sub",record)==0)
483     {
484       char *tok;
485
486       /* The long keyid */
487       if((tok=strsep(&line,":"))==NULL)
488         return;
489
490       if(strlen(tok)==16)
491         make_one_attr(modlist,"pgpSubKeyID",tok);
492       else
493         return;
494
495       /* The subkey algo */
496       if((tok=strsep(&line,":"))==NULL)
497         return;
498
499       /* Size of subkey */
500       if((tok=strsep(&line,":"))==NULL)
501         return;
502
503       if(atoi(tok)>0)
504         {
505           char padded[6];
506           int val=atoi(tok);
507
508           /* We zero pad this on the left to make PGP happy. */
509
510           if(val<99999 && val>0)
511             {
512               sprintf(padded,"%05u",atoi(tok));
513               make_one_attr(modlist,"pgpKeySize",padded);
514             }
515         }
516
517       /* Ignore the rest of the items for subkeys since the LDAP
518          schema doesn't store them. */
519     }
520   else if (strcmp("uid",record)==0)
521     {
522       char *userid,*tok;
523
524       /* The user ID string */
525       if((tok=strsep(&line,":"))==NULL)
526         return;
527
528       if(strlen(tok)==0)
529         return;
530
531       userid=tok;
532
533       /* By definition, de-%-encoding is always smaller than the
534          original string so we can decode in place. */
535
536       i=0;
537
538       while(*tok)
539         if(tok[0]=='%' && tok[1] && tok[2])
540           {
541             if((userid[i]=hextobyte(&tok[1]))==-1)
542               userid[i]='?';
543
544             i++;
545             tok+=3;
546           }
547         else
548           userid[i++]=*tok++;
549
550       userid[i]='\0';
551
552       /* We don't care about the other info provided in the uid: line
553          since the LDAP schema doesn't need it. */
554
555       make_one_attr(modlist,"pgpUserID",userid);
556     }
557   else if(strcmp("sig",record)==0)
558     {
559       char *tok;
560
561       if((tok=strsep(&line,":"))==NULL)
562         return;
563
564       if(strlen(tok)==16)
565         make_one_attr(modlist,"pgpSignerID",tok);
566     }
567 }
568
569 static void
570 free_mod_values(LDAPMod *mod)
571 {
572   char **ptr;
573
574   if(!mod->mod_values)
575     return;
576
577   for(ptr=mod->mod_values;*ptr;ptr++)
578     free(*ptr);
579
580   free(mod->mod_values);
581 }
582
583 static int
584 send_key(int *eof)
585 {
586   int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
587   char *dn=NULL,line[MAX_LINE],*key=NULL;
588   char keyid[17],state[6];
589   LDAPMod **modlist,**addlist,**ml;
590
591   modlist=malloc(sizeof(LDAPMod *));
592   if(!modlist)
593     {
594       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
595       ret=KEYSERVER_NO_MEMORY;
596       goto fail;
597     }
598
599   *modlist=NULL;
600
601   addlist=malloc(sizeof(LDAPMod *));
602   if(!addlist)
603     {
604       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
605       ret=KEYSERVER_NO_MEMORY;
606       goto fail;
607     }
608
609   *addlist=NULL;
610
611   /* Start by nulling out all attributes.  We try and do a modify
612      operation first, so this ensures that we don't leave old
613      attributes lying around. */
614   make_one_attr(&modlist,"pgpDisabled",NULL);
615   make_one_attr(&modlist,"pgpKeyID",NULL);
616   make_one_attr(&modlist,"pgpKeyType",NULL);
617   make_one_attr(&modlist,"pgpUserID",NULL);
618   make_one_attr(&modlist,"pgpKeyCreateTime",NULL);
619   make_one_attr(&modlist,"pgpSignerID",NULL);
620   make_one_attr(&modlist,"pgpRevoked",NULL);
621   make_one_attr(&modlist,"pgpSubKeyID",NULL);
622   make_one_attr(&modlist,"pgpKeySize",NULL);
623   make_one_attr(&modlist,"pgpKeyExpireTime",NULL);
624   make_one_attr(&modlist,"pgpCertID",NULL);
625
626   /* Assemble the INFO stuff into LDAP attributes */
627
628   while(fgets(line,MAX_LINE,input)!=NULL)
629     if(sscanf(line,"INFO%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
630        && strcmp(state,"BEGIN")==0)
631       {
632         begin=1;
633         break;
634       }
635
636   if(!begin)
637     {
638       /* i.e. eof before the INFO BEGIN was found.  This isn't an
639          error. */
640       *eof=1;
641       ret=KEYSERVER_OK;
642       goto fail;
643     }
644
645   if(strlen(keyid)!=16)
646     {
647       *eof=1;
648       ret=KEYSERVER_KEY_INCOMPLETE;
649       goto fail;
650     }
651
652   dn=malloc(strlen("pgpCertID=")+16+1+strlen(basekeyspacedn)+1);
653   if(dn==NULL)
654     {
655       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
656       ret=KEYSERVER_NO_MEMORY;
657       goto fail;
658     }
659
660   sprintf(dn,"pgpCertID=%s,%s",keyid,basekeyspacedn);
661
662   key=malloc(1);
663   if(!key)
664     {
665       fprintf(console,"gpgkeys: unable to allocate memory for key\n");
666       ret=KEYSERVER_NO_MEMORY;
667       goto fail;
668     }
669
670   key[0]='\0';
671
672   /* Now parse each line until we see the END */
673
674   while(fgets(line,MAX_LINE,input)!=NULL)
675     if(sscanf(line,"INFO%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
676        && strcmp(state,"END")==0)
677       {
678         end=1;
679         break;
680       }
681     else
682       build_attrs(&addlist,line);
683
684   if(!end)
685     {
686       fprintf(console,"gpgkeys: no INFO %s END found\n",keyid);
687       *eof=1;
688       ret=KEYSERVER_KEY_INCOMPLETE;
689       goto fail;
690     }
691
692   begin=end=0;
693
694   /* Read and throw away stdin until we see the BEGIN */
695
696   while(fgets(line,MAX_LINE,input)!=NULL)
697     if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
698        && strcmp(state,"BEGIN")==0)
699       {
700         begin=1;
701         break;
702       }
703
704   if(!begin)
705     {
706       /* i.e. eof before the KEY BEGIN was found.  This isn't an
707          error. */
708       *eof=1;
709       ret=KEYSERVER_OK;
710       goto fail;
711     }
712
713   /* Now slurp up everything until we see the END */
714
715   while(fgets(line,MAX_LINE,input)!=NULL)
716     if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
717        && strcmp(state,"END")==0)
718       {
719         end=1;
720         break;
721       }
722     else
723       {
724         char *tempkey;
725         keysize+=strlen(line);
726         tempkey=realloc(key,keysize);
727         if(tempkey==NULL)
728           {
729             fprintf(console,"gpgkeys: unable to reallocate for key\n");
730             ret=KEYSERVER_NO_MEMORY;
731             goto fail;
732           }
733         else
734           key=tempkey;
735
736         strcat(key,line);
737       }
738
739   if(!end)
740     {
741       fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
742       *eof=1;
743       ret=KEYSERVER_KEY_INCOMPLETE;
744       goto fail;
745     }
746
747   make_one_attr(&addlist,"objectClass","pgpKeyInfo");
748   make_one_attr(&addlist,"pgpKey",key);
749
750   /* Now append addlist onto modlist */
751   if(!join_two_modlists(&modlist,addlist))
752     {
753       fprintf(console,"gpgkeys: unable to merge LDAP modification lists\n");
754       ret=KEYSERVER_NO_MEMORY;
755       goto fail;
756     }
757
758   /* Going on the assumption that modify operations are more frequent
759      than adds, we try a modify first.  If it's not there, we just
760      turn around and send an add command for the same key.  Otherwise,
761      the modify brings the server copy into compliance with our copy.
762      Note that unlike the LDAP keyserver (and really, any other
763      keyserver) this does NOT merge signatures, but replaces the whole
764      key.  This should make some people very happy. */
765
766   err=ldap_modify_s(ldap,dn,modlist);
767   if(err==LDAP_NO_SUCH_OBJECT)
768     err=ldap_add_s(ldap,dn,addlist);
769
770   if(err!=LDAP_SUCCESS)
771     {
772       fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
773               keyid,ldap_err2string(err));
774       ret=ldap_err_to_gpg_err(err);
775       goto fail;
776     }
777
778   ret=KEYSERVER_OK;
779
780  fail:
781   /* Unwind and free the whole modlist structure */
782   for(ml=modlist;*ml;ml++)
783     {
784       free_mod_values(*ml);
785       free(*ml);
786     }
787
788   free(modlist);
789   free(addlist);
790   free(dn);
791   free(key);
792
793   if(ret!=0 && begin)
794     fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
795
796   return ret;
797 }
798
799 static int
800 send_key_keyserver(int *eof)
801 {
802   int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
803   char *dn=NULL,line[MAX_LINE],*key[2]={NULL,NULL};
804   char keyid[17],state[6];
805   LDAPMod mod, *attrs[2];
806
807   memset(&mod,0,sizeof(mod));
808   mod.mod_op=LDAP_MOD_ADD;
809   mod.mod_type=pgpkeystr;
810   mod.mod_values=key;
811   attrs[0]=&mod;
812   attrs[1]=NULL;
813
814   dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1);
815   if(dn==NULL)
816     {
817       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
818       ret=KEYSERVER_NO_MEMORY;
819       goto fail;
820     }
821
822   strcpy(dn,"pgpCertid=virtual,");
823   strcat(dn,basekeyspacedn);
824
825   key[0]=malloc(1);
826   if(key[0]==NULL)
827     {
828       fprintf(console,"gpgkeys: unable to allocate memory for key\n");
829       ret=KEYSERVER_NO_MEMORY;
830       goto fail;
831     }
832
833   key[0][0]='\0';
834
835   /* Read and throw away stdin until we see the BEGIN */
836
837   while(fgets(line,MAX_LINE,input)!=NULL)
838     if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
839        && strcmp(state,"BEGIN")==0)
840       {
841         begin=1;
842         break;
843       }
844
845   if(!begin)
846     {
847       /* i.e. eof before the KEY BEGIN was found.  This isn't an
848          error. */
849       *eof=1;
850       ret=KEYSERVER_OK;
851       goto fail;
852     }
853
854   /* Now slurp up everything until we see the END */
855
856   while(fgets(line,MAX_LINE,input)!=NULL)
857     if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
858        && strcmp(state,"END")==0)
859       {
860         end=1;
861         break;
862       }
863     else
864       {
865         keysize+=strlen(line);
866         key[0]=realloc(key[0],keysize);
867         if(key[0]==NULL)
868           {
869             fprintf(console,"gpgkeys: unable to reallocate for key\n");
870             ret=KEYSERVER_NO_MEMORY;
871             goto fail;
872           }
873
874         strcat(key[0],line);
875       }
876
877   if(!end)
878     {
879       fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
880       *eof=1;
881       ret=KEYSERVER_KEY_INCOMPLETE;
882       goto fail;
883     }
884
885   err=ldap_add_s(ldap,dn,attrs);
886   if(err!=LDAP_SUCCESS)
887     {
888       fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
889               keyid,ldap_err2string(err));
890       ret=ldap_err_to_gpg_err(err);
891       goto fail;
892     }
893
894   ret=KEYSERVER_OK;
895
896  fail:
897
898   free(key[0]);
899   free(dn);
900
901   if(ret!=0 && begin)
902     fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
903
904   /* Not a fatal error */
905   if(ret==KEYSERVER_KEY_EXISTS)
906     ret=KEYSERVER_OK;
907
908   return ret;
909 }
910
911 static void
912 build_info(const char *certid,LDAPMessage *each)
913 {
914   char **vals;
915
916   fprintf(output,"INFO %s BEGIN\n",certid);
917
918   fprintf(output,"pub:%s:",certid);
919
920   vals=ldap_get_values(ldap,each,"pgpkeytype");
921   if(vals!=NULL)
922     {
923       if(strcmp(vals[0],"RSA")==0)
924         fprintf(output,"1");
925       else if(strcmp(vals[0],"DSS/DH")==0)
926         fprintf(output,"17");
927       ldap_value_free(vals);
928     }
929
930   fprintf(output,":");
931
932   vals=ldap_get_values(ldap,each,"pgpkeysize");
933   if(vals!=NULL)
934     {
935       if(atoi(vals[0])>0)
936         fprintf(output,"%d",atoi(vals[0]));
937       ldap_value_free(vals);
938     }
939
940   fprintf(output,":");
941
942   vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
943   if(vals!=NULL)
944     {
945       if(strlen(vals[0])==15)
946         fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
947       ldap_value_free(vals);
948     }
949
950   fprintf(output,":");
951
952   vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
953   if(vals!=NULL)
954     {
955       if(strlen(vals[0])==15)
956         fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
957       ldap_value_free(vals);
958     }
959
960   fprintf(output,":");
961
962   vals=ldap_get_values(ldap,each,"pgprevoked");
963   if(vals!=NULL)
964     {
965       if(atoi(vals[0])==1)
966         fprintf(output,"r");
967       ldap_value_free(vals);
968     }
969
970   fprintf(output,"\n");
971
972   vals=ldap_get_values(ldap,each,"pgpuserid");
973   if(vals!=NULL)
974     {
975       int i;
976
977       for(i=0;vals[i];i++)
978         fprintf(output,"uid:%s\n",vals[i]);
979       ldap_value_free(vals);
980     }
981
982   fprintf(output,"INFO %s END\n",certid);
983 }
984
985 /* Note that key-not-found is not a fatal error */
986 static int
987 get_key(char *getkey)
988 {
989   LDAPMessage *res,*each;
990   int ret=KEYSERVER_INTERNAL_ERROR,err,count;
991   struct keylist *dupelist=NULL;
992   char search[62];
993   /* This ordering is significant - specifically, "pgpcertid" needs to
994      be the second item in the list, since everything after it may be
995      discarded if the user isn't in verbose mode. */
996   char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
997                  "pgpdisabled","pgpkeycreatetime","modifytimestamp",
998                  "pgpkeysize","pgpkeytype",NULL};
999   attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
1000                          array initializers. */
1001
1002   /* Build the search string */
1003
1004   /* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3
1005      or v4 short key id */
1006
1007   if(strncmp(getkey,"0x",2)==0)
1008     getkey+=2;
1009
1010   if(strlen(getkey)==32)
1011     {
1012       fprintf(console,
1013               "gpgkeys: LDAP keyservers do not support v3 fingerprints\n");
1014       fprintf(output,"KEY 0x%s BEGIN\n",getkey);
1015       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED);
1016       return KEYSERVER_NOT_SUPPORTED;
1017     }
1018
1019   if(strlen(getkey)>16)
1020     {
1021       char *offset=&getkey[strlen(getkey)-16];
1022
1023       /* fingerprint.  Take the last 16 characters and treat it like a
1024          long key id */
1025
1026       if(opt->flags.include_subkeys)
1027         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
1028                 offset,offset);
1029       else
1030         sprintf(search,"(pgpcertid=%.16s)",offset);
1031     }
1032   else if(strlen(getkey)>8)
1033     {
1034       /* long key id */
1035
1036       if(opt->flags.include_subkeys)
1037         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
1038                 getkey,getkey);
1039       else
1040         sprintf(search,"(pgpcertid=%.16s)",getkey);
1041     }
1042   else
1043     {
1044       /* short key id */
1045     
1046       sprintf(search,"(pgpkeyid=%.8s)",getkey);
1047     }
1048
1049   if(opt->verbose>2)
1050     fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
1051
1052   if(!opt->verbose)
1053     attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
1054
1055   err=ldap_search_s(ldap,basekeyspacedn,
1056                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
1057   if(err!=0)
1058     {
1059       int errtag=ldap_err_to_gpg_err(err);
1060
1061       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
1062       fprintf(output,"KEY 0x%s BEGIN\n",getkey);
1063       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
1064       return errtag;
1065     }
1066
1067   count=ldap_count_entries(ldap,res);
1068   if(count<1)
1069     {
1070       fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
1071       fprintf(output,"KEY 0x%s BEGIN\n",getkey);
1072       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
1073     }
1074   else
1075     {
1076       /* There may be more than one unique result for a given keyID,
1077          so we should fetch them all (test this by fetching short key
1078          id 0xDEADBEEF). */
1079
1080       each=ldap_first_entry(ldap,res);
1081       while(each!=NULL)
1082         {
1083           char **vals,**certid;
1084
1085           /* Use the long keyid to remove duplicates.  The LDAP server
1086              returns the same keyid more than once if there are
1087              multiple user IDs on the key.  Note that this does NOT
1088              mean that a keyid that exists multiple times on the
1089              keyserver will not be fetched.  It means that each KEY,
1090              no matter how many user IDs share its keyid, will be
1091              fetched only once.  If a keyid that belongs to more than
1092              one key is fetched, the server quite properly responds
1093              with all matching keys. -ds */
1094
1095           certid=ldap_get_values(ldap,each,"pgpcertid");
1096           if(certid!=NULL)
1097             {
1098               if(!key_in_keylist(certid[0],dupelist))
1099                 {
1100                   /* it's not a duplicate, so add it */
1101
1102                   int rc=add_key_to_keylist(certid[0],&dupelist);
1103                   if(rc)
1104                     {
1105                       ret=rc;
1106                       goto fail;
1107                     }
1108
1109                   build_info(certid[0],each);
1110
1111                   fprintf(output,"KEY 0x%s BEGIN\n",getkey);
1112
1113                   vals=ldap_get_values(ldap,each,pgpkeystr);
1114                   if(vals==NULL)
1115                     {
1116                       int errtag=ldap_to_gpg_err(ldap);
1117
1118                       fprintf(console,"gpgkeys: unable to retrieve key %s "
1119                               "from keyserver\n",getkey);
1120                       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
1121                     }
1122                   else
1123                     {
1124                       print_nocr(output,vals[0]);
1125                       fprintf(output,"\nKEY 0x%s END\n",getkey);
1126
1127                       ldap_value_free(vals);
1128                     }
1129                 }
1130
1131               ldap_value_free(certid);
1132             }
1133
1134           each=ldap_next_entry(ldap,each);
1135         }
1136     }
1137
1138   ret=KEYSERVER_OK;
1139
1140  fail:
1141   ldap_msgfree(res);
1142   free_keylist(dupelist);
1143
1144   return ret;
1145 }
1146
1147 #define LDAP_ESCAPE_CHARS "*()\\"
1148
1149 /* Append string to buffer in a LDAP-quoted way */
1150 static void
1151 ldap_quote(char *buffer,const char *string)
1152 {
1153   /* Find the end of buffer */
1154   buffer+=strlen(buffer);
1155
1156   for(;*string;string++)
1157     {
1158       if(strchr(LDAP_ESCAPE_CHARS,*string))
1159         {
1160           sprintf(buffer,"\\%02X",*string);
1161           buffer+=3;
1162         }
1163       else
1164         *buffer++=*string;
1165     }
1166
1167   *buffer='\0';
1168 }
1169
1170 /* Note that key-not-found is not a fatal error */
1171 static int
1172 get_name(char *getkey)
1173 {
1174   LDAPMessage *res,*each;
1175   int ret=KEYSERVER_INTERNAL_ERROR,err,count;
1176   /* The maximum size of the search, including the optional stuff and
1177      the trailing \0 */
1178   char search[2+12+(MAX_LINE*3)+2+15+14+1+1+20];
1179   /* This ordering is significant - specifically, "pgpcertid" needs to
1180      be the second item in the list, since everything after it may be
1181      discarded if the user isn't in verbose mode. */
1182   char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
1183                  "pgpdisabled","pgpkeycreatetime","modifytimestamp",
1184                  "pgpkeysize","pgpkeytype",NULL};
1185   attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
1186                          array initializers. */
1187
1188   /* Build the search string */
1189
1190   search[0]='\0';
1191
1192   if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1193     strcat(search,"(&");
1194
1195   strcat(search,"(pgpUserID=*");
1196   ldap_quote(search,getkey);
1197   strcat(search,"*)");
1198
1199   if(!opt->flags.include_disabled)
1200     strcat(search,"(pgpDisabled=0)");
1201
1202   if(!opt->flags.include_revoked)
1203     strcat(search,"(pgpRevoked=0)");
1204
1205   if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1206     strcat(search,")");
1207
1208   if(opt->verbose>2)
1209     fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
1210
1211   if(!opt->verbose)
1212     attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
1213
1214   err=ldap_search_s(ldap,basekeyspacedn,
1215                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
1216   if(err!=0)
1217     {
1218       int errtag=ldap_err_to_gpg_err(err);
1219
1220       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
1221       fprintf(output,"NAME %s BEGIN\n",getkey);
1222       fprintf(output,"NAME %s FAILED %d\n",getkey,errtag);
1223       return errtag;
1224     }
1225
1226   count=ldap_count_entries(ldap,res);
1227   if(count<1)
1228     {
1229       fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
1230       fprintf(output,"NAME %s BEGIN\n",getkey);
1231       fprintf(output,"NAME %s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
1232     }
1233   else
1234     {
1235       /* There may be more than one result, but we return them all. */
1236
1237       each=ldap_first_entry(ldap,res);
1238       while(each!=NULL)
1239         {
1240           char **vals,**certid;
1241
1242           certid=ldap_get_values(ldap,each,"pgpcertid");
1243           if(certid!=NULL)
1244             {
1245               build_info(certid[0],each);
1246
1247               fprintf(output,"NAME %s BEGIN\n",getkey);
1248
1249               vals=ldap_get_values(ldap,each,pgpkeystr);
1250               if(vals==NULL)
1251                 {
1252                   int errtag=ldap_to_gpg_err(ldap);
1253
1254                   fprintf(console,"gpgkeys: unable to retrieve key %s "
1255                           "from keyserver\n",getkey);
1256                   fprintf(output,"NAME %s FAILED %d\n",getkey,errtag);
1257                 }
1258               else
1259                 {
1260                   print_nocr(output,vals[0]);
1261                   fprintf(output,"\nNAME %s END\n",getkey);
1262
1263                   ldap_value_free(vals);
1264                 }
1265
1266               ldap_value_free(certid);
1267             }
1268
1269           each=ldap_next_entry(ldap,each);
1270         }
1271     }
1272
1273   ret=KEYSERVER_OK;
1274
1275   ldap_msgfree(res);
1276
1277   return ret;
1278 }
1279
1280 static void
1281 printquoted(FILE *stream,char *string,char delim)
1282 {
1283   while(*string)
1284     {
1285       if(*string==delim || *string=='%')
1286         fprintf(stream,"%%%02x",(unsigned char)*string);
1287       else
1288         fputc(*string,stream);
1289
1290       string++;
1291     }
1292 }
1293
1294 /* Returns 0 on success and -1 on error.  Note that key-not-found is
1295    not an error! */
1296 static int
1297 search_key(const char *searchkey)
1298 {
1299   char **vals,*search;
1300   LDAPMessage *res,*each;
1301   int err,count=0;
1302   struct keylist *dupelist=NULL;
1303   /* The maximum size of the search, including the optional stuff and
1304      the trailing \0 */
1305   char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
1306                  "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
1307                  "pgpkeysize","pgpkeytype",NULL};
1308   enum ks_search_type search_type;
1309
1310   search=malloc(2+1+9+1+3+strlen(searchkey)+3+1+15+14+1+1+20);
1311   if(!search)
1312     {
1313       fprintf(console,"gpgkeys: out of memory when building search list\n");
1314       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,KEYSERVER_NO_MEMORY);
1315       return KEYSERVER_NO_MEMORY;
1316     }
1317
1318   fprintf(output,"SEARCH %s BEGIN\n",searchkey);
1319
1320   search_type=classify_ks_search(&searchkey);
1321
1322   if(opt->debug)
1323     fprintf(console,"search type is %d, and key is \"%s\"\n",
1324             search_type,searchkey);
1325
1326   /* Build the search string */
1327
1328   search[0]='\0';
1329
1330   if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1331     strcat(search,"(&");
1332
1333   strcat(search,"(");
1334
1335   switch(search_type)
1336     {
1337     case KS_SEARCH_KEYID_SHORT:
1338       strcat(search,"pgpKeyID");
1339       break;
1340
1341     case KS_SEARCH_KEYID_LONG:
1342       strcat(search,"pgpCertID");
1343       break;
1344
1345     default:
1346       strcat(search,"pgpUserID");
1347       break;
1348     }
1349
1350   strcat(search,"=");
1351
1352   switch(search_type)
1353     {
1354     case KS_SEARCH_SUBSTR:
1355       strcat(search,"*");
1356       break;
1357
1358     case KS_SEARCH_MAIL:
1359       strcat(search,"*<");
1360       break;
1361
1362     case KS_SEARCH_MAILSUB:
1363       strcat(search,"*<*");
1364       break;
1365
1366     case KS_SEARCH_EXACT:
1367     case KS_SEARCH_KEYID_LONG:
1368     case KS_SEARCH_KEYID_SHORT:
1369       break;
1370     }
1371
1372   strcat(search,searchkey);
1373
1374   switch(search_type)
1375     {
1376     case KS_SEARCH_SUBSTR:
1377       strcat(search,"*");
1378       break;
1379
1380     case KS_SEARCH_MAIL:
1381       strcat(search,">*");
1382       break;
1383
1384     case KS_SEARCH_MAILSUB:
1385       strcat(search,"*>*");
1386       break;
1387
1388     case KS_SEARCH_EXACT:
1389     case KS_SEARCH_KEYID_LONG:
1390     case KS_SEARCH_KEYID_SHORT:
1391       break;
1392     }
1393
1394   strcat(search,")");
1395
1396   if(!opt->flags.include_disabled)
1397     strcat(search,"(pgpDisabled=0)");
1398
1399   if(!opt->flags.include_revoked)
1400     strcat(search,"(pgpRevoked=0)");
1401
1402   if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1403     strcat(search,")");
1404
1405   if(opt->verbose>2)
1406     fprintf(console,"gpgkeys: LDAP search for: %s\n",search);
1407
1408   err=ldap_search_s(ldap,basekeyspacedn,
1409                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
1410   free(search);
1411   if(err!=LDAP_SUCCESS && err!=LDAP_SIZELIMIT_EXCEEDED)
1412     {
1413       int errtag=ldap_err_to_gpg_err(err);
1414
1415       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,errtag);
1416       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
1417       return errtag;
1418     }
1419
1420   /* The LDAP server doesn't return a real count of unique keys, so we
1421      can't use ldap_count_entries here. */
1422   each=ldap_first_entry(ldap,res);
1423   while(each!=NULL)
1424     {
1425       char **certid=ldap_get_values(ldap,each,"pgpcertid");
1426
1427       if(certid!=NULL)
1428         {
1429           if(!key_in_keylist(certid[0],dupelist))
1430             {
1431               int rc=add_key_to_keylist(certid[0],&dupelist);
1432               if(rc!=0)
1433                 {
1434                   fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
1435                   free_keylist(dupelist);
1436                   return rc;
1437                 }
1438
1439               count++;
1440             }
1441         }
1442
1443       each=ldap_next_entry(ldap,each);
1444     }
1445
1446   if(err==LDAP_SIZELIMIT_EXCEEDED)
1447     {
1448       if(count==1)
1449         fprintf(console,"gpgkeys: search results exceeded server limit."
1450                 "  First %d result shown.\n",count);
1451       else
1452         fprintf(console,"gpgkeys: search results exceeded server limit."
1453                 "  First %d results shown.\n",count);
1454     }
1455
1456   free_keylist(dupelist);
1457   dupelist=NULL;
1458
1459   if(count<1)
1460     fprintf(output,"info:1:0\n");
1461   else
1462     {
1463       fprintf(output,"info:1:%d\n",count);
1464
1465       each=ldap_first_entry(ldap,res);
1466       while(each!=NULL)
1467         {
1468           char **certid;
1469
1470           certid=ldap_get_values(ldap,each,"pgpcertid");
1471           if(certid!=NULL)
1472             {
1473               LDAPMessage *uids;
1474
1475               /* Have we seen this certid before? */
1476               if(!key_in_keylist(certid[0],dupelist))
1477                 {
1478                   int rc=add_key_to_keylist(certid[0],&dupelist);
1479                   if(rc)
1480                     {
1481                       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
1482                       free_keylist(dupelist);
1483                       ldap_value_free(certid);
1484                       ldap_msgfree(res);
1485                       return rc;
1486                     }
1487
1488                   fprintf(output,"pub:%s:",certid[0]);
1489
1490                   vals=ldap_get_values(ldap,each,"pgpkeytype");
1491                   if(vals!=NULL)
1492                     {
1493                       /* The LDAP server doesn't exactly handle this
1494                          well. */
1495                       if(ascii_strcasecmp(vals[0],"RSA")==0)
1496                         fprintf(output,"1");
1497                       else if(ascii_strcasecmp(vals[0],"DSS/DH")==0)
1498                         fprintf(output,"17");
1499                       ldap_value_free(vals);
1500                     }
1501
1502                   fputc(':',output);
1503
1504                   vals=ldap_get_values(ldap,each,"pgpkeysize");
1505                   if(vals!=NULL)
1506                     {
1507                       /* Not sure why, but some keys are listed with a
1508                          key size of 0.  Treat that like an
1509                          unknown. */
1510                       if(atoi(vals[0])>0)
1511                         fprintf(output,"%d",atoi(vals[0]));
1512                       ldap_value_free(vals);
1513                     }
1514
1515                   fputc(':',output);
1516
1517                   /* YYYYMMDDHHmmssZ */
1518
1519                   vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
1520                   if(vals!=NULL && strlen(vals[0])==15)
1521                     {
1522                       fprintf(output,"%u",
1523                               (unsigned int)ldap2epochtime(vals[0]));
1524                       ldap_value_free(vals);
1525                     }
1526
1527                   fputc(':',output);
1528
1529                   vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
1530                   if(vals!=NULL && strlen(vals[0])==15)
1531                     {
1532                       fprintf(output,"%u",
1533                               (unsigned int)ldap2epochtime(vals[0]));
1534                       ldap_value_free(vals);
1535                     }
1536
1537                   fputc(':',output);
1538
1539                   vals=ldap_get_values(ldap,each,"pgprevoked");
1540                   if(vals!=NULL)
1541                     {
1542                       if(atoi(vals[0])==1)
1543                         fprintf(output,"r");
1544                       ldap_value_free(vals);
1545                     }
1546
1547                   vals=ldap_get_values(ldap,each,"pgpdisabled");
1548                   if(vals!=NULL)
1549                     {
1550                       if(atoi(vals[0])==1)
1551                         fprintf(output,"d");
1552                       ldap_value_free(vals);
1553                     }
1554
1555 #if 0
1556                   /* This is not yet specified in the keyserver
1557                      protocol, but may be someday. */
1558                   fputc(':',output);
1559
1560                   vals=ldap_get_values(ldap,each,"modifytimestamp");
1561                   if(vals!=NULL && strlen(vals[0])==15)
1562                     {
1563                       fprintf(output,"%u",
1564                               (unsigned int)ldap2epochtime(vals[0]));
1565                       ldap_value_free(vals);
1566                     }
1567 #endif
1568
1569                   fprintf(output,"\n");
1570
1571                   /* Now print all the uids that have this certid */
1572                   uids=ldap_first_entry(ldap,res);
1573                   while(uids!=NULL)
1574                     {
1575                       vals=ldap_get_values(ldap,uids,"pgpcertid");
1576                       if(vals!=NULL)
1577                         {
1578                           if(ascii_strcasecmp(certid[0],vals[0])==0)
1579                             {
1580                               char **uidvals;
1581
1582                               fprintf(output,"uid:");
1583
1584                               uidvals=ldap_get_values(ldap,uids,"pgpuserid");
1585                               if(uidvals!=NULL)
1586                                 {
1587                                   /* Need to escape any colons */
1588                                   printquoted(output,uidvals[0],':');
1589                                   ldap_value_free(uidvals);
1590                                 }
1591
1592                               fprintf(output,"\n");
1593                             }
1594
1595                           ldap_value_free(vals);
1596                         }
1597
1598                       uids=ldap_next_entry(ldap,uids);
1599                     }
1600                 }
1601
1602               ldap_value_free(certid);
1603             }
1604
1605           each=ldap_next_entry(ldap,each);
1606         }
1607     }
1608
1609   ldap_msgfree(res);
1610   free_keylist(dupelist);
1611
1612   fprintf(output,"SEARCH %s END\n",searchkey);
1613
1614   return KEYSERVER_OK;
1615 }
1616
1617 static void
1618 fail_all(struct keylist *keylist,int err)
1619 {
1620   if(!keylist)
1621     return;
1622
1623   if(opt->action==KS_SEARCH)
1624     {
1625       fprintf(output,"SEARCH ");
1626       while(keylist)
1627         {
1628           fprintf(output,"%s ",keylist->str);
1629           keylist=keylist->next;
1630         }
1631       fprintf(output,"FAILED %d\n",err);
1632     }
1633   else
1634     while(keylist)
1635       {
1636         fprintf(output,"KEY %s FAILED %d\n",keylist->str,err);
1637         keylist=keylist->next;
1638       }
1639 }
1640
1641 static int
1642 find_basekeyspacedn(void)
1643 {
1644   int err,i;
1645   char *attr[]={"namingContexts",NULL,NULL,NULL};
1646   LDAPMessage *res;
1647   char **context;
1648
1649   /* Look for namingContexts */
1650   err=ldap_search_s(ldap,"",LDAP_SCOPE_BASE,"(objectClass=*)",attr,0,&res);
1651   if(err==LDAP_SUCCESS)
1652     {
1653       context=ldap_get_values(ldap,res,"namingContexts");
1654       if(context)
1655         {
1656           attr[0]="pgpBaseKeySpaceDN";
1657           attr[1]="pgpVersion";
1658           attr[2]="pgpSoftware";
1659
1660           real_ldap=1;
1661
1662           /* We found some, so try each namingContext as the search base
1663              and look for pgpBaseKeySpaceDN.  Because we found this, we
1664              know we're talking to a regular-ish LDAP server and not a
1665              LDAP keyserver. */
1666
1667           for(i=0;context[i] && !basekeyspacedn;i++)
1668             {
1669               char **vals;
1670               LDAPMessage *si_res;
1671               char *object;
1672
1673               object=malloc(17+strlen(context[i])+1);
1674               if(!object)
1675                 return -1;
1676
1677               strcpy(object,"cn=pgpServerInfo,");
1678               strcat(object,context[i]);
1679
1680               err=ldap_search_s(ldap,object,LDAP_SCOPE_BASE,
1681                                 "(objectClass=*)",attr,0,&si_res);
1682               free(object);
1683
1684               if(err==LDAP_NO_SUCH_OBJECT)
1685                 continue;
1686               else if(err!=LDAP_SUCCESS)
1687                 return err;
1688
1689               vals=ldap_get_values(ldap,si_res,"pgpBaseKeySpaceDN");
1690               if(vals)
1691                 {
1692                   basekeyspacedn=strdup(vals[0]);
1693                   ldap_value_free(vals);
1694                 }
1695
1696               if(opt->verbose>1)
1697                 {
1698                   vals=ldap_get_values(ldap,si_res,"pgpSoftware");
1699                   if(vals)
1700                     {
1701                       fprintf(console,"Server: \t%s\n",vals[0]);
1702                       ldap_value_free(vals);
1703                     }
1704
1705                   vals=ldap_get_values(ldap,si_res,"pgpVersion");
1706                   if(vals)
1707                     {
1708                       fprintf(console,"Version:\t%s\n",vals[0]);
1709                       ldap_value_free(vals);
1710                     }
1711                 }
1712
1713               ldap_msgfree(si_res);
1714             }
1715
1716           ldap_value_free(context);
1717         }
1718
1719       ldap_msgfree(res);
1720     }
1721   else
1722     {
1723       /* We don't have an answer yet, which means the server might be
1724          a LDAP keyserver. */
1725       char **vals;
1726       LDAPMessage *si_res;
1727
1728       attr[0]="pgpBaseKeySpaceDN";
1729       attr[1]="version";
1730       attr[2]="software";
1731
1732       err=ldap_search_s(ldap,"cn=pgpServerInfo",LDAP_SCOPE_BASE,
1733                         "(objectClass=*)",attr,0,&si_res);
1734       if(err!=LDAP_SUCCESS)
1735         return err;
1736
1737       /* For the LDAP keyserver, this is always "OU=ACTIVE,O=PGP
1738          KEYSPACE,C=US", but it might not be in the future. */
1739
1740       vals=ldap_get_values(ldap,si_res,"baseKeySpaceDN");
1741       if(vals)
1742         {
1743           basekeyspacedn=strdup(vals[0]);
1744           ldap_value_free(vals);
1745         }
1746
1747       if(opt->verbose>1)
1748         {
1749           vals=ldap_get_values(ldap,si_res,"software");
1750           if(vals)
1751             {
1752               fprintf(console,"Server: \t%s\n",vals[0]);
1753               ldap_value_free(vals);
1754             }
1755         }
1756
1757       vals=ldap_get_values(ldap,si_res,"version");
1758       if(vals)
1759         {
1760           if(opt->verbose>1)
1761             fprintf(console,"Version:\t%s\n",vals[0]);
1762
1763           /* If the version is high enough, use the new pgpKeyV2
1764              attribute.  This design if iffy at best, but it matches how
1765              PGP does it.  I figure the NAI folks assumed that there would
1766              never be a LDAP keyserver vendor with a different numbering
1767              scheme. */
1768           if(atoi(vals[0])>1)
1769             pgpkeystr="pgpKeyV2";
1770
1771           ldap_value_free(vals);
1772         }
1773
1774       ldap_msgfree(si_res);
1775     }   
1776
1777   return LDAP_SUCCESS;
1778 }
1779
1780 static void 
1781 show_help (FILE *fp)
1782 {
1783   fprintf (fp,"-h\thelp\n");
1784   fprintf (fp,"-V\tversion\n");
1785   fprintf (fp,"-o\toutput to this file\n");
1786 }
1787
1788 int
1789 main(int argc,char *argv[])
1790 {
1791   int port=0,arg,err,ret=KEYSERVER_INTERNAL_ERROR;
1792   char line[MAX_LINE],*binddn=NULL,*bindpw=NULL;
1793   int failed=0,use_ssl=0,use_tls=0,bound=0;
1794   struct keylist *keylist=NULL,*keyptr=NULL;
1795
1796   console=stderr;
1797
1798   /* Kludge to implement standard GNU options.  */
1799   if (argc > 1 && !strcmp (argv[1], "--version"))
1800     {
1801       fputs ("gpgkeys_ldap (GnuPG) " VERSION"\n", stdout);
1802       return 0;
1803     }
1804   else if (argc > 1 && !strcmp (argv[1], "--help"))
1805     {
1806       show_help (stdout);
1807       return 0;
1808     }
1809
1810   while((arg=getopt(argc,argv,"hVo:"))!=-1)
1811     switch(arg)
1812       {
1813       default:
1814       case 'h':
1815         show_help (console);
1816         return KEYSERVER_OK;
1817
1818       case 'V':
1819         fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
1820         return KEYSERVER_OK;
1821
1822       case 'o':
1823         output=fopen(optarg,"w");
1824         if(output==NULL)
1825           {
1826             fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
1827                     optarg,strerror(errno));
1828             return KEYSERVER_INTERNAL_ERROR;
1829           }
1830
1831         break;
1832       }
1833
1834   if(argc>optind)
1835     {
1836       input=fopen(argv[optind],"r");
1837       if(input==NULL)
1838         {
1839           fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
1840                   argv[optind],strerror(errno));
1841           return KEYSERVER_INTERNAL_ERROR;
1842         }
1843     }
1844
1845   if(input==NULL)
1846     input=stdin;
1847
1848   if(output==NULL)
1849     output=stdout;
1850
1851   opt=init_ks_options();
1852   if(!opt)
1853     return KEYSERVER_NO_MEMORY;
1854
1855   /* Get the command and info block */
1856
1857   while(fgets(line,MAX_LINE,input)!=NULL)
1858     {
1859       char optionstr[MAX_OPTION+1];
1860
1861       if(line[0]=='\n')
1862         break;
1863
1864       err=parse_ks_options(line,opt);
1865       if(err>0)
1866         {
1867           ret=err;
1868           goto fail;
1869         }
1870       else if(err==0)
1871         continue;
1872
1873       if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",optionstr)==1)
1874         {
1875           int no=0;
1876           char *start=&optionstr[0];
1877
1878           optionstr[MAX_OPTION]='\0';
1879
1880           if(ascii_strncasecmp(optionstr,"no-",3)==0)
1881             {
1882               no=1;
1883               start=&optionstr[3];
1884             }
1885
1886           if(ascii_strncasecmp(start,"tls",3)==0)
1887             {
1888               if(no)
1889                 use_tls=0;
1890               else if(start[3]=='=')
1891                 {
1892                   if(ascii_strcasecmp(&start[4],"no")==0)
1893                     use_tls=0;
1894                   else if(ascii_strcasecmp(&start[4],"try")==0)
1895                     use_tls=1;
1896                   else if(ascii_strcasecmp(&start[4],"warn")==0)
1897                     use_tls=2;
1898                   else if(ascii_strcasecmp(&start[4],"require")==0)
1899                     use_tls=3;
1900                   else
1901                     use_tls=1;
1902                 }
1903               else if(start[3]=='\0')
1904                 use_tls=1;
1905             }
1906           else if(ascii_strncasecmp(start,"basedn",6)==0)
1907             {
1908               if(no)
1909                 {
1910                   free(basekeyspacedn);
1911                   basekeyspacedn=NULL;
1912                 }
1913               else if(start[6]=='=')
1914                 {
1915                   free(basekeyspacedn);
1916                   basekeyspacedn=strdup(&start[7]);
1917                   if(!basekeyspacedn)
1918                     {
1919                       fprintf(console,"gpgkeys: out of memory while creating "
1920                               "base DN\n");
1921                       ret=KEYSERVER_NO_MEMORY;
1922                       goto fail;
1923                     }
1924
1925                   real_ldap=1;
1926                 }
1927             }
1928           else if(ascii_strncasecmp(start,"binddn",6)==0)
1929             {
1930               if(no)
1931                 {
1932                   free(binddn);
1933                   binddn=NULL;
1934                 }
1935               else if(start[6]=='=')
1936                 {
1937                   free(binddn);
1938                   binddn=strdup(&start[7]);
1939                   if(!binddn)
1940                     {
1941                       fprintf(console,"gpgkeys: out of memory while creating "
1942                               "bind DN\n");
1943                       ret=KEYSERVER_NO_MEMORY;
1944                       goto fail;
1945                     }
1946
1947                   real_ldap=1;
1948                 }
1949             }
1950           else if(ascii_strncasecmp(start,"bindpw",6)==0)
1951             {
1952               if(no)
1953                 {
1954                   free(bindpw);
1955                   bindpw=NULL;
1956                 }
1957               else if(start[6]=='=')
1958                 {
1959                   free(bindpw);
1960                   bindpw=strdup(&start[7]);
1961                   if(!bindpw)
1962                     {
1963                       fprintf(console,"gpgkeys: out of memory while creating "
1964                               "bind password\n");
1965                       ret=KEYSERVER_NO_MEMORY;
1966                       goto fail;
1967                     }
1968
1969                   real_ldap=1;
1970                 }
1971             }
1972
1973           continue;
1974         }
1975     }
1976
1977   if(!opt->scheme)
1978     {
1979       fprintf(console,"gpgkeys: no scheme supplied!\n");
1980       ret=KEYSERVER_SCHEME_NOT_FOUND;
1981       goto fail;
1982     }
1983
1984   if(ascii_strcasecmp(opt->scheme,"ldaps")==0)
1985     {
1986       port=636;
1987       use_ssl=1;
1988     }
1989
1990   if(opt->port)
1991     port=atoi(opt->port);
1992
1993   if(!opt->host)
1994     {
1995       fprintf(console,"gpgkeys: no keyserver host provided\n");
1996       goto fail;
1997     }
1998
1999   if(opt->timeout && register_timeout()==-1)
2000     {
2001       fprintf(console,"gpgkeys: unable to register timeout handler\n");
2002       return KEYSERVER_INTERNAL_ERROR;
2003     }
2004
2005 #if defined(LDAP_OPT_X_TLS_CACERTFILE) && defined(HAVE_LDAP_SET_OPTION)
2006
2007   if(opt->ca_cert_file)
2008     {
2009       err=ldap_set_option(NULL,LDAP_OPT_X_TLS_CACERTFILE,opt->ca_cert_file);
2010       if(err!=LDAP_SUCCESS)
2011         {
2012           fprintf(console,"gpgkeys: unable to set ca-cert-file: %s\n",
2013                   ldap_err2string(err));
2014           ret=KEYSERVER_INTERNAL_ERROR;
2015           goto fail;
2016         }
2017     }
2018 #endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */
2019
2020   /* SSL trumps TLS */
2021   if(use_ssl)
2022     use_tls=0;
2023
2024   /* If it's a GET or a SEARCH, the next thing to come in is the
2025      keyids.  If it's a SEND, then there are no keyids. */
2026
2027   if(opt->action==KS_SEND)
2028     while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
2029   else if(opt->action==KS_GET
2030           || opt->action==KS_GETNAME || opt->action==KS_SEARCH)
2031     {
2032       for(;;)
2033         {
2034           struct keylist *work;
2035
2036           if(fgets(line,MAX_LINE,input)==NULL)
2037             break;
2038           else
2039             {
2040               if(line[0]=='\n' || line[0]=='\0')
2041                 break;
2042
2043               work=malloc(sizeof(struct keylist));
2044               if(work==NULL)
2045                 {
2046                   fprintf(console,"gpgkeys: out of memory while "
2047                           "building key list\n");
2048                   ret=KEYSERVER_NO_MEMORY;
2049                   goto fail;
2050                 }
2051
2052               strcpy(work->str,line);
2053
2054               /* Trim the trailing \n */
2055               work->str[strlen(line)-1]='\0';
2056
2057               work->next=NULL;
2058
2059               /* Always attach at the end to keep the list in proper
2060                  order for searching */
2061               if(keylist==NULL)
2062                 keylist=work;
2063               else
2064                 keyptr->next=work;
2065
2066               keyptr=work;
2067             }
2068         }
2069     }
2070   else
2071     {
2072       fprintf(console,"gpgkeys: no keyserver command specified\n");
2073       goto fail;
2074     }
2075
2076   /* Send the response */
2077
2078   fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
2079   fprintf(output,"PROGRAM %s\n\n",VERSION);
2080
2081   if(opt->verbose>1)
2082     {
2083       fprintf(console,"Host:\t\t%s\n",opt->host);
2084       if(port)
2085         fprintf(console,"Port:\t\t%d\n",port);
2086       fprintf(console,"Command:\t%s\n",ks_action_to_string(opt->action));
2087     }
2088
2089   if(opt->debug)
2090     {
2091 #if defined(LDAP_OPT_DEBUG_LEVEL) && defined(HAVE_LDAP_SET_OPTION)
2092       err=ldap_set_option(NULL,LDAP_OPT_DEBUG_LEVEL,&opt->debug);
2093       if(err!=LDAP_SUCCESS)
2094         fprintf(console,"gpgkeys: unable to set debug mode: %s\n",
2095                 ldap_err2string(err));
2096       else
2097         fprintf(console,"gpgkeys: debug level %d\n",opt->debug);
2098 #else
2099       fprintf(console,"gpgkeys: not built with debugging support\n");
2100 #endif
2101     }
2102
2103   /* We have a timeout set for the setup stuff since it could time out
2104      as well. */
2105   set_timeout(opt->timeout);
2106
2107   /* Note that this tries all A records on a given host (or at least,
2108      OpenLDAP does). */
2109   ldap=ldap_init(opt->host,port);
2110   if(ldap==NULL)
2111     {
2112       fprintf(console,"gpgkeys: internal LDAP init error: %s\n",
2113               strerror(errno));
2114       fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2115       goto fail;
2116     }
2117
2118   if(use_ssl)
2119     {
2120 #if defined(LDAP_OPT_X_TLS) && defined(HAVE_LDAP_SET_OPTION)
2121       int ssl=LDAP_OPT_X_TLS_HARD;
2122
2123       err=ldap_set_option(ldap,LDAP_OPT_X_TLS,&ssl);
2124       if(err!=LDAP_SUCCESS)
2125         {
2126           fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
2127                   ldap_err2string(err));
2128           fail_all(keylist,ldap_err_to_gpg_err(err));
2129           goto fail;
2130         }
2131
2132       if(!opt->flags.check_cert)
2133         ssl=LDAP_OPT_X_TLS_NEVER;
2134
2135       err=ldap_set_option(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,&ssl);
2136       if(err!=LDAP_SUCCESS)
2137         {
2138           fprintf(console,
2139                   "gpgkeys: unable to set certificate validation: %s\n",
2140                   ldap_err2string(err));
2141           fail_all(keylist,ldap_err_to_gpg_err(err));
2142           goto fail;
2143         }
2144 #else
2145       fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
2146               "not built with LDAPS support");
2147       fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2148       goto fail;
2149 #endif
2150     }
2151
2152   if(!basekeyspacedn)
2153     if((err=find_basekeyspacedn()) || !basekeyspacedn)
2154       {
2155         fprintf(console,"gpgkeys: unable to retrieve LDAP base: %s\n",
2156                 err?ldap_err2string(err):"not found");
2157         fail_all(keylist,ldap_err_to_gpg_err(err));
2158         goto fail;
2159       }
2160
2161   /* use_tls: 0=don't use, 1=try silently to use, 2=try loudly to use,
2162      3=force use. */
2163   if(use_tls)
2164     {
2165       if(!real_ldap)
2166         {
2167           if(use_tls>=2)
2168             fprintf(console,"gpgkeys: unable to start TLS: %s\n",
2169                     "not supported by the NAI LDAP keyserver");
2170           if(use_tls==3)
2171             {
2172               fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2173               goto fail;
2174             }
2175         }
2176       else
2177         {
2178 #if defined(HAVE_LDAP_START_TLS_S) && defined(HAVE_LDAP_SET_OPTION)
2179           int ver=LDAP_VERSION3;
2180
2181           err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
2182
2183 #ifdef LDAP_OPT_X_TLS
2184           if(err==LDAP_SUCCESS)
2185             {
2186               if(opt->flags.check_cert)
2187                 ver=LDAP_OPT_X_TLS_HARD;
2188               else
2189                 ver=LDAP_OPT_X_TLS_NEVER;
2190
2191               err=ldap_set_option(ldap,LDAP_OPT_X_TLS_REQUIRE_CERT,&ver);
2192             }
2193 #endif
2194
2195           if(err==LDAP_SUCCESS)
2196             err=ldap_start_tls_s(ldap,NULL,NULL);
2197
2198           if(err!=LDAP_SUCCESS)
2199             {
2200               if(use_tls>=2 || opt->verbose>2)
2201                 fprintf(console,"gpgkeys: unable to start TLS: %s\n",
2202                         ldap_err2string(err));
2203               /* Are we forcing it? */
2204               if(use_tls==3)
2205                 {
2206                   fail_all(keylist,ldap_err_to_gpg_err(err));
2207                   goto fail;
2208                 }
2209             }
2210           else if(opt->verbose>1)
2211             fprintf(console,"gpgkeys: TLS started successfully.\n");
2212 #else
2213           if(use_tls>=2)
2214             fprintf(console,"gpgkeys: unable to start TLS: %s\n",
2215                     "not built with TLS support");
2216           if(use_tls==3)
2217             {
2218               fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2219               goto fail;
2220             }
2221 #endif
2222         }
2223     }
2224
2225   /* By default we don't bind as there is usually no need to.  For
2226      cases where the server needs some authentication, the user can
2227      use binddn and bindpw for auth. */
2228
2229   if(binddn)
2230     {
2231 #ifdef HAVE_LDAP_SET_OPTION
2232       int ver=LDAP_VERSION3;
2233
2234       err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
2235       if(err!=LDAP_SUCCESS)
2236         {
2237           fprintf(console,"gpgkeys: unable to go to LDAP 3: %s\n",
2238                   ldap_err2string(err));
2239           fail_all(keylist,ldap_err_to_gpg_err(err));
2240           goto fail;
2241         }
2242 #endif
2243
2244       if(opt->verbose>2)
2245         fprintf(console,"gpgkeys: LDAP bind to %s, pw %s\n",binddn,
2246                 bindpw?">not shown<":">none<");
2247       err=ldap_simple_bind_s(ldap,binddn,bindpw);
2248       if(err!=LDAP_SUCCESS)
2249         {
2250           fprintf(console,"gpgkeys: internal LDAP bind error: %s\n",
2251                   ldap_err2string(err));
2252           fail_all(keylist,ldap_err_to_gpg_err(err));
2253           goto fail;
2254         }
2255       else
2256         bound=1;
2257     }
2258
2259   if(opt->action==KS_GET)
2260     {
2261       keyptr=keylist;
2262
2263       while(keyptr!=NULL)
2264         {
2265           set_timeout(opt->timeout);
2266
2267           if(get_key(keyptr->str)!=KEYSERVER_OK)
2268             failed++;
2269
2270           keyptr=keyptr->next;
2271         }
2272     }
2273   else if(opt->action==KS_GETNAME)
2274     {
2275       keyptr=keylist;
2276
2277       while(keyptr!=NULL)
2278         {
2279           set_timeout(opt->timeout);
2280
2281           if(get_name(keyptr->str)!=KEYSERVER_OK)
2282             failed++;
2283
2284           keyptr=keyptr->next;
2285         }
2286     }
2287   else if(opt->action==KS_SEND)
2288     {
2289       int eof=0;
2290
2291       do
2292         {
2293           set_timeout(opt->timeout);
2294
2295           if(real_ldap)
2296             {
2297               if(send_key(&eof)!=KEYSERVER_OK)
2298                 failed++;
2299             }
2300           else
2301             {
2302               if(send_key_keyserver(&eof)!=KEYSERVER_OK)
2303                 failed++;
2304             }
2305         }
2306       while(!eof);
2307     }
2308   else if(opt->action==KS_SEARCH)
2309     {
2310       char *searchkey=NULL;
2311       int len=0;
2312
2313       set_timeout(opt->timeout);
2314
2315       /* To search, we stick a * in between each key to search for.
2316          This means that if the user enters words, they'll get
2317          "enters*words".  If the user "enters words", they'll get
2318          "enters words" */
2319
2320       keyptr=keylist;
2321       while(keyptr!=NULL)
2322         {
2323           len+=strlen(keyptr->str)+1;
2324           keyptr=keyptr->next;
2325         }
2326
2327       searchkey=malloc((len*3)+1);
2328       if(searchkey==NULL)
2329         {
2330           ret=KEYSERVER_NO_MEMORY;
2331           fail_all(keylist,KEYSERVER_NO_MEMORY);
2332           goto fail;
2333         }
2334
2335       searchkey[0]='\0';
2336
2337       keyptr=keylist;
2338       while(keyptr!=NULL)
2339         {
2340           ldap_quote(searchkey,keyptr->str);
2341           strcat(searchkey,"*");
2342           keyptr=keyptr->next;
2343         }
2344
2345       /* Nail that last "*" */
2346       if(*searchkey)
2347         searchkey[strlen(searchkey)-1]='\0';
2348
2349       if(search_key(searchkey)!=KEYSERVER_OK)
2350         failed++;
2351
2352       free(searchkey);
2353     }
2354   else
2355     assert (!"invalid action");
2356
2357   if(!failed)
2358     ret=KEYSERVER_OK;
2359
2360  fail:
2361
2362   while(keylist!=NULL)
2363     {
2364       struct keylist *current=keylist;
2365       keylist=keylist->next;
2366       free(current);
2367     }
2368
2369   if(input!=stdin)
2370     fclose(input);
2371
2372   if(output!=stdout)
2373     fclose(output);
2374
2375   free_ks_options(opt);
2376
2377   if(ldap!=NULL && bound)
2378     ldap_unbind_s(ldap);
2379
2380   free(basekeyspacedn);
2381
2382   return ret;
2383 }