2006-09-06 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / keyserver / gpgkeys_ldap.c
blobb56cca1cfebcd4d22664ff6bc234174438c86f7e
1 /* gpgkeys_ldap.c - talk to a LDAP keyserver
2 * Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 #include <config.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <time.h>
26 #include <unistd.h>
27 #ifdef HAVE_GETOPT_H
28 #include <getopt.h>
29 #endif
30 #include <stdlib.h>
31 #include <errno.h>
33 #ifdef _WIN32
34 #include <winsock2.h>
35 #include <winldap.h>
36 #else
37 #ifdef NEED_LBER_H
38 #include <lber.h>
39 #endif
40 /* For OpenLDAP, to enable the API that we're using. */
41 #define LDAP_DEPRECATED 1
42 #include <ldap.h>
43 #endif
45 #include "util.h"
46 #include "keyserver.h"
47 #include "ksutil.h"
49 #ifdef __riscos__
50 #include "util.h"
51 #endif
53 extern char *optarg;
54 extern int optind;
56 static int real_ldap=0;
57 static char *basekeyspacedn=NULL;
58 static char *pgpkeystr="pgpKey";
59 static FILE *input=NULL,*output=NULL,*console=NULL;
60 static LDAP *ldap=NULL;
61 static struct ks_options *opt;
63 #ifndef HAVE_TIMEGM
64 time_t timegm(struct tm *tm);
65 #endif
67 static int
68 ldap_err_to_gpg_err(int err)
70 int ret;
72 switch(err)
74 case LDAP_ALREADY_EXISTS:
75 ret=KEYSERVER_KEY_EXISTS;
76 break;
78 case LDAP_SERVER_DOWN:
79 ret=KEYSERVER_UNREACHABLE;
80 break;
82 default:
83 ret=KEYSERVER_GENERAL_ERROR;
84 break;
87 return ret;
90 static int
91 ldap_to_gpg_err(LDAP *ld)
93 #if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
95 int err;
97 if(ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&err)==0)
98 return ldap_err_to_gpg_err(err);
99 else
100 return KEYSERVER_GENERAL_ERROR;
102 #elif defined(HAVE_LDAP_LD_ERRNO)
104 return ldap_err_to_gpg_err(ld->ld_errno);
106 #else
108 /* We should never get here since the LDAP library should always
109 have either ldap_get_option or ld_errno, but just in case... */
110 return KEYSERVER_GENERAL_ERROR;
112 #endif
115 static int
116 key_in_keylist(const char *key,struct keylist *list)
118 struct keylist *keyptr=list;
120 while(keyptr!=NULL)
122 if(strcasecmp(key,keyptr->str)==0)
123 return 1;
125 keyptr=keyptr->next;
128 return 0;
131 static int
132 add_key_to_keylist(const char *key,struct keylist **list)
134 struct keylist *keyptr=malloc(sizeof(struct keylist));
136 if(keyptr==NULL)
138 fprintf(console,"gpgkeys: out of memory when deduping "
139 "key list\n");
140 return KEYSERVER_NO_MEMORY;
143 strncpy(keyptr->str,key,MAX_LINE);
144 keyptr->str[MAX_LINE-1]='\0';
145 keyptr->next=*list;
146 *list=keyptr;
148 return 0;
151 static void
152 free_keylist(struct keylist *list)
154 while(list!=NULL)
156 struct keylist *keyptr=list;
158 list=keyptr->next;
159 free(keyptr);
163 static time_t
164 ldap2epochtime(const char *timestr)
166 struct tm pgptime;
167 time_t answer;
169 memset(&pgptime,0,sizeof(pgptime));
171 /* YYYYMMDDHHmmssZ */
173 sscanf(timestr,"%4d%2d%2d%2d%2d%2d",
174 &pgptime.tm_year,
175 &pgptime.tm_mon,
176 &pgptime.tm_mday,
177 &pgptime.tm_hour,
178 &pgptime.tm_min,
179 &pgptime.tm_sec);
181 pgptime.tm_year-=1900;
182 pgptime.tm_isdst=-1;
183 pgptime.tm_mon--;
185 /* mktime() takes the timezone into account, so we use timegm() */
187 answer=timegm(&pgptime);
189 return answer;
192 /* Caller must free */
193 static char *
194 epoch2ldaptime(time_t stamp)
196 struct tm *ldaptime;
197 char buf[16];
199 ldaptime=gmtime(&stamp);
201 ldaptime->tm_year+=1900;
202 ldaptime->tm_mon++;
204 /* YYYYMMDDHHmmssZ */
206 sprintf(buf,"%04d%02d%02d%02d%02d%02dZ",
207 ldaptime->tm_year,
208 ldaptime->tm_mon,
209 ldaptime->tm_mday,
210 ldaptime->tm_hour,
211 ldaptime->tm_min,
212 ldaptime->tm_sec);
214 return strdup(buf);
217 /* Append two onto the end of one. Two is not freed, but its pointers
218 are now part of one. Make sure you don't free them both! */
219 static int
220 join_two_modlists(LDAPMod ***one,LDAPMod **two)
222 int i,one_count=0,two_count=0;
223 LDAPMod **grow;
225 for(grow=*one;*grow;grow++)
226 one_count++;
228 for(grow=two;*grow;grow++)
229 two_count++;
231 grow=realloc(*one,sizeof(LDAPMod *)*(one_count+two_count+1));
232 if(!grow)
233 return 0;
235 for(i=0;i<two_count;i++)
236 grow[one_count+i]=two[i];
238 grow[one_count+i]=NULL;
240 *one=grow;
242 return 1;
245 /* Passing a NULL for value effectively deletes that attribute. This
246 doesn't mean "delete" in the sense of removing something from the
247 modlist, but "delete" in the LDAP sense of adding a modlist item
248 that specifies LDAP_MOD_REPLACE and a null attribute for the given
249 attribute. LDAP_MOD_DELETE doesn't work here as we don't know if
250 the attribute in question exists or not. */
252 static int
253 make_one_attr(LDAPMod ***modlist,char *attr,const char *value)
255 LDAPMod **m;
256 int nummods=0;
258 /* Search modlist for the attribute we're playing with. */
259 for(m=*modlist;*m;m++)
261 if(strcasecmp((*m)->mod_type,attr)==0)
263 char **ptr=(*m)->mod_values;
264 int numvalues=0;
266 /* We have this attribute already, so when the REPLACE
267 happens, the server attributes will be replaced
268 anyway. */
269 if(!value)
270 return 1;
272 if(ptr)
273 for(ptr=(*m)->mod_values;*ptr;ptr++)
275 /* Duplicate value */
276 if(strcmp(*ptr,value)==0)
277 return 1;
278 numvalues++;
281 ptr=realloc((*m)->mod_values,sizeof(char *)*(numvalues+2));
282 if(!ptr)
283 return 0;
285 (*m)->mod_values=ptr;
286 ptr[numvalues]=strdup(value);
287 if(!ptr[numvalues])
288 return 0;
290 ptr[numvalues+1]=NULL;
291 break;
294 nummods++;
297 /* We didn't find the attr, so make one and add it to the end */
298 if(!*m)
300 LDAPMod **grow;
302 grow=realloc(*modlist,sizeof(LDAPMod *)*(nummods+2));
303 if(!grow)
304 return 0;
306 *modlist=grow;
307 grow[nummods]=malloc(sizeof(LDAPMod));
308 if(!grow[nummods])
309 return 0;
310 grow[nummods]->mod_op=LDAP_MOD_REPLACE;
311 grow[nummods]->mod_type=attr;
312 if(value)
314 grow[nummods]->mod_values=malloc(sizeof(char *)*2);
315 if(!grow[nummods]->mod_values)
317 grow[nummods]=NULL;
318 return 0;
321 /* Is this the right thing? Can a UTF8-encoded user ID have
322 embedded nulls? */
323 grow[nummods]->mod_values[0]=strdup(value);
324 if(!grow[nummods]->mod_values[0])
326 free(grow[nummods]->mod_values);
327 grow[nummods]=NULL;
328 return 0;
331 grow[nummods]->mod_values[1]=NULL;
333 else
334 grow[nummods]->mod_values=NULL;
336 grow[nummods+1]=NULL;
339 return 1;
342 static void
343 build_attrs(LDAPMod ***modlist,char *line)
345 char *record;
346 int i;
348 /* Remove trailing whitespace */
349 for(i=strlen(line);i>0;i--)
350 if(ascii_isspace(line[i-1]))
351 line[i-1]='\0';
352 else
353 break;
355 if((record=strsep(&line,":"))==NULL)
356 return;
358 if(ascii_strcasecmp("pub",record)==0)
360 char *tok;
361 int disabled=0,revoked=0;
363 /* The long keyid */
364 if((tok=strsep(&line,":"))==NULL)
365 return;
367 if(strlen(tok)==16)
369 make_one_attr(modlist,"pgpCertID",tok);
370 make_one_attr(modlist,"pgpKeyID",&tok[8]);
372 else
373 return;
375 /* The primary pubkey algo */
376 if((tok=strsep(&line,":"))==NULL)
377 return;
379 switch(atoi(tok))
381 case 1:
382 make_one_attr(modlist,"pgpKeyType","RSA");
383 break;
385 case 17:
386 make_one_attr(modlist,"pgpKeyType","DSS/DH");
387 break;
390 /* Size of primary key */
391 if((tok=strsep(&line,":"))==NULL)
392 return;
394 if(atoi(tok)>0)
396 char padded[6];
397 int val=atoi(tok);
399 /* We zero pad this on the left to make PGP happy. */
401 if(val<99999 && val>0)
403 sprintf(padded,"%05u",atoi(tok));
404 make_one_attr(modlist,"pgpKeySize",padded);
408 /* pk timestamp */
409 if((tok=strsep(&line,":"))==NULL)
410 return;
412 if(atoi(tok)>0)
414 char *stamp=epoch2ldaptime(atoi(tok));
415 if(stamp)
417 make_one_attr(modlist,"pgpKeyCreateTime",stamp);
418 free(stamp);
422 /* pk expire */
423 if((tok=strsep(&line,":"))==NULL)
424 return;
426 if(atoi(tok)>0)
428 char *stamp=epoch2ldaptime(atoi(tok));
429 if(stamp)
431 make_one_attr(modlist,"pgpKeyExpireTime",stamp);
432 free(stamp);
436 /* flags */
437 if((tok=strsep(&line,":"))==NULL)
438 return;
440 while(*tok)
441 switch(*tok++)
443 case 'r':
444 case 'R':
445 revoked=1;
446 break;
448 case 'd':
449 case 'D':
450 disabled=1;
451 break;
455 Note that we always create the pgpDisabled and pgpRevoked
456 attributes, regardless of whether the key is disabled/revoked
457 or not. This is because a very common search is like
458 "(&(pgpUserID=*isabella*)(pgpDisabled=0))"
461 make_one_attr(modlist,"pgpDisabled",disabled?"1":"0");
462 make_one_attr(modlist,"pgpRevoked",revoked?"1":"0");
464 else if(ascii_strcasecmp("sub",record)==0)
466 char *tok;
468 /* The long keyid */
469 if((tok=strsep(&line,":"))==NULL)
470 return;
472 if(strlen(tok)==16)
473 make_one_attr(modlist,"pgpSubKeyID",tok);
474 else
475 return;
477 /* The subkey algo */
478 if((tok=strsep(&line,":"))==NULL)
479 return;
481 /* Size of subkey */
482 if((tok=strsep(&line,":"))==NULL)
483 return;
485 if(atoi(tok)>0)
487 char padded[6];
488 int val=atoi(tok);
490 /* We zero pad this on the left to make PGP happy. */
492 if(val<99999 && val>0)
494 sprintf(padded,"%05u",atoi(tok));
495 make_one_attr(modlist,"pgpKeySize",padded);
499 /* Ignore the rest of the items for subkeys since the LDAP
500 schema doesn't store them. */
502 else if(ascii_strcasecmp("uid",record)==0)
504 char *userid,*tok;
506 /* The user ID string */
507 if((tok=strsep(&line,":"))==NULL)
508 return;
510 if(strlen(tok)==0)
511 return;
513 userid=tok;
515 /* By definition, de-%-encoding is always smaller than the
516 original string so we can decode in place. */
518 i=0;
520 while(*tok)
521 if(tok[0]=='%' && tok[1] && tok[2])
523 if((userid[i]=hextobyte(&tok[1]))==-1)
524 userid[i]='?';
526 i++;
527 tok+=3;
529 else
530 userid[i++]=*tok++;
532 userid[i]='\0';
534 /* We don't care about the other info provided in the uid: line
535 since the LDAP schema doesn't need it. */
537 make_one_attr(modlist,"pgpUserID",userid);
539 else if(ascii_strcasecmp("sig",record)==0)
541 char *tok;
543 if((tok=strsep(&line,":"))==NULL)
544 return;
546 if(strlen(tok)==16)
547 make_one_attr(modlist,"pgpSignerID",tok);
551 static void
552 free_mod_values(LDAPMod *mod)
554 char **ptr;
556 if(!mod->mod_values)
557 return;
559 for(ptr=mod->mod_values;*ptr;ptr++)
560 free(*ptr);
562 free(mod->mod_values);
565 static int
566 send_key(int *eof)
568 int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
569 char *dn=NULL,line[MAX_LINE],*key=NULL;
570 char keyid[17],state[6];
571 LDAPMod **modlist,**addlist,**ml;
573 modlist=malloc(sizeof(LDAPMod *));
574 if(!modlist)
576 fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
577 ret=KEYSERVER_NO_MEMORY;
578 goto fail;
581 *modlist=NULL;
583 addlist=malloc(sizeof(LDAPMod *));
584 if(!addlist)
586 fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
587 ret=KEYSERVER_NO_MEMORY;
588 goto fail;
591 *addlist=NULL;
593 /* Start by nulling out all attributes. We try and do a modify
594 operation first, so this ensures that we don't leave old
595 attributes lying around. */
596 make_one_attr(&modlist,"pgpDisabled",NULL);
597 make_one_attr(&modlist,"pgpKeyID",NULL);
598 make_one_attr(&modlist,"pgpKeyType",NULL);
599 make_one_attr(&modlist,"pgpUserID",NULL);
600 make_one_attr(&modlist,"pgpKeyCreateTime",NULL);
601 make_one_attr(&modlist,"pgpSignerID",NULL);
602 make_one_attr(&modlist,"pgpRevoked",NULL);
603 make_one_attr(&modlist,"pgpSubKeyID",NULL);
604 make_one_attr(&modlist,"pgpKeySize",NULL);
605 make_one_attr(&modlist,"pgpKeyExpireTime",NULL);
606 make_one_attr(&modlist,"pgpCertID",NULL);
608 /* Assemble the INFO stuff into LDAP attributes */
610 while(fgets(line,MAX_LINE,input)!=NULL)
611 if(sscanf(line,"INFO%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
612 && strcmp(state,"BEGIN")==0)
614 begin=1;
615 break;
618 if(!begin)
620 /* i.e. eof before the INFO BEGIN was found. This isn't an
621 error. */
622 *eof=1;
623 ret=KEYSERVER_OK;
624 goto fail;
627 if(strlen(keyid)!=16)
629 *eof=1;
630 ret=KEYSERVER_KEY_INCOMPLETE;
631 goto fail;
634 dn=malloc(strlen("pgpCertID=")+16+1+strlen(basekeyspacedn)+1);
635 if(dn==NULL)
637 fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
638 ret=KEYSERVER_NO_MEMORY;
639 goto fail;
642 sprintf(dn,"pgpCertID=%s,%s",keyid,basekeyspacedn);
644 key=malloc(1);
645 if(!key)
647 fprintf(console,"gpgkeys: unable to allocate memory for key\n");
648 ret=KEYSERVER_NO_MEMORY;
649 goto fail;
652 key[0]='\0';
654 /* Now parse each line until we see the END */
656 while(fgets(line,MAX_LINE,input)!=NULL)
657 if(sscanf(line,"INFO%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
658 && strcmp(state,"END")==0)
660 end=1;
661 break;
663 else
664 build_attrs(&addlist,line);
666 if(!end)
668 fprintf(console,"gpgkeys: no INFO %s END found\n",keyid);
669 *eof=1;
670 ret=KEYSERVER_KEY_INCOMPLETE;
671 goto fail;
674 begin=end=0;
676 /* Read and throw away stdin until we see the BEGIN */
678 while(fgets(line,MAX_LINE,input)!=NULL)
679 if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
680 && strcmp(state,"BEGIN")==0)
682 begin=1;
683 break;
686 if(!begin)
688 /* i.e. eof before the KEY BEGIN was found. This isn't an
689 error. */
690 *eof=1;
691 ret=KEYSERVER_OK;
692 goto fail;
695 /* Now slurp up everything until we see the END */
697 while(fgets(line,MAX_LINE,input)!=NULL)
698 if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
699 && strcmp(state,"END")==0)
701 end=1;
702 break;
704 else
706 char *tempkey;
707 keysize+=strlen(line);
708 tempkey=realloc(key,keysize);
709 if(tempkey==NULL)
711 fprintf(console,"gpgkeys: unable to reallocate for key\n");
712 ret=KEYSERVER_NO_MEMORY;
713 goto fail;
715 else
716 key=tempkey;
718 strcat(key,line);
721 if(!end)
723 fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
724 *eof=1;
725 ret=KEYSERVER_KEY_INCOMPLETE;
726 goto fail;
729 make_one_attr(&addlist,"objectClass","pgpKeyInfo");
730 make_one_attr(&addlist,"pgpKey",key);
732 /* Now append addlist onto modlist */
733 if(!join_two_modlists(&modlist,addlist))
735 fprintf(console,"gpgkeys: unable to merge LDAP modification lists\n");
736 ret=KEYSERVER_NO_MEMORY;
737 goto fail;
740 /* Going on the assumption that modify operations are more frequent
741 than adds, we try a modify first. If it's not there, we just
742 turn around and send an add command for the same key. Otherwise,
743 the modify brings the server copy into compliance with our copy.
744 Note that unlike the LDAP keyserver (and really, any other
745 keyserver) this does NOT merge signatures, but replaces the whole
746 key. This should make some people very happy. */
748 err=ldap_modify_s(ldap,dn,modlist);
749 if(err==LDAP_NO_SUCH_OBJECT)
750 err=ldap_add_s(ldap,dn,addlist);
752 if(err!=LDAP_SUCCESS)
754 fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
755 keyid,ldap_err2string(err));
756 ret=ldap_err_to_gpg_err(err);
757 goto fail;
760 ret=KEYSERVER_OK;
762 fail:
763 /* Unwind and free the whole modlist structure */
764 for(ml=modlist;*ml;ml++)
766 free_mod_values(*ml);
767 free(*ml);
770 free(modlist);
771 free(addlist);
772 free(dn);
774 if(ret!=0 && begin)
775 fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
777 return ret;
780 static int
781 send_key_keyserver(int *eof)
783 int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
784 char *dn=NULL,line[MAX_LINE],*key[2]={NULL,NULL};
785 char keyid[17],state[6];
786 LDAPMod mod, *attrs[2];
788 memset(&mod,0,sizeof(mod));
789 mod.mod_op=LDAP_MOD_ADD;
790 mod.mod_type=pgpkeystr;
791 mod.mod_values=key;
792 attrs[0]=&mod;
793 attrs[1]=NULL;
795 dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1);
796 if(dn==NULL)
798 fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
799 ret=KEYSERVER_NO_MEMORY;
800 goto fail;
803 strcpy(dn,"pgpCertid=virtual,");
804 strcat(dn,basekeyspacedn);
806 key[0]=malloc(1);
807 if(key[0]==NULL)
809 fprintf(console,"gpgkeys: unable to allocate memory for key\n");
810 ret=KEYSERVER_NO_MEMORY;
811 goto fail;
814 key[0][0]='\0';
816 /* Read and throw away stdin until we see the BEGIN */
818 while(fgets(line,MAX_LINE,input)!=NULL)
819 if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
820 && strcmp(state,"BEGIN")==0)
822 begin=1;
823 break;
826 if(!begin)
828 /* i.e. eof before the KEY BEGIN was found. This isn't an
829 error. */
830 *eof=1;
831 ret=KEYSERVER_OK;
832 goto fail;
835 /* Now slurp up everything until we see the END */
837 while(fgets(line,MAX_LINE,input)!=NULL)
838 if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
839 && strcmp(state,"END")==0)
841 end=1;
842 break;
844 else
846 keysize+=strlen(line);
847 key[0]=realloc(key[0],keysize);
848 if(key[0]==NULL)
850 fprintf(console,"gpgkeys: unable to reallocate for key\n");
851 ret=KEYSERVER_NO_MEMORY;
852 goto fail;
855 strcat(key[0],line);
858 if(!end)
860 fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
861 *eof=1;
862 ret=KEYSERVER_KEY_INCOMPLETE;
863 goto fail;
866 err=ldap_add_s(ldap,dn,attrs);
867 if(err!=LDAP_SUCCESS)
869 fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
870 keyid,ldap_err2string(err));
871 ret=ldap_err_to_gpg_err(err);
872 goto fail;
875 ret=KEYSERVER_OK;
877 fail:
879 free(key[0]);
880 free(dn);
882 if(ret!=0 && begin)
883 fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
885 /* Not a fatal error */
886 if(ret==KEYSERVER_KEY_EXISTS)
887 ret=KEYSERVER_OK;
889 return ret;
892 static void
893 build_info(const char *certid,LDAPMessage *each)
895 char **vals;
897 fprintf(output,"INFO %s BEGIN\n",certid);
899 fprintf(output,"pub:%s:",certid);
901 vals=ldap_get_values(ldap,each,"pgpkeytype");
902 if(vals!=NULL)
904 if(strcmp(vals[0],"RSA")==0)
905 fprintf(output,"1");
906 else if(strcmp(vals[0],"DSS/DH")==0)
907 fprintf(output,"17");
908 ldap_value_free(vals);
911 fprintf(output,":");
913 vals=ldap_get_values(ldap,each,"pgpkeysize");
914 if(vals!=NULL)
916 if(atoi(vals[0])>0)
917 fprintf(output,"%d",atoi(vals[0]));
918 ldap_value_free(vals);
921 fprintf(output,":");
923 vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
924 if(vals!=NULL)
926 if(strlen(vals[0])==15)
927 fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
928 ldap_value_free(vals);
931 fprintf(output,":");
933 vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
934 if(vals!=NULL)
936 if(strlen(vals[0])==15)
937 fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
938 ldap_value_free(vals);
941 fprintf(output,":");
943 vals=ldap_get_values(ldap,each,"pgprevoked");
944 if(vals!=NULL)
946 if(atoi(vals[0])==1)
947 fprintf(output,"r");
948 ldap_value_free(vals);
951 fprintf(output,"\n");
953 vals=ldap_get_values(ldap,each,"pgpuserid");
954 if(vals!=NULL)
956 int i;
958 for(i=0;vals[i];i++)
959 fprintf(output,"uid:%s\n",vals[i]);
960 ldap_value_free(vals);
963 fprintf(output,"INFO %s END\n",certid);
966 /* Note that key-not-found is not a fatal error */
967 static int
968 get_key(char *getkey)
970 LDAPMessage *res,*each;
971 int ret=KEYSERVER_INTERNAL_ERROR,err,count;
972 struct keylist *dupelist=NULL;
973 char search[62];
974 /* This ordering is significant - specifically, "pgpcertid" needs to
975 be the second item in the list, since everything after it may be
976 discarded if the user isn't in verbose mode. */
977 char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
978 "pgpdisabled","pgpkeycreatetime","modifytimestamp",
979 "pgpkeysize","pgpkeytype",NULL};
980 attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
981 array initializers. */
983 /* Build the search string */
985 /* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3
986 or v4 short key id */
988 if(strncmp(getkey,"0x",2)==0)
989 getkey+=2;
991 if(strlen(getkey)==32)
993 fprintf(console,
994 "gpgkeys: LDAP keyservers do not support v3 fingerprints\n");
995 fprintf(output,"KEY 0x%s BEGIN\n",getkey);
996 fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED);
997 return KEYSERVER_NOT_SUPPORTED;
1000 if(strlen(getkey)>16)
1002 char *offset=&getkey[strlen(getkey)-16];
1004 /* fingerprint. Take the last 16 characters and treat it like a
1005 long key id */
1007 if(opt->flags.include_subkeys)
1008 sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
1009 offset,offset);
1010 else
1011 sprintf(search,"(pgpcertid=%.16s)",offset);
1013 else if(strlen(getkey)>8)
1015 /* long key id */
1017 if(opt->flags.include_subkeys)
1018 sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
1019 getkey,getkey);
1020 else
1021 sprintf(search,"(pgpcertid=%.16s)",getkey);
1023 else
1025 /* short key id */
1027 sprintf(search,"(pgpkeyid=%.8s)",getkey);
1030 if(opt->verbose>2)
1031 fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
1033 if(!opt->verbose)
1034 attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
1036 err=ldap_search_s(ldap,basekeyspacedn,
1037 LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
1038 if(err!=0)
1040 int errtag=ldap_err_to_gpg_err(err);
1042 fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
1043 fprintf(output,"KEY 0x%s BEGIN\n",getkey);
1044 fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
1045 return errtag;
1048 count=ldap_count_entries(ldap,res);
1049 if(count<1)
1051 fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
1052 fprintf(output,"KEY 0x%s BEGIN\n",getkey);
1053 fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
1055 else
1057 /* There may be more than one unique result for a given keyID,
1058 so we should fetch them all (test this by fetching short key
1059 id 0xDEADBEEF). */
1061 each=ldap_first_entry(ldap,res);
1062 while(each!=NULL)
1064 char **vals,**certid;
1066 /* Use the long keyid to remove duplicates. The LDAP server
1067 returns the same keyid more than once if there are
1068 multiple user IDs on the key. Note that this does NOT
1069 mean that a keyid that exists multiple times on the
1070 keyserver will not be fetched. It means that each KEY,
1071 no matter how many user IDs share its keyid, will be
1072 fetched only once. If a keyid that belongs to more than
1073 one key is fetched, the server quite properly responds
1074 with all matching keys. -ds */
1076 certid=ldap_get_values(ldap,each,"pgpcertid");
1077 if(certid!=NULL)
1079 if(!key_in_keylist(certid[0],dupelist))
1081 /* it's not a duplicate, so add it */
1083 int rc=add_key_to_keylist(certid[0],&dupelist);
1084 if(rc)
1086 ret=rc;
1087 goto fail;
1090 build_info(certid[0],each);
1092 fprintf(output,"KEY 0x%s BEGIN\n",getkey);
1094 vals=ldap_get_values(ldap,each,pgpkeystr);
1095 if(vals==NULL)
1097 int errtag=ldap_to_gpg_err(ldap);
1099 fprintf(console,"gpgkeys: unable to retrieve key %s "
1100 "from keyserver\n",getkey);
1101 fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
1103 else
1105 print_nocr(output,vals[0]);
1106 fprintf(output,"\nKEY 0x%s END\n",getkey);
1108 ldap_value_free(vals);
1112 ldap_value_free(certid);
1115 each=ldap_next_entry(ldap,each);
1119 ret=KEYSERVER_OK;
1121 fail:
1122 ldap_msgfree(res);
1123 free_keylist(dupelist);
1125 return ret;
1128 #define LDAP_ESCAPE_CHARS "*()\\"
1130 /* Append string to buffer in a LDAP-quoted way */
1131 static void
1132 ldap_quote(char *buffer,const char *string)
1134 /* Find the end of buffer */
1135 buffer+=strlen(buffer);
1137 for(;*string;string++)
1139 if(strchr(LDAP_ESCAPE_CHARS,*string))
1141 sprintf(buffer,"\\%02X",*string);
1142 buffer+=3;
1144 else
1145 *buffer++=*string;
1148 *buffer='\0';
1151 /* Note that key-not-found is not a fatal error */
1152 static int
1153 get_name(char *getkey)
1155 LDAPMessage *res,*each;
1156 int ret=KEYSERVER_INTERNAL_ERROR,err,count;
1157 /* The maximum size of the search, including the optional stuff and
1158 the trailing \0 */
1159 char search[2+12+(MAX_LINE*3)+2+15+14+1+1+20];
1160 /* This ordering is significant - specifically, "pgpcertid" needs to
1161 be the second item in the list, since everything after it may be
1162 discarded if the user isn't in verbose mode. */
1163 char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
1164 "pgpdisabled","pgpkeycreatetime","modifytimestamp",
1165 "pgpkeysize","pgpkeytype",NULL};
1166 attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
1167 array initializers. */
1169 /* Build the search string */
1171 search[0]='\0';
1173 if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1174 strcat(search,"(&");
1176 strcat(search,"(pgpUserID=*");
1177 ldap_quote(search,getkey);
1178 strcat(search,"*)");
1180 if(!opt->flags.include_disabled)
1181 strcat(search,"(pgpDisabled=0)");
1183 if(!opt->flags.include_revoked)
1184 strcat(search,"(pgpRevoked=0)");
1186 if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1187 strcat(search,")");
1189 if(opt->verbose>2)
1190 fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
1192 if(!opt->verbose)
1193 attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
1195 err=ldap_search_s(ldap,basekeyspacedn,
1196 LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
1197 if(err!=0)
1199 int errtag=ldap_err_to_gpg_err(err);
1201 fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
1202 fprintf(output,"NAME %s BEGIN\n",getkey);
1203 fprintf(output,"NAME %s FAILED %d\n",getkey,errtag);
1204 return errtag;
1207 count=ldap_count_entries(ldap,res);
1208 if(count<1)
1210 fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
1211 fprintf(output,"NAME %s BEGIN\n",getkey);
1212 fprintf(output,"NAME %s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
1214 else
1216 /* There may be more than one result, but we return them all. */
1218 each=ldap_first_entry(ldap,res);
1219 while(each!=NULL)
1221 char **vals,**certid;
1223 certid=ldap_get_values(ldap,each,"pgpcertid");
1224 if(certid!=NULL)
1226 build_info(certid[0],each);
1228 fprintf(output,"NAME %s BEGIN\n",getkey);
1230 vals=ldap_get_values(ldap,each,pgpkeystr);
1231 if(vals==NULL)
1233 int errtag=ldap_to_gpg_err(ldap);
1235 fprintf(console,"gpgkeys: unable to retrieve key %s "
1236 "from keyserver\n",getkey);
1237 fprintf(output,"NAME %s FAILED %d\n",getkey,errtag);
1239 else
1241 print_nocr(output,vals[0]);
1242 fprintf(output,"\nNAME %s END\n",getkey);
1244 ldap_value_free(vals);
1247 ldap_value_free(certid);
1250 each=ldap_next_entry(ldap,each);
1254 ret=KEYSERVER_OK;
1256 ldap_msgfree(res);
1258 return ret;
1261 static void
1262 printquoted(FILE *stream,char *string,char delim)
1264 while(*string)
1266 if(*string==delim || *string=='%')
1267 fprintf(stream,"%%%02x",*string);
1268 else
1269 fputc(*string,stream);
1271 string++;
1275 /* Returns 0 on success and -1 on error. Note that key-not-found is
1276 not an error! */
1277 static int
1278 search_key(const char *searchkey)
1280 char **vals;
1281 LDAPMessage *res,*each;
1282 int err,count=0;
1283 struct keylist *dupelist=NULL;
1284 /* The maximum size of the search, including the optional stuff and
1285 the trailing \0 */
1286 char search[2+1+9+1+3+(MAX_LINE*3)+3+1+15+14+1+1+20];
1287 char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
1288 "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
1289 "pgpkeysize","pgpkeytype",NULL};
1290 enum ks_search_type search_type;
1292 fprintf(output,"SEARCH %s BEGIN\n",searchkey);
1294 search_type=classify_ks_search(&searchkey);
1296 if(opt->debug)
1297 fprintf(console,"search type is %d, and key is \"%s\"\n",
1298 search_type,searchkey);
1300 /* Build the search string */
1302 search[0]='\0';
1304 if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1305 strcat(search,"(&");
1307 strcat(search,"(");
1309 switch(search_type)
1311 case KS_SEARCH_KEYID_SHORT:
1312 strcat(search,"pgpKeyID");
1313 break;
1315 case KS_SEARCH_KEYID_LONG:
1316 strcat(search,"pgpCertID");
1317 break;
1319 default:
1320 strcat(search,"pgpUserID");
1321 break;
1324 strcat(search,"=");
1326 switch(search_type)
1328 case KS_SEARCH_SUBSTR:
1329 strcat(search,"*");
1330 break;
1332 case KS_SEARCH_MAIL:
1333 strcat(search,"*<");
1334 break;
1336 case KS_SEARCH_MAILSUB:
1337 strcat(search,"*<*");
1338 break;
1340 case KS_SEARCH_EXACT:
1341 case KS_SEARCH_KEYID_LONG:
1342 case KS_SEARCH_KEYID_SHORT:
1343 break;
1346 ldap_quote(search,searchkey);
1348 switch(search_type)
1350 case KS_SEARCH_SUBSTR:
1351 strcat(search,"*");
1352 break;
1354 case KS_SEARCH_MAIL:
1355 strcat(search,">*");
1356 break;
1358 case KS_SEARCH_MAILSUB:
1359 strcat(search,"*>*");
1360 break;
1362 case KS_SEARCH_EXACT:
1363 case KS_SEARCH_KEYID_LONG:
1364 case KS_SEARCH_KEYID_SHORT:
1365 break;
1368 strcat(search,")");
1370 if(!opt->flags.include_disabled)
1371 strcat(search,"(pgpDisabled=0)");
1373 if(!opt->flags.include_revoked)
1374 strcat(search,"(pgpRevoked=0)");
1376 if(!opt->flags.include_disabled || !opt->flags.include_revoked)
1377 strcat(search,")");
1379 if(opt->verbose>2)
1380 fprintf(console,"gpgkeys: LDAP search for: %s\n",search);
1382 err=ldap_search_s(ldap,basekeyspacedn,
1383 LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
1384 if(err!=LDAP_SUCCESS && err!=LDAP_SIZELIMIT_EXCEEDED)
1386 int errtag=ldap_err_to_gpg_err(err);
1388 fprintf(output,"SEARCH %s FAILED %d\n",searchkey,errtag);
1389 fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
1390 return errtag;
1393 /* The LDAP server doesn't return a real count of unique keys, so we
1394 can't use ldap_count_entries here. */
1395 each=ldap_first_entry(ldap,res);
1396 while(each!=NULL)
1398 char **certid=ldap_get_values(ldap,each,"pgpcertid");
1400 if(certid!=NULL)
1402 if(!key_in_keylist(certid[0],dupelist))
1404 int rc=add_key_to_keylist(certid[0],&dupelist);
1405 if(rc!=0)
1407 fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
1408 free_keylist(dupelist);
1409 return rc;
1412 count++;
1416 each=ldap_next_entry(ldap,each);
1419 if(err==LDAP_SIZELIMIT_EXCEEDED)
1421 if(count==1)
1422 fprintf(console,"gpgkeys: search results exceeded server limit."
1423 " First %d result shown.\n",count);
1424 else
1425 fprintf(console,"gpgkeys: search results exceeded server limit."
1426 " First %d results shown.\n",count);
1429 free_keylist(dupelist);
1430 dupelist=NULL;
1432 if(count<1)
1433 fprintf(output,"info:1:0\n");
1434 else
1436 fprintf(output,"info:1:%d\n",count);
1438 each=ldap_first_entry(ldap,res);
1439 while(each!=NULL)
1441 char **certid;
1443 certid=ldap_get_values(ldap,each,"pgpcertid");
1444 if(certid!=NULL)
1446 LDAPMessage *uids;
1448 /* Have we seen this certid before? */
1449 if(!key_in_keylist(certid[0],dupelist))
1451 int rc=add_key_to_keylist(certid[0],&dupelist);
1452 if(rc)
1454 fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
1455 free_keylist(dupelist);
1456 ldap_value_free(certid);
1457 ldap_msgfree(res);
1458 return rc;
1461 fprintf(output,"pub:%s:",certid[0]);
1463 vals=ldap_get_values(ldap,each,"pgpkeytype");
1464 if(vals!=NULL)
1466 /* The LDAP server doesn't exactly handle this
1467 well. */
1468 if(strcasecmp(vals[0],"RSA")==0)
1469 fprintf(output,"1");
1470 else if(strcasecmp(vals[0],"DSS/DH")==0)
1471 fprintf(output,"17");
1472 ldap_value_free(vals);
1475 fputc(':',output);
1477 vals=ldap_get_values(ldap,each,"pgpkeysize");
1478 if(vals!=NULL)
1480 /* Not sure why, but some keys are listed with a
1481 key size of 0. Treat that like an
1482 unknown. */
1483 if(atoi(vals[0])>0)
1484 fprintf(output,"%d",atoi(vals[0]));
1485 ldap_value_free(vals);
1488 fputc(':',output);
1490 /* YYYYMMDDHHmmssZ */
1492 vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
1493 if(vals!=NULL && strlen(vals[0])==15)
1495 fprintf(output,"%u",
1496 (unsigned int)ldap2epochtime(vals[0]));
1497 ldap_value_free(vals);
1500 fputc(':',output);
1502 vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
1503 if(vals!=NULL && strlen(vals[0])==15)
1505 fprintf(output,"%u",
1506 (unsigned int)ldap2epochtime(vals[0]));
1507 ldap_value_free(vals);
1510 fputc(':',output);
1512 vals=ldap_get_values(ldap,each,"pgprevoked");
1513 if(vals!=NULL)
1515 if(atoi(vals[0])==1)
1516 fprintf(output,"r");
1517 ldap_value_free(vals);
1520 vals=ldap_get_values(ldap,each,"pgpdisabled");
1521 if(vals!=NULL)
1523 if(atoi(vals[0])==1)
1524 fprintf(output,"d");
1525 ldap_value_free(vals);
1528 #if 0
1529 /* This is not yet specified in the keyserver
1530 protocol, but may be someday. */
1531 fputc(':',output);
1533 vals=ldap_get_values(ldap,each,"modifytimestamp");
1534 if(vals!=NULL && strlen(vals[0])==15)
1536 fprintf(output,"%u",
1537 (unsigned int)ldap2epochtime(vals[0]));
1538 ldap_value_free(vals);
1540 #endif
1542 fprintf(output,"\n");
1544 /* Now print all the uids that have this certid */
1545 uids=ldap_first_entry(ldap,res);
1546 while(uids!=NULL)
1548 vals=ldap_get_values(ldap,uids,"pgpcertid");
1549 if(vals!=NULL)
1551 if(strcasecmp(certid[0],vals[0])==0)
1553 char **uidvals;
1555 fprintf(output,"uid:");
1557 uidvals=ldap_get_values(ldap,uids,"pgpuserid");
1558 if(uidvals!=NULL)
1560 /* Need to escape any colons */
1561 printquoted(output,uidvals[0],':');
1562 ldap_value_free(uidvals);
1565 fprintf(output,"\n");
1568 ldap_value_free(vals);
1571 uids=ldap_next_entry(ldap,uids);
1575 ldap_value_free(certid);
1578 each=ldap_next_entry(ldap,each);
1582 ldap_msgfree(res);
1583 free_keylist(dupelist);
1585 fprintf(output,"SEARCH %s END\n",searchkey);
1587 return KEYSERVER_OK;
1590 static void
1591 fail_all(struct keylist *keylist,int err)
1593 if(!keylist)
1594 return;
1596 if(opt->action==KS_SEARCH)
1598 fprintf(output,"SEARCH ");
1599 while(keylist)
1601 fprintf(output,"%s ",keylist->str);
1602 keylist=keylist->next;
1604 fprintf(output,"FAILED %d\n",err);
1606 else
1607 while(keylist)
1609 fprintf(output,"KEY %s FAILED %d\n",keylist->str,err);
1610 keylist=keylist->next;
1614 static int
1615 find_basekeyspacedn(void)
1617 int err,i;
1618 char *attr[]={"namingContexts",NULL,NULL,NULL};
1619 LDAPMessage *res;
1620 char **context;
1622 /* Look for namingContexts */
1623 err=ldap_search_s(ldap,"",LDAP_SCOPE_BASE,"(objectClass=*)",attr,0,&res);
1624 if(err==LDAP_SUCCESS)
1626 context=ldap_get_values(ldap,res,"namingContexts");
1627 if(context)
1629 attr[0]="pgpBaseKeySpaceDN";
1630 attr[1]="pgpVersion";
1631 attr[2]="pgpSoftware";
1633 real_ldap=1;
1635 /* We found some, so try each namingContext as the search base
1636 and look for pgpBaseKeySpaceDN. Because we found this, we
1637 know we're talking to a regular-ish LDAP server and not a
1638 LDAP keyserver. */
1640 for(i=0;context[i] && !basekeyspacedn;i++)
1642 char **vals;
1643 LDAPMessage *si_res;
1644 char *object;
1646 object=malloc(17+strlen(context[i])+1);
1647 if(!object)
1648 return -1;
1650 strcpy(object,"cn=pgpServerInfo,");
1651 strcat(object,context[i]);
1653 err=ldap_search_s(ldap,object,LDAP_SCOPE_BASE,
1654 "(objectClass=*)",attr,0,&si_res);
1655 free(object);
1657 if(err==LDAP_NO_SUCH_OBJECT)
1658 continue;
1659 else if(err!=LDAP_SUCCESS)
1660 return err;
1662 vals=ldap_get_values(ldap,si_res,"pgpBaseKeySpaceDN");
1663 if(vals)
1665 basekeyspacedn=strdup(vals[0]);
1666 ldap_value_free(vals);
1669 if(opt->verbose>1)
1671 vals=ldap_get_values(ldap,si_res,"pgpSoftware");
1672 if(vals)
1674 fprintf(console,"Server: \t%s\n",vals[0]);
1675 ldap_value_free(vals);
1678 vals=ldap_get_values(ldap,si_res,"pgpVersion");
1679 if(vals)
1681 fprintf(console,"Version:\t%s\n",vals[0]);
1682 ldap_value_free(vals);
1686 ldap_msgfree(si_res);
1689 ldap_value_free(context);
1692 ldap_msgfree(res);
1694 else
1696 /* We don't have an answer yet, which means the server might be
1697 a LDAP keyserver. */
1698 char **vals;
1699 LDAPMessage *si_res;
1701 attr[0]="pgpBaseKeySpaceDN";
1702 attr[1]="version";
1703 attr[2]="software";
1705 err=ldap_search_s(ldap,"cn=pgpServerInfo",LDAP_SCOPE_BASE,
1706 "(objectClass=*)",attr,0,&si_res);
1707 if(err!=LDAP_SUCCESS)
1708 return err;
1710 /* For the LDAP keyserver, this is always "OU=ACTIVE,O=PGP
1711 KEYSPACE,C=US", but it might not be in the future. */
1713 vals=ldap_get_values(ldap,si_res,"baseKeySpaceDN");
1714 if(vals)
1716 basekeyspacedn=strdup(vals[0]);
1717 ldap_value_free(vals);
1720 if(opt->verbose>1)
1722 vals=ldap_get_values(ldap,si_res,"software");
1723 if(vals)
1725 fprintf(console,"Server: \t%s\n",vals[0]);
1726 ldap_value_free(vals);
1730 vals=ldap_get_values(ldap,si_res,"version");
1731 if(vals)
1733 if(opt->verbose>1)
1734 fprintf(console,"Version:\t%s\n",vals[0]);
1736 /* If the version is high enough, use the new pgpKeyV2
1737 attribute. This design if iffy at best, but it matches how
1738 PGP does it. I figure the NAI folks assumed that there would
1739 never be a LDAP keyserver vendor with a different numbering
1740 scheme. */
1741 if(atoi(vals[0])>1)
1742 pgpkeystr="pgpKeyV2";
1744 ldap_value_free(vals);
1747 ldap_msgfree(si_res);
1750 return LDAP_SUCCESS;
1753 static void
1754 show_help (FILE *fp)
1756 fprintf (fp,"-h\thelp\n");
1757 fprintf (fp,"-V\tversion\n");
1758 fprintf (fp,"-o\toutput to this file\n");
1762 main(int argc,char *argv[])
1764 int port=0,arg,err,ret=KEYSERVER_INTERNAL_ERROR;
1765 char line[MAX_LINE],*binddn=NULL,*bindpw=NULL;
1766 int failed=0,use_ssl=0,use_tls=0,bound=0;
1767 struct keylist *keylist=NULL,*keyptr=NULL;
1769 console=stderr;
1771 /* Kludge to implement standard GNU options. */
1772 if (argc > 1 && !strcmp (argv[1], "--version"))
1774 fputs ("gpgkeys_ldap (GnuPG) " VERSION"\n", stdout);
1775 return 0;
1777 else if (argc > 1 && !strcmp (argv[1], "--help"))
1779 show_help (stdout);
1780 return 0;
1783 while((arg=getopt(argc,argv,"hVo:"))!=-1)
1784 switch(arg)
1786 default:
1787 case 'h':
1788 show_help (console);
1789 return KEYSERVER_OK;
1791 case 'V':
1792 fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
1793 return KEYSERVER_OK;
1795 case 'o':
1796 output=fopen(optarg,"w");
1797 if(output==NULL)
1799 fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
1800 optarg,strerror(errno));
1801 return KEYSERVER_INTERNAL_ERROR;
1804 break;
1807 if(argc>optind)
1809 input=fopen(argv[optind],"r");
1810 if(input==NULL)
1812 fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
1813 argv[optind],strerror(errno));
1814 return KEYSERVER_INTERNAL_ERROR;
1818 if(input==NULL)
1819 input=stdin;
1821 if(output==NULL)
1822 output=stdout;
1824 opt=init_ks_options();
1825 if(!opt)
1826 return KEYSERVER_NO_MEMORY;
1828 /* Get the command and info block */
1830 while(fgets(line,MAX_LINE,input)!=NULL)
1832 char optionstr[MAX_OPTION+1];
1834 if(line[0]=='\n')
1835 break;
1837 err=parse_ks_options(line,opt);
1838 if(err>0)
1840 ret=err;
1841 goto fail;
1843 else if(err==0)
1844 continue;
1846 if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",optionstr)==1)
1848 int no=0;
1849 char *start=&optionstr[0];
1851 optionstr[MAX_OPTION]='\0';
1853 if(strncasecmp(optionstr,"no-",3)==0)
1855 no=1;
1856 start=&optionstr[3];
1859 if(strncasecmp(start,"tls",3)==0)
1861 if(no)
1862 use_tls=0;
1863 else if(start[3]=='=')
1865 if(strcasecmp(&start[4],"no")==0)
1866 use_tls=0;
1867 else if(strcasecmp(&start[4],"try")==0)
1868 use_tls=1;
1869 else if(strcasecmp(&start[4],"warn")==0)
1870 use_tls=2;
1871 else if(strcasecmp(&start[4],"require")==0)
1872 use_tls=3;
1873 else
1874 use_tls=1;
1876 else if(start[3]=='\0')
1877 use_tls=1;
1879 else if(strncasecmp(start,"basedn",6)==0)
1881 if(no)
1883 free(basekeyspacedn);
1884 basekeyspacedn=NULL;
1886 else if(start[6]=='=')
1888 free(basekeyspacedn);
1889 basekeyspacedn=strdup(&start[7]);
1890 if(!basekeyspacedn)
1892 fprintf(console,"gpgkeys: out of memory while creating "
1893 "base DN\n");
1894 ret=KEYSERVER_NO_MEMORY;
1895 goto fail;
1898 real_ldap=1;
1901 else if(strncasecmp(start,"binddn",6)==0)
1903 if(no)
1905 free(binddn);
1906 binddn=NULL;
1908 else if(start[6]=='=')
1910 free(binddn);
1911 binddn=strdup(&start[7]);
1912 if(!binddn)
1914 fprintf(console,"gpgkeys: out of memory while creating "
1915 "bind DN\n");
1916 ret=KEYSERVER_NO_MEMORY;
1917 goto fail;
1920 real_ldap=1;
1923 else if(strncasecmp(start,"bindpw",6)==0)
1925 if(no)
1927 free(bindpw);
1928 bindpw=NULL;
1930 else if(start[6]=='=')
1932 free(bindpw);
1933 bindpw=strdup(&start[7]);
1934 if(!bindpw)
1936 fprintf(console,"gpgkeys: out of memory while creating "
1937 "bind password\n");
1938 ret=KEYSERVER_NO_MEMORY;
1939 goto fail;
1942 real_ldap=1;
1946 continue;
1950 if(!opt->scheme)
1952 fprintf(console,"gpgkeys: no scheme supplied!\n");
1953 ret=KEYSERVER_SCHEME_NOT_FOUND;
1954 goto fail;
1957 if(strcasecmp(opt->scheme,"ldaps")==0)
1959 port=636;
1960 use_ssl=1;
1963 if(opt->port)
1964 port=atoi(opt->port);
1966 if(!opt->host)
1968 fprintf(console,"gpgkeys: no keyserver host provided\n");
1969 goto fail;
1972 if(opt->timeout && register_timeout()==-1)
1974 fprintf(console,"gpgkeys: unable to register timeout handler\n");
1975 return KEYSERVER_INTERNAL_ERROR;
1978 #if defined(LDAP_OPT_X_TLS_CACERTFILE) && defined(HAVE_LDAP_SET_OPTION)
1980 if(opt->ca_cert_file)
1982 err=ldap_set_option(NULL,LDAP_OPT_X_TLS_CACERTFILE,opt->ca_cert_file);
1983 if(err!=LDAP_SUCCESS)
1985 fprintf(console,"gpgkeys: unable to set ca-cert-file: %s\n",
1986 ldap_err2string(err));
1987 ret=KEYSERVER_INTERNAL_ERROR;
1988 goto fail;
1991 #endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */
1993 /* SSL trumps TLS */
1994 if(use_ssl)
1995 use_tls=0;
1997 /* If it's a GET or a SEARCH, the next thing to come in is the
1998 keyids. If it's a SEND, then there are no keyids. */
2000 if(opt->action==KS_SEND)
2001 while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
2002 else if(opt->action==KS_GET
2003 || opt->action==KS_GETNAME || opt->action==KS_SEARCH)
2005 for(;;)
2007 struct keylist *work;
2009 if(fgets(line,MAX_LINE,input)==NULL)
2010 break;
2011 else
2013 if(line[0]=='\n' || line[0]=='\0')
2014 break;
2016 work=malloc(sizeof(struct keylist));
2017 if(work==NULL)
2019 fprintf(console,"gpgkeys: out of memory while "
2020 "building key list\n");
2021 ret=KEYSERVER_NO_MEMORY;
2022 goto fail;
2025 strcpy(work->str,line);
2027 /* Trim the trailing \n */
2028 work->str[strlen(line)-1]='\0';
2030 work->next=NULL;
2032 /* Always attach at the end to keep the list in proper
2033 order for searching */
2034 if(keylist==NULL)
2035 keylist=work;
2036 else
2037 keyptr->next=work;
2039 keyptr=work;
2043 else
2045 fprintf(console,"gpgkeys: no keyserver command specified\n");
2046 goto fail;
2049 /* Send the response */
2051 fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
2052 fprintf(output,"PROGRAM %s\n\n",VERSION);
2054 if(opt->verbose>1)
2056 fprintf(console,"Host:\t\t%s\n",opt->host);
2057 if(port)
2058 fprintf(console,"Port:\t\t%d\n",port);
2059 fprintf(console,"Command:\t%s\n",ks_action_to_string(opt->action));
2062 if(opt->debug)
2064 #if defined(LDAP_OPT_DEBUG_LEVEL) && defined(HAVE_LDAP_SET_OPTION)
2065 err=ldap_set_option(NULL,LDAP_OPT_DEBUG_LEVEL,&opt->debug);
2066 if(err!=LDAP_SUCCESS)
2067 fprintf(console,"gpgkeys: unable to set debug mode: %s\n",
2068 ldap_err2string(err));
2069 else
2070 fprintf(console,"gpgkeys: debug level %d\n",opt->debug);
2071 #else
2072 fprintf(console,"gpgkeys: not built with debugging support\n");
2073 #endif
2076 /* We have a timeout set for the setup stuff since it could time out
2077 as well. */
2078 set_timeout(opt->timeout);
2080 /* Note that this tries all A records on a given host (or at least,
2081 OpenLDAP does). */
2082 ldap=ldap_init(opt->host,port);
2083 if(ldap==NULL)
2085 fprintf(console,"gpgkeys: internal LDAP init error: %s\n",
2086 strerror(errno));
2087 fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2088 goto fail;
2091 if(use_ssl)
2093 #if defined(LDAP_OPT_X_TLS) && defined(HAVE_LDAP_SET_OPTION)
2094 int ssl=LDAP_OPT_X_TLS_HARD;
2096 err=ldap_set_option(ldap,LDAP_OPT_X_TLS,&ssl);
2097 if(err!=LDAP_SUCCESS)
2099 fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
2100 ldap_err2string(err));
2101 fail_all(keylist,ldap_err_to_gpg_err(err));
2102 goto fail;
2105 if(!opt->flags.check_cert)
2106 ssl=LDAP_OPT_X_TLS_NEVER;
2108 err=ldap_set_option(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,&ssl);
2109 if(err!=LDAP_SUCCESS)
2111 fprintf(console,
2112 "gpgkeys: unable to set certificate validation: %s\n",
2113 ldap_err2string(err));
2114 fail_all(keylist,ldap_err_to_gpg_err(err));
2115 goto fail;
2117 #else
2118 fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
2119 "not built with LDAPS support");
2120 fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2121 goto fail;
2122 #endif
2125 if(!basekeyspacedn)
2126 if((err=find_basekeyspacedn()) || !basekeyspacedn)
2128 fprintf(console,"gpgkeys: unable to retrieve LDAP base: %s\n",
2129 err?ldap_err2string(err):"not found");
2130 fail_all(keylist,ldap_err_to_gpg_err(err));
2131 goto fail;
2134 /* use_tls: 0=don't use, 1=try silently to use, 2=try loudly to use,
2135 3=force use. */
2136 if(use_tls)
2138 if(!real_ldap)
2140 if(use_tls>=2)
2141 fprintf(console,"gpgkeys: unable to start TLS: %s\n",
2142 "not supported by the NAI LDAP keyserver");
2143 if(use_tls==3)
2145 fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2146 goto fail;
2149 else
2151 #if defined(HAVE_LDAP_START_TLS_S) && defined(HAVE_LDAP_SET_OPTION)
2152 int ver=LDAP_VERSION3;
2154 err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
2156 #ifdef LDAP_OPT_X_TLS
2157 if(err==LDAP_SUCCESS)
2159 if(opt->flags.check_cert)
2160 ver=LDAP_OPT_X_TLS_HARD;
2161 else
2162 ver=LDAP_OPT_X_TLS_NEVER;
2164 err=ldap_set_option(ldap,LDAP_OPT_X_TLS_REQUIRE_CERT,&ver);
2166 #endif
2168 if(err==LDAP_SUCCESS)
2169 err=ldap_start_tls_s(ldap,NULL,NULL);
2171 if(err!=LDAP_SUCCESS)
2173 if(use_tls>=2 || opt->verbose>2)
2174 fprintf(console,"gpgkeys: unable to start TLS: %s\n",
2175 ldap_err2string(err));
2176 /* Are we forcing it? */
2177 if(use_tls==3)
2179 fail_all(keylist,ldap_err_to_gpg_err(err));
2180 goto fail;
2183 else if(opt->verbose>1)
2184 fprintf(console,"gpgkeys: TLS started successfully.\n");
2185 #else
2186 if(use_tls>=2)
2187 fprintf(console,"gpgkeys: unable to start TLS: %s\n",
2188 "not built with TLS support");
2189 if(use_tls==3)
2191 fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
2192 goto fail;
2194 #endif
2198 /* By default we don't bind as there is usually no need to. For
2199 cases where the server needs some authentication, the user can
2200 use binddn and bindpw for auth. */
2202 if(binddn)
2204 #ifdef HAVE_LDAP_SET_OPTION
2205 int ver=LDAP_VERSION3;
2207 err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
2208 if(err!=LDAP_SUCCESS)
2210 fprintf(console,"gpgkeys: unable to go to LDAP 3: %s\n",
2211 ldap_err2string(err));
2212 fail_all(keylist,ldap_err_to_gpg_err(err));
2213 goto fail;
2215 #endif
2217 if(opt->verbose>2)
2218 fprintf(console,"gpgkeys: LDAP bind to %s, pw %s\n",binddn,
2219 bindpw?">not shown<":">none<");
2220 err=ldap_simple_bind_s(ldap,binddn,bindpw);
2221 if(err!=LDAP_SUCCESS)
2223 fprintf(console,"gpgkeys: internal LDAP bind error: %s\n",
2224 ldap_err2string(err));
2225 fail_all(keylist,ldap_err_to_gpg_err(err));
2226 goto fail;
2228 else
2229 bound=1;
2232 if(opt->action==KS_GET)
2234 keyptr=keylist;
2236 while(keyptr!=NULL)
2238 set_timeout(opt->timeout);
2240 if(get_key(keyptr->str)!=KEYSERVER_OK)
2241 failed++;
2243 keyptr=keyptr->next;
2246 else if(opt->action==KS_GETNAME)
2248 keyptr=keylist;
2250 while(keyptr!=NULL)
2252 set_timeout(opt->timeout);
2254 if(get_name(keyptr->str)!=KEYSERVER_OK)
2255 failed++;
2257 keyptr=keyptr->next;
2260 else if(opt->action==KS_SEND)
2262 int eof=0;
2266 set_timeout(opt->timeout);
2268 if(real_ldap)
2270 if(send_key(&eof)!=KEYSERVER_OK)
2271 failed++;
2273 else
2275 if(send_key_keyserver(&eof)!=KEYSERVER_OK)
2276 failed++;
2279 while(!eof);
2281 else if(opt->action==KS_SEARCH)
2283 char *searchkey=NULL;
2284 int len=0;
2286 set_timeout(opt->timeout);
2288 /* To search, we stick a * in between each key to search for.
2289 This means that if the user enters words, they'll get
2290 "enters*words". If the user "enters words", they'll get
2291 "enters words" */
2293 keyptr=keylist;
2294 while(keyptr!=NULL)
2296 len+=strlen(keyptr->str)+1;
2297 keyptr=keyptr->next;
2300 searchkey=malloc(len+1);
2301 if(searchkey==NULL)
2303 ret=KEYSERVER_NO_MEMORY;
2304 fail_all(keylist,KEYSERVER_NO_MEMORY);
2305 goto fail;
2308 searchkey[0]='\0';
2310 keyptr=keylist;
2311 while(keyptr!=NULL)
2313 strcat(searchkey,keyptr->str);
2314 strcat(searchkey,"*");
2315 keyptr=keyptr->next;
2318 /* Nail that last "*" */
2319 if(*searchkey)
2320 searchkey[strlen(searchkey)-1]='\0';
2322 if(search_key(searchkey)!=KEYSERVER_OK)
2323 failed++;
2325 free(searchkey);
2327 else
2328 BUG();
2330 if(!failed)
2331 ret=KEYSERVER_OK;
2333 fail:
2335 while(keylist!=NULL)
2337 struct keylist *current=keylist;
2338 keylist=keylist->next;
2339 free(current);
2342 if(input!=stdin)
2343 fclose(input);
2345 if(output!=stdout)
2346 fclose(output);
2348 free_ks_options(opt);
2350 if(ldap!=NULL && bound)
2351 ldap_unbind_s(ldap);
2353 free(basekeyspacedn);
2355 return ret;