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