1 /* ks-engine-ldap.c - talk to a LDAP keyserver
2 * Copyright (C) 2001, 2002, 2004, 2005, 2006
3 * 2007 Free Software Foundation, Inc.
4 * Copyright (C) 2015, 2020 g10 Code GmbH
6 * This file is part of GnuPG.
8 * GnuPG is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuPG is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <https://www.gnu.org/licenses/>.
36 #include "../common/userids.h"
37 #include "../common/mbox-util.h"
38 #include "ks-engine.h"
39 #include "ldap-misc.h"
40 #include "ldap-parse-uri.h"
41 #include "ldapserver.h"
44 /* Flags with infos from the connected server. */
45 #define SERVERINFO_REALLDAP 1 /* This is not the PGP keyserver. */
46 #define SERVERINFO_PGPKEYV2 2 /* Needs "pgpeyV2" instead of "pgpKey" */
47 #define SERVERINFO_SCHEMAV2 4 /* Version 2 of the Schema. */
48 #define SERVERINFO_NTDS 8 /* Server is an Active Directory. */
52 time_t timegm(struct tm *tm);
58 ldap2epochtime (const char *timestr)
63 memset (&pgptime, 0, sizeof(pgptime));
67 sscanf (timestr, "%4d%2d%2d%2d%2d%2d",
75 pgptime.tm_year -= 1900;
76 pgptime.tm_isdst = -1;
79 /* mktime() takes the timezone into account, so we use timegm() */
81 answer = timegm (&pgptime);
86 /* Caller must free the result. */
88 tm2ldaptime (struct tm *tm)
98 snprintf (buf, sizeof buf, "%04d%02d%02d%02d%02d%02dZ",
106 return xstrdup (buf);
110 /* Caller must free */
112 epoch2ldaptime (time_t stamp)
115 if (gmtime_r (&stamp, &tm))
116 return tm2ldaptime (&tm);
118 return xstrdup ("INVALID TIME");
124 my_ldap_value_free (char **vals)
127 ldap_value_free (vals);
132 /* Print a help output for the schemata supported by this module. */
134 ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri)
137 "Handler for LDAP URLs:\n"
138 " ldap://HOST:PORT/[BASEDN]????[bindname=BINDNAME,password=PASSWORD]\n"
140 "Note: basedn, bindname and password need to be percent escaped. In\n"
141 "particular, spaces need to be replaced with %20 and commas with %2c.\n"
142 "Thus bindname will typically be of the form:\n"
144 " uid=user%2cou=PGP%20Users%2cdc=EXAMPLE%2cdc=ORG\n"
146 "The ldaps:// and ldapi:// schemes are also supported. If ldaps is used\n"
147 "then the server's certificate will be checked. If it is not valid, any\n"
148 "operation will be aborted. Note that ldaps means LDAP with STARTTLS\n"
150 "As an alternative to an URL a string in this form may be used:\n"
152 " HOST:PORT:BINDNAME:PASSWORD:BASEDN:FLAGS:\n"
154 "The use of the percent sign or a colon in one of the string values is\n"
155 "currently not supported.\n"
157 "Supported methods: search, get, put\n";
161 err = ks_print_help (ctrl, " ldap");
162 else if (!strcmp (uri->scheme, "ldap")
163 || !strcmp (uri->scheme, "ldaps")
164 || !strcmp (uri->scheme, "ldapi")
166 err = ks_print_help (ctrl, data);
173 /* Convert a keyspec to a filter. Return an error if the keyspec is
174 bad or is not supported. The filter is escaped and returned in
175 *filter. It is the caller's responsibility to free *filter.
176 *filter is only set if this function returns success (i.e., 0). */
178 keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact,
179 unsigned int serverinfo)
181 /* Remove search type indicator and adjust PATTERN accordingly.
182 Note: don't include a preceding 0x when searching by keyid. */
184 /* XXX: Should we include disabled / revoke options? */
185 KEYDB_SEARCH_DESC desc;
190 gpg_error_t err = classify_user_id (keyspec, &desc, 1);
196 case KEYDB_SEARCH_MODE_EXACT:
197 f = xasprintf ("(pgpUserID=%s)",
198 (freeme = ldap_escape_filter (desc.u.name)));
201 case KEYDB_SEARCH_MODE_SUBSTR:
203 f = xasprintf ("(pgpUserID=*%s*)",
204 (freeme = ldap_escape_filter (desc.u.name)));
207 case KEYDB_SEARCH_MODE_MAIL:
208 freeme = ldap_escape_filter (desc.u.name);
211 if (*freeme == '<' && freeme[1] && freeme[2])
213 /* Strip angle brackets. Note that it is does not
214 * matter whether we work on the plan or LDAP escaped
215 * version of the mailbox. */
217 if (p[strlen(p)-1] == '>')
222 if ((serverinfo & SERVERINFO_SCHEMAV2))
223 f = xasprintf ("(&(gpgMailbox=%s)(!(|(pgpRevoked=1)(pgpDisabled=1))))",
225 else if (!only_exact)
226 f = xasprintf ("(pgpUserID=*<%s>*)", p);
229 case KEYDB_SEARCH_MODE_MAILSUB:
231 f = xasprintf ("(pgpUserID=*<*%s*>*)",
232 (freeme = ldap_escape_filter (desc.u.name)));
235 case KEYDB_SEARCH_MODE_MAILEND:
237 f = xasprintf ("(pgpUserID=*<*%s>*)",
238 (freeme = ldap_escape_filter (desc.u.name)));
241 case KEYDB_SEARCH_MODE_SHORT_KID:
242 f = xasprintf ("(pgpKeyID=%08lX)", (ulong) desc.u.kid[1]);
244 case KEYDB_SEARCH_MODE_LONG_KID:
245 f = xasprintf ("(pgpCertID=%08lX%08lX)",
246 (ulong) desc.u.kid[0], (ulong) desc.u.kid[1]);
249 case KEYDB_SEARCH_MODE_FPR16:
250 case KEYDB_SEARCH_MODE_FPR20:
251 case KEYDB_SEARCH_MODE_FPR:
252 if ((serverinfo & SERVERINFO_SCHEMAV2))
254 freeme = bin2hex (desc.u.fpr, 20, NULL);
256 return gpg_error_from_syserror ();
257 f = xasprintf ("(|(gpgFingerprint=%s)(gpgSubFingerprint=%s))",
259 /* FIXME: For an exact search and in case of a match on
260 * gpgSubFingerprint we need to check that there is only one
265 case KEYDB_SEARCH_MODE_ISSUER:
266 case KEYDB_SEARCH_MODE_ISSUER_SN:
267 case KEYDB_SEARCH_MODE_SN:
268 case KEYDB_SEARCH_MODE_SUBJECT:
269 case KEYDB_SEARCH_MODE_KEYGRIP:
270 case KEYDB_SEARCH_MODE_WORDS:
271 case KEYDB_SEARCH_MODE_FIRST:
272 case KEYDB_SEARCH_MODE_NEXT:
281 log_error ("Unsupported search mode.\n");
282 return gpg_error (GPG_ERR_NOT_SUPPORTED);
292 /* Connect to an LDAP server and interrogate it.
294 - uri describes the server to connect to and various options
295 including whether to use TLS and the username and password (see
296 ldap_parse_uri for a description of the various fields).
298 This function returns:
300 - The ldap connection handle in *LDAP_CONNP.
302 - The base DN for the PGP key space by querying the
303 pgpBaseKeySpaceDN attribute (This is normally
304 'ou=PGP Keys,dc=EXAMPLE,dc=ORG').
306 - The attribute to lookup to find the pgp key. This is either
307 'pgpKey' or 'pgpKeyV2'.
309 - Whether this is a real ldap server. (It's unclear what this
312 The values are returned in the passed variables. If you pass NULL,
313 then the value won't be returned. It is the caller's
314 responsibility to release *LDAP_CONNP with ldap_unbind and xfree
317 If this function successfully interrogated the server, it returns
318 0. If there was an LDAP error, it returns the LDAP error code. If
319 an error occurred, *basednp, etc., are undefined (and don't need to
322 R_SERVERINFO receives information about the server.
324 If no LDAP error occurred, you still need to check that *basednp is
325 valid. If it is NULL, then the server does not appear to be an
326 OpenPGP Keyserver. */
328 my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
329 char **r_basedn, char **r_host, int *r_use_tls,
330 unsigned int *r_serverinfo)
334 ldap_server_t server = NULL;
335 LDAP *ldap_conn = NULL;
337 char *host = NULL; /* Host to use. */
338 int port; /* Port to use. */
339 int use_tls; /* 1 = starttls, 2 = ldap-over-tls */
340 int use_ntds; /* Use Active Directory authentication. */
341 const char *bindname;
342 const char *password;
343 const char *basedn_arg;
344 #ifndef HAVE_W32_SYSTEM
358 server = ldapserver_parse_one (uri->path, NULL, 0);
360 return gpg_error (GPG_ERR_LDAP_OTHER);
363 bindname = server->user;
364 password = bindname? server->pass : NULL;
365 basedn_arg = server->base;
366 use_tls = server->starttls? 1 : server->ldap_over_tls? 2 : 0;
367 use_ntds = server->ntds;
373 bindname = uri->auth;
374 password = bindname? uri_query_value (uri, "password") : NULL;
375 basedn_arg = uri->path;
376 use_tls = uri->use_tls ? 1 : 0;
377 use_ntds = uri->ad_current;
381 port = use_tls == 2? 636 : 389;
386 host = xtrystrdup (host);
389 err = gpg_error_from_syserror ();
395 log_info ("ldap connect to '%s:%d:%s:%s:%s:%s%s'\n",
397 basedn_arg ? basedn_arg : "",
398 bindname ? bindname : "",
399 password ? "*****" : "",
400 use_tls == 1? "starttls" : use_tls == 2? "ldaptls" : "plain",
401 use_ntds ? ",ntds":"");
404 /* If the uri specifies a secure connection and we don't support
405 TLS, then fail; don't silently revert to an insecure
409 #ifndef HAVE_LDAP_START_TLS_S
410 log_error ("ldap: can't connect to the server: no TLS support.");
411 err = GPG_ERR_LDAP_NOT_SUPPORTED;
417 #ifdef HAVE_W32_SYSTEM
418 /* Note that host==NULL uses the default domain controller. */
420 ldap_conn = ldap_sslinit (host, port, (use_tls == 2));
424 lerr = LdapGetLastError ();
425 err = ldap_err_to_gpg_err (lerr);
426 log_error ("error initializing LDAP '%s:%d': %s\n",
427 host, port, ldap_err2string (lerr));
431 tmpstr = xtryasprintf ("%s://%s:%d",
432 use_tls == 2? "ldaps" : "ldap",
436 err = gpg_error_from_syserror ();
440 lerr = ldap_initialize (&ldap_conn, tmpstr);
442 if (lerr != LDAP_SUCCESS || !ldap_conn)
444 err = ldap_err_to_gpg_err (lerr);
445 log_error ("error initializing LDAP '%s': %s\n",
446 tmpstr, ldap_err2string (lerr));
453 #ifdef HAVE_LDAP_SET_OPTION
455 int ver = LDAP_VERSION3;
457 lerr = ldap_set_option (ldap_conn, LDAP_OPT_PROTOCOL_VERSION, &ver);
458 if (lerr != LDAP_SUCCESS)
460 log_error ("ks-ldap: unable to go to LDAP 3: %s\n",
461 ldap_err2string (lerr));
462 err = ldap_err_to_gpg_err (lerr);
468 int ver = opt.ldaptimeout;
470 lerr = ldap_set_option (ldap_conn, LDAP_OPT_TIMELIMIT, &ver);
471 if (lerr != LDAP_SUCCESS)
473 log_error ("ks-ldap: unable to set LDAP timelimit to %us: %s\n",
474 opt.ldaptimeout, ldap_err2string (lerr));
475 err = ldap_err_to_gpg_err (lerr);
479 log_info ("ldap timeout set to %us\n", opt.ldaptimeout);
484 #ifdef HAVE_LDAP_START_TLS_S
487 #ifndef HAVE_W32_SYSTEM
488 int check_cert = LDAP_OPT_X_TLS_HARD; /* LDAP_OPT_X_TLS_NEVER */
490 lerr = ldap_set_option (ldap_conn,
491 LDAP_OPT_X_TLS_REQUIRE_CERT, &check_cert);
494 log_error ("ldap: error setting an TLS option: %s\n",
495 ldap_err2string (lerr));
496 err = ldap_err_to_gpg_err (lerr);
500 /* On Windows, the certificates are checked by default. If the
501 option to disable checking mentioned above is ever
502 implemented, the way to do that on Windows is to install a
503 callback routine using ldap_set_option (..,
504 LDAP_OPT_SERVER_CERTIFICATE, ..); */
508 lerr = ldap_start_tls_s (ldap_conn,
509 #ifdef HAVE_W32_SYSTEM
510 /* ServerReturnValue, result */
513 /* ServerControls, ClientControls */
518 log_error ("ldap: error switching to STARTTLS mode: %s\n",
519 ldap_err2string (lerr));
520 err = ldap_err_to_gpg_err (lerr);
528 #ifdef HAVE_W32_SYSTEM
530 lerr = ldap_bind_s (ldap_conn, NULL, NULL, LDAP_AUTH_NEGOTIATE);
532 if (lerr != LDAP_SUCCESS)
534 log_error ("error binding to LDAP via AD: %s\n",
535 ldap_err2string (lerr));
536 err = ldap_err_to_gpg_err (lerr);
540 log_error ("ldap: no Active Directory support but 'ntds' requested\n");
541 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
548 lerr = ldap_simple_bind_s (ldap_conn, bindname, password);
550 if (lerr != LDAP_SUCCESS)
552 log_error ("error binding to LDAP: %s\n", ldap_err2string (lerr));
553 err = ldap_err_to_gpg_err (lerr);
559 /* By default we don't bind as there is usually no need to. */
562 if (basedn_arg && *basedn_arg)
564 /* User specified base DN. In this case we know the server is a
565 * real LDAP server. */
566 basedn = xtrystrdup (basedn_arg);
569 err = gpg_error_from_syserror ();
572 *r_serverinfo |= SERVERINFO_REALLDAP;
575 { /* Look for namingContexts. */
576 LDAPMessage *res = NULL;
577 char *attr[] = { "namingContexts", NULL };
580 lerr = ldap_search_s (ldap_conn, "", LDAP_SCOPE_BASE,
581 "(objectClass=*)", attr, 0, &res);
584 if (lerr == LDAP_SUCCESS)
589 context = ldap_get_values (ldap_conn, res, "namingContexts");
593 /* We found some, so try each namingContext as the
594 * search base and look for pgpBaseKeySpaceDN. Because
595 * we found this, we know we're talking to a regular-ish
596 * LDAP server and not an LDAP keyserver. */
599 { "pgpBaseKeySpaceDN", "pgpVersion", "pgpSoftware", NULL };
601 *r_serverinfo |= SERVERINFO_REALLDAP;
603 for (i = 0; context[i] && !basedn; i++)
610 char *object = xasprintf ("cn=pgpServerInfo,%s",
613 lerr = ldap_search_s (ldap_conn, object, LDAP_SCOPE_BASE,
614 "(objectClass=*)", attr2, 0, &si_res);
619 if (lerr == LDAP_SUCCESS)
621 vals = ldap_get_values (ldap_conn, si_res,
622 "pgpBaseKeySpaceDN");
625 basedn = xtrystrdup (vals[0]);
627 my_ldap_value_free (vals);
629 vals = ldap_get_values (ldap_conn, si_res,
634 log_debug ("Server: \t%s\n", vals[0]);
635 if (!ascii_strcasecmp (vals[0], "GnuPG"))
638 my_ldap_value_free (vals);
640 vals = ldap_get_values (ldap_conn, si_res,
645 log_debug ("Version:\t%s\n", vals[0]);
650 nfields = split_fields (vals[0],
651 fields, DIM(fields));
652 if (nfields > 0 && atoi(fields[0]) > 1)
653 *r_serverinfo |= SERVERINFO_SCHEMAV2;
655 && !ascii_strcasecmp (fields[1], "ntds"))
656 *r_serverinfo |= SERVERINFO_NTDS;
659 my_ldap_value_free (vals);
662 /* From man ldap_search_s: "res parameter of
663 ldap_search_ext_s() and ldap_search_s() should be
664 freed with ldap_msgfree() regardless of return
665 value of these functions. */
666 ldap_msgfree (si_res);
669 ldap_value_free (context);
672 else /* ldap_search failed. */
674 /* We don't have an answer yet, which means the server might
675 be a PGP.com keyserver. */
677 LDAPMessage *si_res = NULL;
679 char *attr2[] = { "pgpBaseKeySpaceDN", "version", "software", NULL };
682 lerr = ldap_search_s (ldap_conn, "cn=pgpServerInfo", LDAP_SCOPE_BASE,
683 "(objectClass=*)", attr2, 0, &si_res);
685 if (lerr == LDAP_SUCCESS)
687 /* For the PGP LDAP keyserver, this is always
688 * "OU=ACTIVE,O=PGP KEYSPACE,C=US", but it might not be
691 vals = ldap_get_values (ldap_conn, si_res, "baseKeySpaceDN");
694 basedn = xtrystrdup (vals[0]);
696 my_ldap_value_free (vals);
698 vals = ldap_get_values (ldap_conn, si_res, "software");
702 log_debug ("ks-ldap: PGP Server: \t%s\n", vals[0]);
704 my_ldap_value_free (vals);
706 vals = ldap_get_values (ldap_conn, si_res, "version");
710 log_debug ("ks-ldap: PGP Server Version:\t%s\n", vals[0]);
712 /* If the version is high enough, use the new
713 pgpKeyV2 attribute. This design is iffy at best,
714 but it matches how PGP does it. I figure the NAI
715 folks assumed that there would never be an LDAP
716 keyserver vendor with a different numbering
718 if (atoi (vals[0]) > 1)
719 *r_serverinfo |= SERVERINFO_PGPKEYV2;
722 my_ldap_value_free (vals);
725 ldap_msgfree (si_res);
728 /* From man ldap_search_s: "res parameter of ldap_search_ext_s()
729 and ldap_search_s() should be freed with ldap_msgfree()
730 regardless of return value of these functions. */
735 if (!err && opt.debug)
737 log_debug ("ldap_conn: %p\n", ldap_conn);
738 log_debug ("server_type: %s\n", ((*r_serverinfo & SERVERINFO_REALLDAP)
739 ? "LDAP" : "PGP.com keyserver") );
740 log_debug ("basedn: %s\n", basedn);
741 log_debug ("pgpkeyattr: %s\n",
742 (*r_serverinfo & SERVERINFO_PGPKEYV2)? "pgpKeyV2":"pgpKey");
745 ldapserver_list_free (server);
751 ldap_unbind (ldap_conn);
764 *ldap_connp = ldap_conn;
770 /* Extract keys from an LDAP reply and write them out to the output
771 stream OUTPUT in a format GnuPG can import (either the OpenPGP
772 binary format or armored format). */
774 extract_keys (estream_t output,
775 LDAP *ldap_conn, const char *certid, LDAPMessage *message)
779 es_fprintf (output, "INFO %s BEGIN\n", certid);
781 /* Note: ldap_get_values returns a NULL terminated array of
784 vals = ldap_get_values (ldap_conn, message, "gpgfingerprint");
785 if (vals && vals[0] && vals[0][0])
786 es_fprintf (output, "pub:%s:", vals[0]);
788 es_fprintf (output, "pub:%s:", certid);
789 my_ldap_value_free (vals);
791 vals = ldap_get_values (ldap_conn, message, "pgpkeytype");
794 if (strcmp (vals[0], "RSA") == 0)
795 es_fprintf (output, "1");
796 else if (strcmp (vals[0],"DSS/DH") == 0)
797 es_fprintf (output, "17");
799 my_ldap_value_free (vals);
801 es_fprintf (output, ":");
803 vals = ldap_get_values (ldap_conn, message, "pgpkeysize");
806 int v = atoi (vals[0]);
808 es_fprintf (output, "%d", v);
810 my_ldap_value_free (vals);
812 es_fprintf (output, ":");
814 vals = ldap_get_values (ldap_conn, message, "pgpkeycreatetime");
817 if (strlen (vals[0]) == 15)
818 es_fprintf (output, "%u", (unsigned int) ldap2epochtime (vals[0]));
820 my_ldap_value_free (vals);
822 es_fprintf (output, ":");
824 vals = ldap_get_values (ldap_conn, message, "pgpkeyexpiretime");
827 if (strlen (vals[0]) == 15)
828 es_fprintf (output, "%u", (unsigned int) ldap2epochtime (vals[0]));
830 my_ldap_value_free (vals);
832 es_fprintf (output, ":");
834 vals = ldap_get_values (ldap_conn, message, "pgprevoked");
837 if (atoi (vals[0]) == 1)
838 es_fprintf (output, "r");
840 my_ldap_value_free (vals);
842 es_fprintf (output, "\n");
844 vals = ldap_get_values (ldap_conn, message, "pgpuserid");
848 for (i = 0; vals[i]; i++)
849 es_fprintf (output, "uid:%s\n", vals[i]);
851 my_ldap_value_free (vals);
853 es_fprintf (output, "INFO %s END\n", certid);
856 /* Get the key described key the KEYSPEC string from the keyserver
857 identified by URI. On success R_FP has an open stream to read the
860 ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec,
865 unsigned int serverinfo;
869 LDAP *ldap_conn = NULL;
872 LDAPMessage *message = NULL;
876 if (dirmngr_use_tor ())
878 /* For now we do not support LDAP over Tor. */
879 log_error (_("LDAP access not possible due to Tor mode\n"));
880 return gpg_error (GPG_ERR_NOT_SUPPORTED);
883 /* Make sure we are talking to an OpenPGP LDAP server. */
884 err = my_ldap_connect (uri, &ldap_conn,
885 &basedn, &host, &use_tls, &serverinfo);
889 err = gpg_error (GPG_ERR_GENERAL);
893 /* Now that we have information about the server we can construct a
894 * query best suited for the capabilities of the server. */
895 err = keyspec_to_ldap_filter (keyspec, &filter, 1, serverinfo);
900 log_debug ("ks-ldap: using filter: %s\n", filter);
903 /* The ordering is significant. Specifically, "pgpcertid" needs
904 to be the second item in the list, since everything after it
905 may be discarded if we aren't in verbose mode. */
909 "pgpcertid", "pgpuserid", "pgpkeyid", "pgprevoked", "pgpdisabled",
910 "pgpkeycreatetime", "modifytimestamp", "pgpkeysize", "pgpkeytype",
914 /* 1 if we want just attribute types; 0 if we want both attribute
915 * types and values. */
919 /* Replace "dummy". */
920 attrs[0] = (serverinfo & SERVERINFO_PGPKEYV2)? "pgpKeyV2" : "pgpKey";
923 ldap_err = ldap_search_s (ldap_conn, basedn, LDAP_SCOPE_SUBTREE,
924 filter, attrs, attrsonly, &message);
928 err = ldap_err_to_gpg_err (ldap_err);
930 log_error ("ks-ldap: LDAP search error: %s\n",
931 ldap_err2string (ldap_err));
935 count = ldap_count_entries (ldap_conn, message);
938 log_info ("ks-ldap: key %s not found on keyserver\n", keyspec);
941 err = ldap_to_gpg_err (ldap_conn);
943 err = gpg_error (GPG_ERR_NO_DATA);
949 /* There may be more than one unique result for a given keyID,
950 so we should fetch them all (test this by fetching short key
953 /* The set of entries that we've seen. */
954 strlist_t seen = NULL;
958 for (npth_unprotect (),
959 each = ldap_first_entry (ldap_conn, message),
963 each = ldap_next_entry (ldap_conn, each),
969 /* Use the long keyid to remove duplicates. The LDAP
970 server returns the same keyid more than once if there
971 are multiple user IDs on the key. Note that this does
972 NOT mean that a keyid that exists multiple times on the
973 keyserver will not be fetched. It means that each KEY,
974 no matter how many user IDs share its keyid, will be
975 fetched only once. If a keyid that belongs to more
976 than one key is fetched, the server quite properly
977 responds with all matching keys. -ds */
979 certid = ldap_get_values (ldap_conn, each, "pgpcertid");
980 if (certid && certid[0])
982 if (! strlist_find (seen, certid[0]))
984 /* It's not a duplicate, add it */
986 add_to_strlist (&seen, certid[0]);
989 fp = es_fopenmem(0, "rw");
991 extract_keys (fp, ldap_conn, certid[0], each);
993 vals = ldap_get_values (ldap_conn, each, attrs[0]);
996 err = ldap_to_gpg_err (ldap_conn);
997 log_error("ks-ldap: unable to retrieve key %s "
998 "from keyserver\n", certid[0]);
1003 /* We should strip the new lines. */
1004 es_fprintf (fp, "KEY 0x%s BEGIN\n", certid[0]);
1005 es_fputs (vals[0], fp);
1006 es_fprintf (fp, "\nKEY 0x%s END\n", certid[0]);
1008 ldap_value_free (vals);
1014 my_ldap_value_free (certid);
1017 free_strlist (seen);
1020 err = gpg_error (GPG_ERR_NO_DATA);
1023 err = dirmngr_status_printf (ctrl, "SOURCE", "%s://%s",
1024 use_tls? "ldaps" : "ldap",
1031 ldap_msgfree (message);
1041 es_fseek (fp, 0, SEEK_SET);
1050 ldap_unbind (ldap_conn);
1058 /* Search the keyserver identified by URI for keys matching PATTERN.
1059 On success R_FP has an open stream to read the data. */
1061 ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
1066 unsigned int serverinfo;
1067 char *filter = NULL;
1068 LDAP *ldap_conn = NULL;
1069 char *basedn = NULL;
1070 estream_t fp = NULL;
1074 if (dirmngr_use_tor ())
1076 /* For now we do not support LDAP over Tor. */
1077 log_error (_("LDAP access not possible due to Tor mode\n"));
1078 return gpg_error (GPG_ERR_NOT_SUPPORTED);
1081 /* Make sure we are talking to an OpenPGP LDAP server. */
1082 err = my_ldap_connect (uri, &ldap_conn, &basedn, NULL, NULL, &serverinfo);
1086 err = GPG_ERR_GENERAL;
1090 /* Now that we have information about the server we can construct a
1091 * query best suited for the capabilities of the server. */
1092 err = keyspec_to_ldap_filter (pattern, &filter, 0, serverinfo);
1095 log_error ("Bad search pattern: '%s'\n", pattern);
1099 /* Even if we have no results, we want to return a stream. */
1100 fp = es_fopenmem(0, "rw");
1103 err = gpg_error_from_syserror ();
1109 LDAPMessage *res, *each;
1111 strlist_t dupelist = NULL;
1113 /* The maximum size of the search, including the optional stuff
1114 and the trailing \0 */
1117 "pgpcertid", "pgpuserid", "pgprevoked", "pgpdisabled",
1118 "pgpkeycreatetime", "pgpkeyexpiretime", "modifytimestamp",
1119 "pgpkeysize", "pgpkeytype", "gpgfingerprint",
1124 log_debug ("SEARCH '%s' => '%s' BEGIN\n", pattern, filter);
1127 ldap_err = ldap_search_s (ldap_conn, basedn,
1128 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &res);
1134 if (ldap_err != LDAP_SUCCESS && ldap_err != LDAP_SIZELIMIT_EXCEEDED)
1136 err = ldap_err_to_gpg_err (ldap_err);
1138 log_error ("SEARCH %s FAILED %d\n", pattern, err);
1139 log_error ("ks-ldap: LDAP search error: %s\n",
1140 ldap_err2string (err));
1144 /* The LDAP server doesn't return a real count of unique keys, so we
1145 can't use ldap_count_entries here. */
1146 for (npth_unprotect (),
1147 each = ldap_first_entry (ldap_conn, res),
1151 each = ldap_next_entry (ldap_conn, each),
1154 char **certid = ldap_get_values (ldap_conn, each, "pgpcertid");
1155 if (certid && certid[0] && ! strlist_find (dupelist, certid[0]))
1157 add_to_strlist (&dupelist, certid[0]);
1160 my_ldap_value_free (certid);
1163 if (ldap_err == LDAP_SIZELIMIT_EXCEEDED)
1166 log_error ("ks-ldap: search results exceeded server limit."
1167 " First 1 result shown.\n");
1169 log_error ("ks-ldap: search results exceeded server limit."
1170 " First %d results shown.\n", count);
1173 free_strlist (dupelist);
1177 es_fputs ("info:1:0\n", fp);
1180 es_fprintf (fp, "info:1:%d\n", count);
1182 for (each = ldap_first_entry (ldap_conn, res);
1184 each = ldap_next_entry (ldap_conn, each))
1189 certid = ldap_get_values (ldap_conn, each, "pgpcertid");
1190 if (!certid || !certid[0])
1192 my_ldap_value_free (certid);
1196 /* Have we seen this certid before? */
1197 if (! strlist_find (dupelist, certid[0]))
1199 add_to_strlist (&dupelist, certid[0]);
1201 vals = ldap_get_values (ldap_conn, each, "gpgfingerprint");
1202 if (vals && vals[0] && vals[0][0])
1203 es_fprintf (fp, "pub:%s:", vals[0]);
1205 es_fprintf (fp, "pub:%s:", certid[0]);
1206 my_ldap_value_free (vals);
1208 vals = ldap_get_values (ldap_conn, each, "pgpkeytype");
1209 if (vals && vals[0])
1211 /* The LDAP server doesn't exactly handle this
1213 if (strcasecmp (vals[0], "RSA") == 0)
1215 else if (strcasecmp (vals[0], "DSS/DH") == 0)
1216 es_fputs ("17", fp);
1218 my_ldap_value_free (vals);
1222 vals = ldap_get_values (ldap_conn, each, "pgpkeysize");
1223 if (vals && vals[0])
1225 /* Not sure why, but some keys are listed with a
1226 key size of 0. Treat that like an unknown. */
1227 if (atoi (vals[0]) > 0)
1228 es_fprintf (fp, "%d", atoi (vals[0]));
1230 my_ldap_value_free (vals);
1234 /* YYYYMMDDHHmmssZ */
1236 vals = ldap_get_values (ldap_conn, each, "pgpkeycreatetime");
1237 if(vals && vals[0] && strlen (vals[0]) == 15)
1239 es_fprintf (fp, "%u",
1240 (unsigned int) ldap2epochtime(vals[0]));
1242 my_ldap_value_free (vals);
1246 vals = ldap_get_values (ldap_conn, each, "pgpkeyexpiretime");
1247 if (vals && vals[0] && strlen (vals[0]) == 15)
1249 es_fprintf (fp, "%u",
1250 (unsigned int) ldap2epochtime (vals[0]));
1252 my_ldap_value_free (vals);
1256 vals = ldap_get_values (ldap_conn, each, "pgprevoked");
1257 if (vals && vals[0])
1259 if (atoi (vals[0]) == 1)
1260 es_fprintf (fp, "r");
1262 my_ldap_value_free (vals);
1264 vals = ldap_get_values (ldap_conn, each, "pgpdisabled");
1265 if (vals && vals[0])
1267 if (atoi (vals[0]) ==1)
1268 es_fprintf (fp, "d");
1270 my_ldap_value_free (vals);
1273 /* This is not yet specified in the keyserver
1274 protocol, but may be someday. */
1277 vals = ldap_get_values (ldap_conn, each, "modifytimestamp");
1278 if(vals && vals[0] strlen (vals[0]) == 15)
1280 es_fprintf (fp, "%u",
1281 (unsigned int) ldap2epochtime (vals[0]));
1283 my_ldap_value_free (vals);
1286 es_fprintf (fp, "\n");
1288 /* Now print all the uids that have this certid */
1289 for (uids = ldap_first_entry (ldap_conn, res);
1291 uids = ldap_next_entry (ldap_conn, uids))
1293 vals = ldap_get_values (ldap_conn, uids, "pgpcertid");
1294 if (!vals || !vals[0])
1296 my_ldap_value_free (vals);
1300 if (!ascii_strcasecmp (certid[0], vals[0]))
1304 es_fprintf (fp, "uid:");
1306 uidvals = ldap_get_values (ldap_conn,
1310 /* Need to percent escape any colons */
1311 char *quoted = try_percent_escape (uidvals[0],
1314 es_fputs (quoted, fp);
1317 my_ldap_value_free (uidvals);
1319 es_fprintf (fp, "\n");
1322 ldap_value_free(vals);
1326 my_ldap_value_free (certid);
1331 free_strlist (dupelist);
1335 log_debug ("SEARCH %s END\n", pattern);
1344 /* Return the read stream. */
1346 es_fseek (fp, 0, SEEK_SET);
1354 ldap_unbind (ldap_conn);
1363 /* A modlist describes a set of changes to an LDAP entry. (An entry
1364 consists of 1 or more attributes. Attributes are <name, value>
1365 pairs. Note: an attribute may be multi-valued in which case
1366 multiple values are associated with a single name.)
1368 A modlist is a NULL terminated array of struct LDAPMod's.
1378 Is the ith modification.
1380 Each LDAPMod describes a change to a single attribute. Further,
1381 there is one modification for each attribute that we want to
1382 change. The attribute's new value is stored in LDAPMod.mod_values.
1383 If the attribute is multi-valued, we still only use a single
1384 LDAPMod structure: mod_values is a NULL-terminated array of
1385 strings. To delete an attribute from an entry, we set mod_values
1390 modlist[i]->mod_values == NULL
1392 then we remove the attribute.
1394 (Using LDAP_MOD_DELETE doesn't work here as we don't know if the
1395 attribute in question exists or not.)
1397 Note: this function does NOT copy or free ATTR. It does copy
1400 modlist_add (LDAPMod ***modlistp, char *attr, const char *value)
1402 LDAPMod **modlist = *modlistp;
1407 /* Search modlist for the attribute we're playing with. If modlist
1408 is NULL, then the list is empty. Recall: modlist is a NULL
1409 terminated array. */
1410 for (m = modlist; m && *m; m++, nummods ++)
1412 /* The attribute is already on the list. */
1416 if (strcasecmp ((*m)->mod_type, attr) != 0)
1419 /* We have this attribute already, so when the REPLACE happens,
1420 the server attributes will be replaced anyway. */
1424 /* Attributes can be multi-valued. See if the value is already
1425 present. mod_values is a NULL terminated array of pointers.
1426 Note: mod_values can be NULL. */
1427 for (ptr = (*m)->mod_values; ptr && *ptr; ptr++)
1429 if (strcmp (*ptr, value) == 0)
1430 /* Duplicate value, we're done. */
1435 /* Append the value. */
1436 ptr = xrealloc ((*m)->mod_values, sizeof (char *) * (numvalues + 2));
1438 (*m)->mod_values = ptr;
1439 ptr[numvalues] = xstrdup (value);
1441 ptr[numvalues + 1] = NULL;
1446 /* We didn't find the attr, so make one and add it to the end */
1448 /* Like attribute values, the list of attributes is NULL terminated
1449 array of pointers. */
1450 modlist = xrealloc (modlist, sizeof (LDAPMod *) * (nummods + 2));
1452 *modlistp = modlist;
1453 modlist[nummods] = xmalloc (sizeof (LDAPMod));
1455 modlist[nummods]->mod_op = LDAP_MOD_REPLACE;
1456 modlist[nummods]->mod_type = attr;
1459 modlist[nummods]->mod_values = xmalloc (sizeof(char *) * 2);
1461 modlist[nummods]->mod_values[0] = xstrdup (value);
1462 modlist[nummods]->mod_values[1] = NULL;
1465 modlist[nummods]->mod_values = NULL;
1467 modlist[nummods + 1] = NULL;
1472 /* Look up the value of an attribute in the specified modlist. If the
1473 attribute is not on the mod list, returns NULL. The result is a
1474 NULL-terminated array of strings. Don't change it. */
1476 modlist_lookup (LDAPMod **modlist, const char *attr)
1479 for (m = modlist; m && *m; m++)
1481 if (strcasecmp ((*m)->mod_type, attr) != 0)
1484 return (*m)->mod_values;
1490 /* Dump a modlist to a file. This is useful for debugging. */
1491 static estream_t modlist_dump (LDAPMod **modlist, estream_t output)
1495 modlist_dump (LDAPMod **modlist, estream_t output)
1503 output = es_fopenmem (0, "rw");
1509 for (m = modlist; m && *m; m++)
1511 es_fprintf (output, " %s:", (*m)->mod_type);
1513 if (! (*m)->mod_values)
1514 es_fprintf(output, " delete.\n");
1521 if ((*m)->mod_values[0] && (*m)->mod_values[1])
1522 /* Have at least 2. */
1526 es_fprintf (output, "\n");
1528 for ((ptr = (*m)->mod_values), (i = 1); ptr && *ptr; ptr++, i ++)
1530 /* Assuming terminals are about 80 characters wide,
1531 display at most about 10 lines of debugging
1532 output. If we do trim the buffer, append '...' to
1534 const int max_len = 10 * 70;
1535 size_t value_len = strlen (*ptr);
1536 int elide = value_len > max_len;
1539 es_fprintf (output, " %d. ", i);
1540 es_fprintf (output, "`%.*s", max_len, *ptr);
1542 es_fprintf (output, "...' (%zd bytes elided)",
1543 value_len - max_len);
1545 es_fprintf (output, "'");
1546 es_fprintf (output, "\n");
1552 es_fseek (output, 0, SEEK_SET);
1557 /* Free all of the memory allocated by the mod list. This assumes
1558 that the attribute names don't have to be freed, but the attributes
1559 values do. (Which is what modlist_add does.) */
1561 modlist_free (LDAPMod **modlist)
1568 /* Unwind and free the whole modlist structure */
1570 /* The modlist is a NULL terminated array of pointers. */
1571 for (ml = modlist; *ml; ml++)
1576 /* The list of values is a NULL termianted array of pointers.
1577 If the list is NULL, there are no values. */
1579 if (mod->mod_values)
1581 for (ptr = mod->mod_values; *ptr; ptr++)
1584 xfree (mod->mod_values);
1592 /* Append two onto the end of one. Two is not freed, but its pointers
1593 are now part of one. Make sure you don't free them both!
1595 As long as you don't add anything to ONE, TWO is still valid.
1596 After that all bets are off. */
1598 modlists_join (LDAPMod ***one, LDAPMod **two)
1600 int i, one_count = 0, two_count = 0;
1604 /* two is empty. Nothing to do. */
1608 /* one is empty. Just set it equal to *two. */
1614 for (grow = *one; *grow; grow++)
1617 for (grow = two; *grow; grow++)
1620 grow = xrealloc (*one, sizeof(LDAPMod *) * (one_count + two_count + 1));
1622 for (i = 0; i < two_count; i++)
1623 grow[one_count + i] = two[i];
1625 grow[one_count + i] = NULL;
1630 /* Given a string, unescape C escapes. In particular, \xXX. This
1631 modifies the string in place. */
1633 uncescape (char *str)
1638 char *first = strchr (str, '\\');
1640 /* No backslashes => no escaping. We're done. */
1643 /* Start at the first '\\'. */
1644 r = w = (uintptr_t) first - (uintptr_t) str;
1648 /* XXX: What to do about bad escapes?
1649 XXX: hextobyte already checks the string thus the hexdigitp
1650 could be removed. */
1651 if (str[r] == '\\' && str[r + 1] == 'x'
1652 && str[r+2] && str[r+3]
1653 && hexdigitp (str + r + 2)
1654 && hexdigitp (str + r + 3))
1656 int x = hextobyte (&str[r + 2]);
1657 log_assert (0 <= x && x <= 0xff);
1661 /* We consumed 4 characters and wrote 1. */
1666 str[w ++] = str[r ++];
1672 /* Given one line from an info block (`gpg --list-{keys,sigs}
1673 --with-colons KEYID'), pull it apart and fill in the modlist with
1674 the relevant (for the LDAP schema) attributes. EXTRACT_STATE
1675 should initally be set to 0 by the caller. SCHEMAV2 is set if the
1676 server supports the version 2 schema. */
1678 extract_attributes (LDAPMod ***modlist, int *extract_state,
1679 char *line, int schemav2)
1684 int is_pub, is_sub, is_uid, is_sig;
1686 /* Remove trailing whitespace */
1687 trim_trailing_spaces (line);
1689 fields = strsplit (line, ':', '\0', &field_count);
1690 if (field_count == 1)
1691 /* We only have a single field. There is definitely nothing to
1695 if (field_count < 7)
1698 is_pub = !ascii_strcasecmp ("pub", fields[0]);
1699 is_sub = !ascii_strcasecmp ("sub", fields[0]);
1700 is_uid = !ascii_strcasecmp ("uid", fields[0]);
1701 is_sig = !ascii_strcasecmp ("sig", fields[0]);
1702 if (!ascii_strcasecmp ("fpr", fields[0]))
1704 /* Special treatment for a fingerprint. */
1705 if (!(*extract_state & 1))
1706 goto out; /* Stray fingerprint line - ignore. */
1707 *extract_state &= ~1;
1708 if (field_count >= 10 && schemav2)
1710 if ((*extract_state & 2))
1711 modlist_add (modlist, "gpgFingerprint", fields[9]);
1713 modlist_add (modlist, "gpgSubFingerprint", fields[9]);
1718 *extract_state &= ~(1|2);
1720 *extract_state |= (1|2);
1722 *extract_state |= 1;
1724 if (!is_pub && !is_sub && !is_uid && !is_sig)
1725 goto out; /* Not a relevant line. */
1729 if (is_uid && strlen (keyid) == 0)
1730 ; /* The uid record type can have an empty keyid. */
1731 else if (strlen (keyid) == 16
1732 && strspn (keyid, "0123456789aAbBcCdDeEfF") == 16)
1733 ; /* Otherwise, we expect exactly 16 hex characters. */
1736 log_error ("malformed record!\n");
1745 for (flags = fields[1]; *flags; flags ++)
1759 /* Note: we always create the pgpDisabled and pgpRevoked
1760 attributes, regardless of whether the key is disabled/revoked
1761 or not. This is because a very common search is like
1762 "(&(pgpUserID=*isabella*)(pgpDisabled=0))" */
1766 modlist_add (modlist,"pgpDisabled", disabled ? "1" : "0");
1767 modlist_add (modlist,"pgpRevoked", revoked ? "1" : "0");
1771 if (is_pub || is_sub)
1776 val = atoi (fields[2]);
1777 if (val < 99999 && val > 0)
1779 /* We zero pad this on the left to make PGP happy. */
1780 snprintf (padded, sizeof padded, "%05u", val);
1781 modlist_add (modlist, "pgpKeySize", padded);
1787 char *algo = fields[3];
1788 int val = atoi (algo);
1805 modlist_add (modlist, "pgpKeyType", algo);
1808 if (is_pub || is_sub || is_sig)
1812 modlist_add (modlist, "pgpCertID", keyid); /* Long keyid(!) */
1813 modlist_add (modlist, "pgpKeyID", &keyid[8]); /* Short keyid */
1817 modlist_add (modlist, "pgpSubKeyID", keyid); /* Long keyid(!) */
1822 char *create_time = fields[5];
1824 if (strlen (create_time) == 0)
1828 char *create_time_orig = create_time;
1833 memset (&tm, 0, sizeof (tm));
1835 /* parse_timestamp handles both seconds fromt he epoch and
1836 ISO 8601 format. We also need to handle YYYY-MM-DD
1837 format (as generated by gpg1 --with-colons --list-key).
1838 Check that first and then if it fails, then try
1841 if (!isodate_human_to_tm (create_time, &tm))
1842 create_time = tm2ldaptime (&tm);
1843 else if ((t = parse_timestamp (create_time, &end)) != (time_t) -1
1847 if (!gnupg_gmtime (&t, &tm))
1850 create_time = tm2ldaptime (&tm);
1856 /* Failed to parse string. */
1857 log_error ("Failed to parse creation time ('%s')",
1863 modlist_add (modlist, "pgpKeyCreateTime", create_time);
1864 xfree (create_time);
1870 char *expire_time = fields[6];
1872 if (strlen (expire_time) == 0)
1876 char *expire_time_orig = expire_time;
1881 memset (&tm, 0, sizeof (tm));
1883 /* parse_timestamp handles both seconds fromt he epoch and
1884 ISO 8601 format. We also need to handle YYYY-MM-DD
1885 format (as generated by gpg1 --with-colons --list-key).
1886 Check that first and then if it fails, then try
1889 if (!isodate_human_to_tm (expire_time, &tm))
1890 expire_time = tm2ldaptime (&tm);
1891 else if ((t = parse_timestamp (expire_time, &end)) != (time_t) -1
1894 if (!gnupg_gmtime (&t, &tm))
1897 expire_time = tm2ldaptime (&tm);
1903 /* Failed to parse string. */
1904 log_error ("Failed to parse creation time ('%s')",
1910 modlist_add (modlist, "pgpKeyExpireTime", expire_time);
1911 xfree (expire_time);
1915 if (is_uid && field_count >= 10)
1917 char *uid = fields[9];
1921 modlist_add (modlist, "pgpUserID", uid);
1922 if (schemav2 && (mbox = mailbox_from_userid (uid)))
1924 modlist_add (modlist, "gpgMailbox", mbox);
1933 /* Send the key in {KEY,KEYLEN} with the metadata {INFO,INFOLEN} to
1934 the keyserver identified by URI. See server.c:cmd_ks_put for the
1935 format of the data and metadata. */
1937 ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri,
1938 void *data, size_t datalen,
1939 void *info, size_t infolen)
1941 gpg_error_t err = 0;
1943 unsigned int serverinfo;
1944 LDAP *ldap_conn = NULL;
1945 char *basedn = NULL;
1946 LDAPMod **modlist = NULL;
1947 LDAPMod **addlist = NULL;
1948 char *data_armored = NULL;
1951 /* The last byte of the info block. */
1952 const char *infoend = (const char *) info + infolen - 1;
1954 /* Enable this code to dump the modlist to /tmp/modlist.txt. */
1956 # warning Disable debug code before checking in.
1957 const int dump_modlist = 1;
1959 const int dump_modlist = 0;
1961 estream_t dump = NULL;
1963 /* Elide a warning. */
1966 if (dirmngr_use_tor ())
1968 /* For now we do not support LDAP over Tor. */
1969 log_error (_("LDAP access not possible due to Tor mode\n"));
1970 return gpg_error (GPG_ERR_NOT_SUPPORTED);
1973 err = my_ldap_connect (uri, &ldap_conn, &basedn, NULL, NULL, &serverinfo);
1977 err = GPG_ERR_GENERAL;
1981 if (!(serverinfo & SERVERINFO_REALLDAP))
1983 /* We appear to have a PGP.com Keyserver, which can unpack the
1984 * key on its own (not just a dump LDAP server). This will
1985 * rarely be the case these days. */
1993 memset (&mod, 0, sizeof (mod));
1994 mod.mod_op = LDAP_MOD_ADD;
1995 mod.mod_type = (serverinfo & SERVERINFO_PGPKEYV2)? "pgpKeyV2":"pgpKey";
1996 mod.mod_values = key;
2000 dn = xtryasprintf ("pgpCertid=virtual,%s", basedn);
2003 err = gpg_error_from_syserror ();
2006 ldap_err = ldap_add_s (ldap_conn, dn, attrs);
2009 if (ldap_err != LDAP_SUCCESS)
2011 err = ldap_err_to_gpg_err (err);
2018 modlist = xtrymalloc (sizeof (LDAPMod *));
2021 err = gpg_error_from_syserror ();
2028 dump = es_fopen("/tmp/modlist.txt", "w");
2030 log_error ("failed to open /tmp/modlist.txt: %s\n",
2031 gpg_strerror (gpg_error_from_syserror ()));
2035 es_fprintf(dump, "data (%zd bytes)\n", datalen);
2036 es_fprintf(dump, "info (%zd bytes): '\n", infolen);
2037 es_fwrite(info, infolen, 1, dump);
2038 es_fprintf(dump, "'\n");
2042 /* Start by nulling out all attributes. We try and do a modify
2043 operation first, so this ensures that we don't leave old
2044 attributes lying around. */
2045 modlist_add (&modlist, "pgpDisabled", NULL);
2046 modlist_add (&modlist, "pgpKeyID", NULL);
2047 modlist_add (&modlist, "pgpKeyType", NULL);
2048 modlist_add (&modlist, "pgpUserID", NULL);
2049 modlist_add (&modlist, "pgpKeyCreateTime", NULL);
2050 modlist_add (&modlist, "pgpRevoked", NULL);
2051 modlist_add (&modlist, "pgpSubKeyID", NULL);
2052 modlist_add (&modlist, "pgpKeySize", NULL);
2053 modlist_add (&modlist, "pgpKeyExpireTime", NULL);
2054 modlist_add (&modlist, "pgpCertID", NULL);
2055 if ((serverinfo & SERVERINFO_SCHEMAV2))
2057 modlist_add (&modlist, "gpgFingerprint", NULL);
2058 modlist_add (&modlist, "gpgSubFingerprint", NULL);
2059 modlist_add (&modlist, "gpgMailbox", NULL);
2062 /* Assemble the INFO stuff into LDAP attributes */
2068 char *newline = memchr (info, '\n', infolen);
2070 /* The last line is not \n terminated! Make a copy so we can
2071 add a NUL terminator. */
2073 temp = xmalloc (infolen + 1);
2074 memcpy (temp, info, infolen);
2076 newline = (char *) info + infolen;
2081 extract_attributes (&addlist, &extract_state, info,
2082 (serverinfo & SERVERINFO_SCHEMAV2));
2084 infolen = infolen - ((uintptr_t) newline - (uintptr_t) info + 1);
2089 log_assert ((char *) info + infolen - 1 == infoend);
2092 log_assert (infolen == -1);
2097 modlist_add (&addlist, "objectClass", "pgpKeyInfo");
2099 err = armor_data (&data_armored, data, datalen);
2103 modlist_add (&addlist,
2104 (serverinfo & SERVERINFO_PGPKEYV2)? "pgpKeyV2":"pgpKey",
2107 /* Now append addlist onto modlist. */
2108 modlists_join (&modlist, addlist);
2112 estream_t input = modlist_dump (modlist, NULL);
2115 copy_stream (input, dump);
2120 /* Going on the assumption that modify operations are more frequent
2121 than adds, we try a modify first. If it's not there, we just
2122 turn around and send an add command for the same key. Otherwise,
2123 the modify brings the server copy into compliance with our copy.
2124 Note that unlike the LDAP keyserver (and really, any other
2125 keyserver) this does NOT merge signatures, but replaces the whole
2126 key. This should make some people very happy. */
2131 if ((serverinfo & SERVERINFO_NTDS))
2133 /* The modern way using a CN RDN with the fingerprint. This
2134 * has the advantage that we won't have duplicate 64 bit
2135 * keyids in the store. In particular NTDS requires the
2136 * DN to be unique. */
2137 attrval = modlist_lookup (addlist, "gpgFingerprint");
2138 /* We should have exactly one value. */
2139 if (!attrval || !(attrval[0] && !attrval[1]))
2141 log_error ("ks-ldap: bad gpgFingerprint provided\n");
2142 err = GPG_ERR_GENERAL;
2145 dn = xtryasprintf ("CN=%s,%s", attrval[0], basedn);
2147 else /* The old style way. */
2149 attrval = modlist_lookup (addlist, "pgpCertID");
2150 /* We should have exactly one value. */
2151 if (!attrval || !(attrval[0] && !attrval[1]))
2153 log_error ("ks-ldap: bad pgpCertID provided\n");
2154 err = GPG_ERR_GENERAL;
2157 dn = xtryasprintf ("pgpCertID=%s,%s", attrval[0], basedn);
2161 err = gpg_error_from_syserror ();
2165 log_debug ("ks-ldap: using DN: %s\n", dn);
2168 err = ldap_modify_s (ldap_conn, dn, modlist);
2169 if (err == LDAP_NO_SUCH_OBJECT)
2170 err = ldap_add_s (ldap_conn, dn, addlist);
2175 if (err != LDAP_SUCCESS)
2177 log_error ("ks-ldap: error adding key to keyserver: %s\n",
2178 ldap_err2string (err));
2179 err = ldap_err_to_gpg_err (err);
2188 ldap_unbind (ldap_conn);
2192 modlist_free (modlist);
2195 xfree (data_armored);