* gpgkeys_ldap.c: Replacement prototypes for setenv and unsetenv.
[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 "keyserver.h"
33
34 #ifdef __riscos__
35 #include "util.h"
36 #endif
37
38 extern char *optarg;
39 extern int optind;
40
41 #define GET    0
42 #define SEND   1
43 #define SEARCH 2
44 #define MAX_LINE 80
45
46 static int verbose=0,include_disabled=0,include_revoked=0,include_subkeys=0;
47 static int real_ldap=0;
48 static char *basekeyspacedn=NULL;
49 static char host[80]={'\0'};
50 static char portstr[10]={'\0'};
51 static char *pgpkeystr="pgpKey";
52 static FILE *input=NULL,*output=NULL,*console=NULL;
53 static LDAP *ldap=NULL;
54
55 #if !HAVE_SETENV
56 int setenv(const char *name, const char *value, int overwrite);
57 #endif
58
59 #if !HAVE_UNSETENV
60 int unsetenv(const char *name);
61 #endif
62
63 struct keylist
64 {
65   char str[MAX_LINE];
66   struct keylist *next;
67 };
68
69 int
70 ldap_err_to_gpg_err(int err)
71 {
72   int ret;
73
74   switch(err)
75     {
76     case LDAP_ALREADY_EXISTS:
77       ret=KEYSERVER_KEY_EXISTS;
78       break;
79
80     case LDAP_SERVER_DOWN:
81       ret=KEYSERVER_UNREACHABLE;
82       break;
83
84     default:
85       ret=KEYSERVER_GENERAL_ERROR;
86       break;
87     }
88
89   return ret;
90 }
91
92 int
93 ldap_to_gpg_err(LDAP *ld)
94 {
95 #if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
96
97   int err;
98
99   if(ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&err)==0)
100     return ldap_err_to_gpg_err(err);
101   else
102     return KEYSERVER_GENERAL_ERROR;
103
104 #elif defined(HAVE_LDAP_LD_ERRNO)
105
106   return ldap_err_to_gpg_err(ld->ld_errno);
107
108 #else
109
110   /* We should never get here since the LDAP library should always
111      have either ldap_get_option or ld_errno, but just in case... */
112   return KEYSERVER_GENERAL_ERROR;
113
114 #endif
115 }
116
117 int
118 key_in_keylist(const char *key,struct keylist *list)
119 {
120   struct keylist *keyptr=list;
121
122   while(keyptr!=NULL)
123     {
124       if(strcasecmp(key,keyptr->str)==0)
125         return 1;
126
127       keyptr=keyptr->next;
128     }
129
130   return 0;
131 }
132
133 int
134 add_key_to_keylist(const char *key,struct keylist **list)
135 {
136   struct keylist *keyptr=malloc(sizeof(struct keylist));
137
138   if(keyptr==NULL)
139     {
140       fprintf(console,"gpgkeys: out of memory when deduping "
141               "key list\n");
142       return KEYSERVER_NO_MEMORY;
143     }
144
145   strncpy(keyptr->str,key,MAX_LINE);
146   keyptr->str[MAX_LINE-1]='\0';
147   keyptr->next=*list;
148   *list=keyptr;
149
150   return 0;
151 }
152
153 void
154 free_keylist(struct keylist *list)
155 {
156   while(list!=NULL)
157     {
158       struct keylist *keyptr=list;
159
160       list=keyptr->next;
161       free(keyptr);
162     }
163 }
164
165 int
166 send_key(int *eof)
167 {
168   int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
169   char *dn=NULL,line[MAX_LINE],*key[2]={NULL,NULL};
170   char keyid[17];
171   LDAPMod mod, *attrs[2];
172
173   memset (&mod, 0, sizeof mod);
174   mod.mod_op      = LDAP_MOD_ADD;
175   mod.mod_type    = pgpkeystr;
176   mod.mod_values  = key;
177   attrs[0]    = &mod;
178   attrs[1]    = NULL;
179
180   dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1);
181   if(dn==NULL)
182     {
183       fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
184       ret=KEYSERVER_NO_MEMORY;
185       goto fail;
186     }
187
188   strcpy(dn,"pgpCertid=virtual,");
189   strcat(dn,basekeyspacedn);
190
191   key[0]=malloc(1);
192   if(key[0]==NULL)
193     {
194       fprintf(console,"gpgkeys: unable to allocate memory for key\n");
195       ret=KEYSERVER_NO_MEMORY;
196       goto fail;
197     }
198
199   key[0][0]='\0';
200
201   /* Read and throw away stdin until we see the BEGIN */
202
203   while(fgets(line,MAX_LINE,input)!=NULL)
204     if(sscanf(line,"KEY %16s BEGIN\n",keyid)==1)
205       {
206         begin=1;
207         break;
208       }
209
210   if(!begin)
211     {
212       /* i.e. eof before the KEY BEGIN was found.  This isn't an
213          error. */
214       *eof=1;
215       ret=KEYSERVER_OK;
216       goto fail;
217     }
218
219   /* Now slurp up everything until we see the END */
220
221   while(fgets(line,MAX_LINE,input)!=NULL)
222     if(sscanf(line,"KEY %16s END\n",keyid)==1)
223       {
224         end=1;
225         break;
226       }
227     else
228       {
229         keysize+=strlen(line);
230         key[0]=realloc(key[0],keysize);
231         if(key[0]==NULL)
232           {
233             fprintf(console,"gpgkeys: unable to reallocate for key\n");
234             ret=KEYSERVER_NO_MEMORY;
235             goto fail;
236           }
237
238         strcat(key[0],line);
239       }
240
241   if(!end)
242     {
243       fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
244       *eof=1;
245       ret=KEYSERVER_KEY_INCOMPLETE;
246       goto fail;
247     }
248
249   err=ldap_add_s(ldap,dn,attrs);
250   if(err!=LDAP_SUCCESS)
251     {
252       fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
253               keyid,ldap_err2string(err));
254       ret=ldap_err_to_gpg_err(err);
255       goto fail;
256     }
257
258   ret=KEYSERVER_OK;
259
260  fail:
261
262   free(key[0]);
263   free(dn);
264
265   if(ret!=0 && begin)
266     fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
267
268   /* Not a fatal error */
269   if(ret==KEYSERVER_KEY_EXISTS)
270     ret=KEYSERVER_OK;
271
272   return ret;
273 }
274
275 /* Note that key-not-found is not a fatal error */
276 int
277 get_key(char *getkey)
278 {
279   LDAPMessage *res,*each;
280   int ret=KEYSERVER_INTERNAL_ERROR,err,count;
281   struct keylist *dupelist=NULL;
282   char search[62];
283   /* This ordering is significant - specifically, "pgpcertid" needs to
284      be the second item in the list, since everything after it may be
285      discarded if the user isn't in verbose mode. */
286   char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
287                  "pgpdisabled","pgpkeycreatetime","modifytimestamp",
288                  "pgpkeysize","pgpkeytype",NULL};
289   attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
290                          array initializers. */
291
292   /* Build the search string */
293
294   /* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3
295      or v4 short key id */
296
297   if(strncmp(getkey,"0x",2)==0)
298     getkey+=2;
299
300   if(strlen(getkey)==32)
301     {
302       fprintf(console,
303               "gpgkeys: LDAP keyservers do not support v3 fingerprints\n");
304       fprintf(output,"KEY 0x%s BEGIN\n",getkey);
305       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED);
306       return KEYSERVER_NOT_SUPPORTED;
307     }
308
309   if(strlen(getkey)>16)
310     {
311       char *offset=&getkey[strlen(getkey)-16];
312
313       /* fingerprint.  Take the last 16 characters and treat it like a
314          long key id */
315
316       if(include_subkeys)
317         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
318                 offset,offset);
319       else
320         sprintf(search,"(pgpcertid=%.16s)",offset);
321     }
322   else if(strlen(getkey)>8)
323     {
324       /* long key id */
325
326       if(include_subkeys)
327         sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
328                 getkey,getkey);
329       else
330         sprintf(search,"(pgpcertid=%.16s)",getkey);
331     }
332   else
333     {
334       /* short key id */
335     
336       sprintf(search,"(pgpkeyid=%.8s)",getkey);
337     }
338
339   fprintf(output,"KEY 0x%s BEGIN\n",getkey);
340
341   if(verbose>2)
342     fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
343
344   if(!verbose)
345     attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
346
347   if(verbose)
348     fprintf(console,"gpgkeys: requesting key 0x%s from ldap://%s%s%s\n",
349             getkey,host,portstr[0]?":":"",portstr[0]?portstr:"");
350
351   err=ldap_search_s(ldap,basekeyspacedn,
352                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
353   if(err!=0)
354     {
355       int errtag=ldap_err_to_gpg_err(err);
356
357       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
358       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
359       return errtag;
360     }
361
362   count=ldap_count_entries(ldap,res);
363   if(count<1)
364     {
365       fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
366       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
367     }
368   else
369     {
370       /* There may be more than one unique result for a given keyID,
371          so we should fetch them all (test this by fetching short key
372          id 0xDEADBEEF). */
373
374       each=ldap_first_entry(ldap,res);
375       while(each!=NULL)
376         {
377           char **vals,**certid;
378
379           /* Use the long keyid to remove duplicates.  The LDAP server
380              returns the same keyid more than once if there are
381              multiple user IDs on the key.  Note that this does NOT
382              mean that a keyid that exists multiple times on the
383              keyserver will not be fetched.  It means that each KEY,
384              no matter how many user IDs share its keyid, will be
385              fetched only once.  If a keyid that belongs to more than
386              one key is fetched, the server quite properly responds
387              with all matching keys. -ds */
388
389           certid=ldap_get_values(ldap,each,"pgpcertid");
390           if(certid!=NULL)
391             {
392               if(!key_in_keylist(certid[0],dupelist))
393                 {
394                   /* it's not a duplicate, so add it */
395
396                   int rc=add_key_to_keylist(certid[0],&dupelist);
397                   if(rc)
398                     {
399                       ret=rc;
400                       goto fail;
401                     }
402
403                   if(verbose)
404                     {
405                       vals=ldap_get_values(ldap,each,"pgpuserid");
406                       if(vals!=NULL)
407                         {
408                           /* This is wrong, as the user ID is UTF8.  A
409                              better way to handle this would be to send it
410                              over to gpg and display it on that side of
411                              the pipe. */
412                           fprintf(console,"\nUser ID:\t%s\n",vals[0]);
413                           ldap_value_free(vals);
414                         }
415
416                       vals=ldap_get_values(ldap,each,"pgprevoked");
417                       if(vals!=NULL)
418                         {
419                           if(atoi(vals[0])==1)
420                             fprintf(console,"\t\t** KEY REVOKED **\n");
421                           ldap_value_free(vals);
422                         }
423
424                       vals=ldap_get_values(ldap,each,"pgpdisabled");
425                       if(vals!=NULL)
426                         {
427                           if(atoi(vals[0])==1)
428                             fprintf(console,"\t\t** KEY DISABLED **\n");
429                           ldap_value_free(vals);
430                         }
431
432                       vals=ldap_get_values(ldap,each,"pgpkeyid");
433                       if(vals!=NULL)
434                         {
435                           fprintf(console,"Short key ID:\t%s\n",vals[0]);
436                           ldap_value_free(vals);
437                         }
438
439                       fprintf(console,"Long key ID:\t%s\n",certid[0]);
440
441                       /* YYYYMMDDHHmmssZ */
442
443                       vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
444                       if(vals!=NULL)
445                         {
446                           if(strlen(vals[0])==15)
447                             fprintf(console,"Key created:\t%.2s/%.2s/%.4s\n",
448                                     &vals[0][4],&vals[0][6],vals[0]);
449                           ldap_value_free(vals);
450                         }
451
452                       vals=ldap_get_values(ldap,each,"modifytimestamp");
453                       if(vals!=NULL)
454                         {
455                           if(strlen(vals[0])==15)
456                             fprintf(console,"Key modified:\t%.2s/%.2s/%.4s\n",
457                                     &vals[0][4],&vals[0][6],vals[0]);
458                           ldap_value_free(vals);
459                         }
460
461                       vals=ldap_get_values(ldap,each,"pgpkeysize");
462                       if(vals!=NULL)
463                         {
464                           if(atoi(vals[0])>0)
465                             fprintf(console,"Key size:\t%d\n",atoi(vals[0]));
466                           ldap_value_free(vals);
467                         }
468
469                       vals=ldap_get_values(ldap,each,"pgpkeytype");
470                       if(vals!=NULL)
471                         {
472                           fprintf(console,"Key type:\t%s\n",vals[0]);
473                           ldap_value_free(vals);
474                         }
475                     }
476
477                   vals=ldap_get_values(ldap,each,pgpkeystr);
478                   if(vals==NULL)
479                     {
480                       int errtag=ldap_to_gpg_err(ldap);
481
482                       fprintf(console,"gpgkeys: unable to retrieve key %s "
483                               "from keyserver\n",getkey);
484                       fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
485                     }
486                   else
487                     {
488                       fprintf(output,"%sKEY 0x%s END\n",vals[0],getkey);
489
490                       ldap_value_free(vals);
491                     }
492                 }
493
494               ldap_value_free(certid);
495             }
496
497           each=ldap_next_entry(ldap,each);
498         }
499     }
500
501   ret=KEYSERVER_OK;
502
503  fail:
504   ldap_msgfree(res);
505   free_keylist(dupelist);
506
507   return ret;
508 }
509
510 time_t
511 ldap2epochtime(const char *timestr)
512 {
513   struct tm pgptime;
514   time_t answer;
515
516   memset(&pgptime,0,sizeof(pgptime));
517
518   /* YYYYMMDDHHmmssZ */
519
520   sscanf(timestr,"%4d%2d%2d%2d%2d%2d",
521          &pgptime.tm_year,
522          &pgptime.tm_mon,
523          &pgptime.tm_mday,
524          &pgptime.tm_hour,
525          &pgptime.tm_min,
526          &pgptime.tm_sec);
527
528   pgptime.tm_year-=1900;
529   pgptime.tm_isdst=-1;
530   pgptime.tm_mon--;
531
532   /* mktime takes the timezone into account, and we can't have that.
533      I'd use timegm, but it's not portable. */
534
535 #ifdef HAVE_TIMEGM
536   answer=timegm(&pgptime);
537 #else
538   {
539     char *zone=getenv("TZ");
540     setenv("TZ","UTC",1);
541     tzset();
542     answer=mktime(&pgptime);
543     if(zone)
544       setenv("TZ",zone,1);
545     else
546       unsetenv("TZ");
547     tzset();
548   }
549 #endif
550
551   return answer;
552 }
553
554 void
555 printquoted(FILE *stream,char *string,char delim)
556 {
557   while(*string)
558     {
559       if(*string==delim || *string=='%')
560         fprintf(stream,"%%%02x",*string);
561       else
562         fputc(*string,stream);
563
564       string++;
565     }
566 }
567
568 /* Returns 0 on success and -1 on error.  Note that key-not-found is
569    not an error! */
570 int
571 search_key(char *searchkey)
572 {
573   char **vals;
574   LDAPMessage *res,*each;
575   int err,count=0;
576   struct keylist *dupelist=NULL;
577   /* The maximum size of the search, including the optional stuff and
578      the trailing \0 */
579   char search[2+12+MAX_LINE+2+15+14+1+1];
580   char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
581                  "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
582                  "pgpkeysize","pgpkeytype",NULL};
583
584   fprintf(output,"SEARCH %s BEGIN\n",searchkey);
585
586   /* Build the search string */
587
588   sprintf(search,"%s(pgpuserid=*%s*)%s%s%s",
589           (!(include_disabled&&include_revoked))?"(&":"",
590           searchkey,
591           include_disabled?"":"(pgpdisabled=0)",
592           include_revoked?"":"(pgprevoked=0)",
593           !(include_disabled&&include_revoked)?")":"");
594
595   if(verbose>2)
596     fprintf(console,"gpgkeys: LDAP search for: %s\n",search);
597
598   fprintf(console,("gpgkeys: searching for \"%s\" from LDAP server %s\n"),
599           searchkey,host);
600
601   err=ldap_search_s(ldap,basekeyspacedn,
602                     LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
603   if(err!=LDAP_SUCCESS && err!=LDAP_SIZELIMIT_EXCEEDED)
604     {
605       int errtag=ldap_err_to_gpg_err(err);
606
607       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,errtag);
608       fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
609       return errtag;
610     }
611
612   /* The LDAP server doesn't return a real count of unique keys, so we
613      can't use ldap_count_entries here. */
614   each=ldap_first_entry(ldap,res);
615   while(each!=NULL)
616     {
617       char **certid=ldap_get_values(ldap,each,"pgpcertid");
618
619       if(certid!=NULL)
620         {
621           if(!key_in_keylist(certid[0],dupelist))
622             {
623               int rc=add_key_to_keylist(certid[0],&dupelist);
624               if(rc!=0)
625                 {
626                   fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
627                   free_keylist(dupelist);
628                   return rc;
629                 }
630
631               count++;
632             }
633         }
634
635       each=ldap_next_entry(ldap,each);
636     }
637
638   if(err==LDAP_SIZELIMIT_EXCEEDED)
639     fprintf(console,"gpgkeys: search results exceeded server limit.  First %d results shown.\n",count);
640
641   free_keylist(dupelist);
642   dupelist=NULL;
643
644   if(count<1)
645     fprintf(output,"info:1:0\n");
646   else
647     {
648       fprintf(output,"info:1:%d\n",count);
649
650       each=ldap_first_entry(ldap,res);
651       while(each!=NULL)
652         {
653           char **certid;
654
655           certid=ldap_get_values(ldap,each,"pgpcertid");
656           if(certid!=NULL)
657             {
658               LDAPMessage *uids;
659
660               /* Have we seen this certid before? */
661               if(!key_in_keylist(certid[0],dupelist))
662                 {
663                   int rc=add_key_to_keylist(certid[0],&dupelist);
664                   if(rc)
665                     {
666                       fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
667                       free_keylist(dupelist);
668                       ldap_value_free(certid);
669                       ldap_msgfree(res);
670                       return rc;
671                     }
672
673                   fprintf(output,"pub:%s:",certid[0]);
674
675                   vals=ldap_get_values(ldap,each,"pgpkeytype");
676                   if(vals!=NULL)
677                     {
678                       /* The LDAP server doesn't exactly handle this
679                          well. */
680                       if(strcasecmp(vals[0],"RSA")==0)
681                         fprintf(output,"1");
682                       else if(strcasecmp(vals[0],"DSS/DH")==0)
683                         fprintf(output,"17");
684                       ldap_value_free(vals);
685                     }
686
687                   fputc(':',output);
688
689                   vals=ldap_get_values(ldap,each,"pgpkeysize");
690                   if(vals!=NULL)
691                     {
692                       /* Not sure why, but some keys are listed with a
693                          key size of 0.  Treat that like an
694                          unknown. */
695                       if(atoi(vals[0])>0)
696                         fprintf(output,"%d",atoi(vals[0]));
697                       ldap_value_free(vals);
698                     }
699
700                   fputc(':',output);
701
702                   /* YYYYMMDDHHmmssZ */
703
704                   vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
705                   if(vals!=NULL && strlen(vals[0])==15)
706                     {
707                       fprintf(output,"%u",
708                               (unsigned int)ldap2epochtime(vals[0]));
709                       ldap_value_free(vals);
710                     }
711
712                   fputc(':',output);
713
714                   vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
715                   if(vals!=NULL && strlen(vals[0])==15)
716                     {
717                       fprintf(output,"%u",
718                               (unsigned int)ldap2epochtime(vals[0]));
719                       ldap_value_free(vals);
720                     }
721
722                   fputc(':',output);
723
724                   vals=ldap_get_values(ldap,each,"pgprevoked");
725                   if(vals!=NULL)
726                     {
727                       if(atoi(vals[0])==1)
728                         fprintf(output,"r");
729                       ldap_value_free(vals);
730                     }
731
732                   vals=ldap_get_values(ldap,each,"pgpdisabled");
733                   if(vals!=NULL)
734                     {
735                       if(atoi(vals[0])==1)
736                         fprintf(output,"d");
737                       ldap_value_free(vals);
738                     }
739
740 #if 0
741                   /* This is not yet specified in the keyserver
742                      protocol, but may be someday. */
743                   fputc(':',output);
744
745                   vals=ldap_get_values(ldap,each,"modifytimestamp");
746                   if(vals!=NULL && strlen(vals[0])==15)
747                     {
748                       fprintf(output,"%u",
749                               (unsigned int)ldap2epochtime(vals[0]));
750                       ldap_value_free(vals);
751                     }
752 #endif
753
754                   fprintf(output,"\n");
755
756                   /* Now print all the uids that have this certid */
757                   uids=ldap_first_entry(ldap,res);
758                   while(uids!=NULL)
759                     {
760                       vals=ldap_get_values(ldap,uids,"pgpcertid");
761                       if(vals!=NULL)
762                         {
763                           if(strcasecmp(certid[0],vals[0])==0)
764                             {
765                               char **uidvals;
766
767                               fprintf(output,"uid:");
768
769                               uidvals=ldap_get_values(ldap,uids,"pgpuserid");
770                               if(uidvals!=NULL)
771                                 {
772                                   /* Need to escape any colons */
773                                   printquoted(output,uidvals[0],':');
774                                   ldap_value_free(uidvals);
775                                 }
776
777                               fprintf(output,"\n");
778                             }
779
780                           ldap_value_free(vals);
781                         }
782
783                       uids=ldap_next_entry(ldap,uids);
784                     }
785                 }
786
787               ldap_value_free(certid);
788             }
789
790           each=ldap_next_entry(ldap,each);
791         }
792     }
793
794   ldap_msgfree(res);
795   free_keylist(dupelist);
796
797   fprintf(output,"SEARCH %s END\n",searchkey);
798
799   return KEYSERVER_OK;
800 }
801
802 void
803 fail_all(struct keylist *keylist,int action,int err)
804 {
805   if(!keylist)
806     return;
807
808   if(action==SEARCH)
809     {
810       fprintf(output,"SEARCH ");
811       while(keylist)
812         {
813           fprintf(output,"%s ",keylist->str);
814           keylist=keylist->next;
815         }
816       fprintf(output,"FAILED %d\n",err);
817     }
818   else
819     while(keylist)
820       {
821         fprintf(output,"KEY %s FAILED %d\n",keylist->str,err);
822         keylist=keylist->next;
823       }
824 }
825
826 static int
827 find_basekeyspacedn(void)
828 {
829   int err,i;
830   char *attr[]={"namingContexts",NULL,NULL,NULL};
831   LDAPMessage *res;
832   char **context;
833
834   /* Look for namingContexts */
835   err=ldap_search_s(ldap,"",LDAP_SCOPE_BASE,"(objectClass=*)",attr,0,&res);
836   if(err==LDAP_SUCCESS)
837     {
838       context=ldap_get_values(ldap,res,"namingContexts");
839       if(context)
840         {
841           attr[0]="pgpBaseKeySpaceDN";
842           attr[1]="pgpVersion";
843           attr[2]="pgpSoftware";
844
845           real_ldap=1;
846
847           /* We found some, so try each namingContext as the search base
848              and look for pgpBaseKeySpaceDN.  Because we found this, we
849              know we're talking to a regular-ish LDAP server and not a
850              LDAP keyserver. */
851
852           for(i=0;context[i] && !basekeyspacedn;i++)
853             {
854               char **vals;
855               LDAPMessage *si_res;
856               err=ldap_search_s(ldap,context[i],LDAP_SCOPE_ONELEVEL,
857                                 "(cn=pgpServerInfo)",attr,0,&si_res);
858               if(err!=LDAP_SUCCESS)
859                 return err;
860
861               vals=ldap_get_values(ldap,si_res,"pgpBaseKeySpaceDN");
862               if(vals)
863                 {
864                   /* This is always "OU=ACTIVE,O=PGP KEYSPACE,C=US", but
865                      it might not be in the future. */
866
867                   basekeyspacedn=strdup(vals[0]);
868                   ldap_value_free(vals);
869                 }
870
871               if(verbose>1)
872                 {
873                   vals=ldap_get_values(ldap,si_res,"pgpSoftware");
874                   if(vals)
875                     {
876                       fprintf(console,"Server: \t%s\n",vals[0]);
877                       ldap_value_free(vals);
878                     }
879
880                   vals=ldap_get_values(ldap,si_res,"pgpVersion");
881                   if(vals)
882                     {
883                       fprintf(console,"Version:\t%s\n",vals[0]);
884                       ldap_value_free(vals);
885                     }
886                 }
887
888               ldap_msgfree(si_res);
889             }
890
891           ldap_value_free(context);
892         }
893
894       ldap_msgfree(res);
895     }
896   else
897     {
898       /* We don't have an answer yet, which means the server might be
899          a LDAP keyserver. */
900       char **vals;
901       LDAPMessage *si_res;
902
903       attr[0]="pgpBaseKeySpaceDN";
904       attr[1]="version";
905       attr[2]="software";
906
907       err=ldap_search_s(ldap,"cn=pgpServerInfo",LDAP_SCOPE_BASE,
908                         "(objectClass=*)",attr,0,&si_res);
909       if(err!=LDAP_SUCCESS)
910         return err;
911
912       vals=ldap_get_values(ldap,si_res,"baseKeySpaceDN");
913       if(vals)
914         {
915           basekeyspacedn=strdup(vals[0]);
916           ldap_value_free(vals);
917         }
918
919       if(verbose>1)
920         {
921           vals=ldap_get_values(ldap,si_res,"software");
922           if(vals)
923             {
924               fprintf(console,"Server: \t%s\n",vals[0]);
925               ldap_value_free(vals);
926             }
927         }
928
929       vals=ldap_get_values(ldap,si_res,"version");
930       if(vals)
931         {
932           if(verbose>1)
933             fprintf(console,"Version:\t%s\n",vals[0]);
934
935           /* If the version is high enough, use the new pgpKeyV2
936              attribute.  This design if iffy at best, but it matches how
937              PGP does it.  I figure the NAI folks assumed that there would
938              never be a LDAP keyserver vendor with a different numbering
939              scheme. */
940           if(atoi(vals[0])>1)
941             pgpkeystr="pgpKeyV2";
942
943           ldap_value_free(vals);
944         }
945
946       ldap_msgfree(si_res);
947     }   
948
949   return LDAP_SUCCESS;
950 }
951
952 int
953 main(int argc,char *argv[])
954 {
955   int port=0,arg,err,action=-1,ret=KEYSERVER_INTERNAL_ERROR;
956   char line[MAX_LINE];
957   int version,failed=0,use_ssl=0,use_tls=0;
958   struct keylist *keylist=NULL,*keyptr=NULL;
959
960   console=stderr;
961
962   while((arg=getopt(argc,argv,"hVo:"))!=-1)
963     switch(arg)
964       {
965       default:
966       case 'h':
967         fprintf(console,"-h\thelp\n");
968         fprintf(console,"-V\tversion\n");
969         fprintf(console,"-o\toutput to this file\n");
970         return KEYSERVER_OK;
971
972       case 'V':
973         fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
974         return KEYSERVER_OK;
975
976       case 'o':
977         output=fopen(optarg,"w");
978         if(output==NULL)
979           {
980             fprintf(console,"gpgkeys: Cannot open output file \"%s\": %s\n",
981                     optarg,strerror(errno));
982             return KEYSERVER_INTERNAL_ERROR;
983           }
984
985         break;
986       }
987
988   if(argc>optind)
989     {
990       input=fopen(argv[optind],"r");
991       if(input==NULL)
992         {
993           fprintf(console,"gpgkeys: Cannot open input file \"%s\": %s\n",
994                   argv[optind],strerror(errno));
995           return KEYSERVER_INTERNAL_ERROR;
996         }
997     }
998
999   if(input==NULL)
1000     input=stdin;
1001
1002   if(output==NULL)
1003     output=stdout;
1004
1005   /* Get the command and info block */
1006
1007   while(fgets(line,MAX_LINE,input)!=NULL)
1008     {
1009       char commandstr[7];
1010       char optionstr[30];
1011       char schemestr[80];
1012       char hash;
1013
1014       if(line[0]=='\n')
1015         break;
1016
1017       if(sscanf(line,"%c",&hash)==1 && hash=='#')
1018         continue;
1019
1020       if(sscanf(line,"COMMAND %6s\n",commandstr)==1)
1021         {
1022           commandstr[6]='\0';
1023
1024           if(strcasecmp(commandstr,"get")==0)
1025             action=GET;
1026           else if(strcasecmp(commandstr,"send")==0)
1027             action=SEND;
1028           else if(strcasecmp(commandstr,"search")==0)
1029             action=SEARCH;
1030
1031           continue;
1032         }
1033
1034       if(sscanf(line,"HOST %79s\n",host)==1)
1035         {
1036           host[79]='\0';
1037           continue;
1038         }
1039
1040       if(sscanf(line,"PORT %9s\n",portstr)==1)
1041         {
1042           portstr[9]='\0';
1043           port=atoi(portstr);
1044           continue;
1045         }
1046
1047       if(sscanf(line,"SCHEME %79s\n",schemestr)==1)
1048         {
1049           schemestr[79]='\0';
1050           if(strcasecmp(schemestr,"ldaps")==0)
1051             {
1052               port=636;
1053               use_ssl=1;
1054             }
1055           continue;
1056         }
1057
1058       if(sscanf(line,"VERSION %d\n",&version)==1)
1059         {
1060           if(version!=KEYSERVER_PROTO_VERSION)
1061             {
1062               ret=KEYSERVER_VERSION_ERROR;
1063               goto fail;
1064             }
1065
1066           continue;
1067         }
1068
1069       if(sscanf(line,"OPTION %29s\n",optionstr)==1)
1070         {
1071           int no=0;
1072           char *start=&optionstr[0];
1073
1074           optionstr[29]='\0';
1075
1076           if(strncasecmp(optionstr,"no-",3)==0)
1077             {
1078               no=1;
1079               start=&optionstr[3];
1080             }
1081
1082           if(strcasecmp(start,"verbose")==0)
1083             {
1084               if(no)
1085                 verbose--;
1086               else
1087                 verbose++;
1088             }
1089           else if(strcasecmp(start,"include-disabled")==0)
1090             {
1091               if(no)
1092                 include_disabled=0;
1093               else
1094                 include_disabled=1;
1095             }
1096           else if(strcasecmp(start,"include-revoked")==0)
1097             {
1098               if(no)
1099                 include_revoked=0;
1100               else
1101                 include_revoked=1;
1102             }
1103           else if(strcasecmp(start,"include-subkeys")==0)
1104             {
1105               if(no)
1106                 include_subkeys=0;
1107               else
1108                 include_subkeys=1;
1109             }
1110           else if(strncasecmp(start,"tls",3)==0)
1111             {
1112               if(no)
1113                 use_tls=0;
1114               else if(start[3]=='=')
1115                 {
1116                   if(strcasecmp(&start[4],"no")==0)
1117                     use_tls=0;
1118                   else if(strcasecmp(&start[4],"try")==0)
1119                     use_tls=1;
1120                   else if(strcasecmp(&start[4],"warn")==0)
1121                     use_tls=2;
1122                   else if(strcasecmp(&start[4],"require")==0)
1123                     use_tls=3;
1124                   else
1125                     use_tls=1;
1126                 }
1127               else if(start[3]=='\0')
1128                 use_tls=1;
1129             }
1130
1131           continue;
1132         }
1133     }
1134
1135   /* If it's a GET or a SEARCH, the next thing to come in is the
1136      keyids.  If it's a SEND, then there are no keyids. */
1137
1138   if(action==SEND)
1139     while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
1140   else if(action==GET || action==SEARCH)
1141     {
1142       for(;;)
1143         {
1144           struct keylist *work;
1145
1146           if(fgets(line,MAX_LINE,input)==NULL)
1147             break;
1148           else
1149             {
1150               if(line[0]=='\n' || line[0]=='\0')
1151                 break;
1152
1153               work=malloc(sizeof(struct keylist));
1154               if(work==NULL)
1155                 {
1156                   fprintf(console,"gpgkeys: out of memory while "
1157                           "building key list\n");
1158                   ret=KEYSERVER_NO_MEMORY;
1159                   goto fail;
1160                 }
1161
1162               strcpy(work->str,line);
1163
1164               /* Trim the trailing \n */
1165               work->str[strlen(line)-1]='\0';
1166
1167               work->next=NULL;
1168
1169               /* Always attach at the end to keep the list in proper
1170                  order for searching */
1171               if(keylist==NULL)
1172                 keylist=work;
1173               else
1174                 keyptr->next=work;
1175
1176               keyptr=work;
1177             }
1178         }
1179     }
1180   else
1181     {
1182       fprintf(console,"gpgkeys: no keyserver command specified\n");
1183       goto fail;
1184     }
1185
1186   /* Send the response */
1187
1188   fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
1189   fprintf(output,"PROGRAM %s\n\n",VERSION);
1190
1191   if(verbose>1)
1192     {
1193       fprintf(console,"Host:\t\t%s\n",host);
1194       if(port)
1195         fprintf(console,"Port:\t\t%d\n",port);
1196       fprintf(console,"Command:\t%s\n",action==GET?"GET":
1197               action==SEND?"SEND":"SEARCH");
1198     }
1199
1200   /* Note that this tries all A records on a given host (or at least,
1201      OpenLDAP does). */
1202   ldap=ldap_init(host,port);
1203   if(ldap==NULL)
1204     {
1205       fprintf(console,"gpgkeys: internal LDAP init error: %s\n",
1206               strerror(errno));
1207       fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1208       goto fail;
1209     }
1210
1211   if(use_ssl)
1212     {
1213       if(!real_ldap)
1214         {
1215           fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
1216                   "not supported by the NAI LDAP keyserver");
1217           fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1218           goto fail;
1219         }
1220       else
1221         {
1222 #if defined(LDAP_OPT_X_TLS_HARD) && defined(HAVE_LDAP_SET_OPTION)
1223           int ssl=LDAP_OPT_X_TLS_HARD;
1224           err=ldap_set_option(ldap,LDAP_OPT_X_TLS,&ssl);
1225           if(err!=LDAP_SUCCESS)
1226             {
1227               fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
1228                       ldap_err2string(err));
1229               fail_all(keylist,action,ldap_err_to_gpg_err(err));
1230               goto fail;
1231             }
1232 #else
1233           fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
1234                   "not built with LDAPS support");
1235           fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1236           goto fail;
1237 #endif
1238         }
1239     }
1240
1241   if((err=find_basekeyspacedn()))
1242     {
1243       fprintf(console,"gpgkeys: unable to retrieve LDAP base: %s\n",
1244               ldap_err2string(err));
1245       fail_all(keylist,action,ldap_err_to_gpg_err(err));
1246       goto fail;
1247     }
1248
1249   /* use_tls: 0=don't use, 1=try silently to use, 2=try loudly to use,
1250      3=force use. */
1251   if(use_tls)
1252     {
1253       if(!real_ldap)
1254         {
1255           if(use_tls>=2)
1256             fprintf(console,"gpgkeys: unable to start TLS: %s\n",
1257                     "not supported by the NAI LDAP keyserver");
1258           if(use_tls==3)
1259             {
1260               fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1261               goto fail;
1262             }
1263         }
1264       else
1265         {
1266 #if defined(HAVE_LDAP_START_TLS_S) && defined(HAVE_LDAP_SET_OPTION)
1267           int ver=LDAP_VERSION3;
1268
1269           err=LDAP_SUCCESS;
1270
1271           err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
1272           if(err==LDAP_SUCCESS)
1273             err=ldap_start_tls_s(ldap,NULL,NULL);
1274
1275           if(err!=LDAP_SUCCESS && use_tls>=2)
1276             {
1277               fprintf(console,"gpgkeys: unable to start TLS: %s\n",
1278                       ldap_err2string(err));
1279               /* Are we forcing it? */
1280               if(use_tls==3)
1281                 {
1282                   fail_all(keylist,action,ldap_err_to_gpg_err(err));
1283                   goto fail;
1284                 }
1285             }
1286           else if(verbose>1)
1287             fprintf(console,"gpgkeys: TLS started successfully.\n");
1288 #else
1289           if(use_tls>=2)
1290             fprintf(console,"gpgkeys: unable to start TLS: %s\n",
1291                     "not built with TLS support");
1292           if(use_tls==3)
1293             {
1294               fail_all(keylist,action,KEYSERVER_INTERNAL_ERROR);
1295               goto fail;
1296             }
1297 #endif
1298         }
1299     }
1300
1301   /* The LDAP keyserver doesn't require this, but it might be useful
1302      if someone stores keys on a V2 LDAP server somewhere.  (V3
1303      doesn't require a bind). */
1304
1305   err=ldap_simple_bind_s(ldap,NULL,NULL);
1306   if(err!=0)
1307     {
1308       fprintf(console,"gpgkeys: internal LDAP bind error: %s\n",
1309               ldap_err2string(err));
1310       fail_all(keylist,action,ldap_err_to_gpg_err(err));
1311       goto fail;
1312     }
1313
1314   switch(action)
1315     {
1316     case GET:
1317       keyptr=keylist;
1318
1319       while(keyptr!=NULL)
1320         {
1321           if(get_key(keyptr->str)!=KEYSERVER_OK)
1322             failed++;
1323
1324           keyptr=keyptr->next;
1325         }
1326       break;
1327
1328     case SEND:
1329       {
1330         int eof=0;
1331
1332         do
1333           {
1334             if(send_key(&eof)!=KEYSERVER_OK)
1335               failed++;
1336           }
1337         while(!eof);
1338       }
1339       break;
1340
1341     case SEARCH:
1342       {
1343         char *searchkey=NULL;
1344         int len=0;
1345
1346         /* To search, we stick a * in between each key to search for.
1347            This means that if the user enters words, they'll get
1348            "enters*words".  If the user "enters words", they'll get
1349            "enters words" */
1350
1351         keyptr=keylist;
1352         while(keyptr!=NULL)
1353           {
1354             len+=strlen(keyptr->str)+1;
1355             keyptr=keyptr->next;
1356           }
1357
1358         searchkey=malloc(len+1);
1359         if(searchkey==NULL)
1360           {
1361             ret=KEYSERVER_NO_MEMORY;
1362             fail_all(keylist,action,KEYSERVER_NO_MEMORY);
1363             goto fail;
1364           }
1365
1366         searchkey[0]='\0';
1367
1368         keyptr=keylist;
1369         while(keyptr!=NULL)
1370           {
1371             strcat(searchkey,keyptr->str);
1372             strcat(searchkey,"*");
1373             keyptr=keyptr->next;
1374           }
1375
1376         /* Nail that last "*" */
1377         if(*searchkey)
1378           searchkey[strlen(searchkey)-1]='\0';
1379
1380         if(search_key(searchkey)!=KEYSERVER_OK)
1381           failed++;
1382
1383         free(searchkey);
1384       }
1385
1386       break;
1387     }
1388
1389   if(!failed)
1390     ret=KEYSERVER_OK;
1391
1392  fail:
1393
1394   while(keylist!=NULL)
1395     {
1396       struct keylist *current=keylist;
1397       keylist=keylist->next;
1398       free(current);
1399     }
1400
1401   if(input!=stdin)
1402     fclose(input);
1403
1404   if(output!=stdout)
1405     fclose(output);
1406
1407   if(ldap!=NULL)
1408     ldap_unbind_s(ldap);
1409
1410   free(basekeyspacedn);
1411
1412   return ret;
1413 }