* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "dirmngr.h"
#include "misc.h"
-#include "userids.h"
+#include "../common/userids.h"
#include "ks-engine.h"
#include "ldap-parse-uri.h"
gpg_error_t
ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri)
{
- const char const data[] =
+ const char data[] =
"Handler for LDAP URLs:\n"
" ldap://host:port/[BASEDN]???[bindname=BINDNAME,password=PASSWORD]\n"
"\n"
"Supported methods: search, get, put\n";
gpg_error_t err;
- if (strcmp (uri->scheme, "ldap") == 0
+ if(!uri)
+ err = ks_print_help (ctrl, " ldap");
+ else if (strcmp (uri->scheme, "ldap") == 0
|| strcmp (uri->scheme, "ldaps") == 0
|| strcmp (uri->scheme, "ldapi") == 0)
err = ks_print_help (ctrl, data);
If this function successfully interrogated the server, it returns
0. If there was an LDAP error, it returns the LDAP error code. If
- an error occured, *basednp, etc., are undefined (and don't need to
+ an error occurred, *basednp, etc., are undefined (and don't need to
be freed.)
- If no LDAP error occured, you still need to check that *basednp is
+ If no LDAP error occurred, you still need to check that *basednp is
valid. If it is NULL, then the server does not appear to be an
OpenPGP Keyserver. In this case, you also do not need to xfree
*pgpkeyattrp. */
static int
-ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
- char **basednp, char **pgpkeyattrp, int *real_ldapp)
+my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
+ char **basednp, char **pgpkeyattrp, int *real_ldapp)
{
int err = 0;
char *pgpkeyattr = "pgpKey";
int real_ldap = 0;
- log_debug ("ldap_connect(%s:%d/%s????%s%s%s%s%s)\n",
+ log_debug ("my_ldap_connect(%s:%d/%s????%s%s%s%s%s)\n",
uri->host, uri->port,
uri->path ?: "",
uri->auth ? "bindname=" : "", uri->auth ?: "",
#endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */
#endif
-#ifndef HAVE_LDAP_START_TLS_S
+#ifdef HAVE_LDAP_START_TLS_S
if (uri->use_tls)
{
/* XXX: We need an option to determine whether to abort if the
certificate is bad or not. Right now we conservatively
default to checking the certificate and aborting. */
+#ifndef HAVE_W32_SYSTEM
int check_cert = LDAP_OPT_X_TLS_HARD; /* LDAP_OPT_X_TLS_NEVER */
err = ldap_set_option (ldap_conn,
log_error ("Failed to set TLS option on LDAP connection.\n");
goto out;
}
+#else
+ /* On Windows, the certificates are checked by default. If the
+ option to disable checking mentioned above is ever
+ implemented, the way to do that on Windows is to install a
+ callback routine using ldap_set_option (..,
+ LDAP_OPT_SERVER_CERTIFICATE, ..); */
+#endif
- err = ldap_start_tls_s (ldap_conn, NULL, NULL);
+ err = ldap_start_tls_s (ldap_conn,
+#ifdef HAVE_W32_SYSTEM
+ /* ServerReturnValue, result */
+ NULL, NULL,
+#endif
+ /* ServerControls, ClientControls */
+ NULL, NULL);
if (err)
{
log_error ("Failed to connect to LDAP server with TLS.\n");
(void) ctrl;
+ if (dirmngr_use_tor ())
+ {
+ /* For now we do not support LDAP over Tor. */
+ log_error (_("LDAP access not possible due to Tor mode\n"));
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+ }
+
/* Before connecting to the server, make sure we have a sane
keyspec. If not, there is no need to establish a network
connection. */
return (err);
/* Make sure we are talking to an OpenPGP LDAP server. */
- ldap_err = ldap_connect (uri, &ldap_conn, &basedn, &pgpkeyattr, NULL);
+ ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &pgpkeyattr, NULL);
if (ldap_err || !basedn)
{
if (ldap_err)
(void) ctrl;
+ if (dirmngr_use_tor ())
+ {
+ /* For now we do not support LDAP over Tor. */
+ log_error (_("LDAP access not possible due to Tor mode\n"));
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+ }
+
/* Before connecting to the server, make sure we have a sane
keyspec. If not, there is no need to establish a network
connection. */
}
/* Make sure we are talking to an OpenPGP LDAP server. */
- ldap_err = ldap_connect (uri, &ldap_conn, &basedn, NULL, NULL);
+ ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, NULL, NULL);
if (ldap_err || !basedn)
{
if (ldap_err)
es_fprintf (fp, "pub:%s:",certid[0]);
- vals = ldap_get_values (ldap_conn, each, "pgpkeytype");
- if (vals)
- {
- /* The LDAP server doesn't exactly handle this
- well. */
- if (strcasecmp (vals[0], "RSA") == 0)
- es_fputs ("1", fp);
- else if (strcasecmp (vals[0], "DSS/DH") == 0)
- es_fputs ("17", fp);
- ldap_value_free (vals);
- }
-
- es_fputc (':', fp);
-
- vals = ldap_get_values (ldap_conn, each, "pgpkeysize");
- if (vals)
- {
- /* Not sure why, but some keys are listed with a
- key size of 0. Treat that like an
- unknown. */
- if (atoi (vals[0]) > 0)
- es_fprintf (fp, "%d", atoi (vals[0]));
- ldap_value_free (vals);
- }
-
- es_fputc (':', fp);
-
- /* YYYYMMDDHHmmssZ */
-
- vals = ldap_get_values (ldap_conn, each, "pgpkeycreatetime");
- if(vals && strlen (vals[0]) == 15)
- {
- es_fprintf (fp, "%u",
- (unsigned int) ldap2epochtime(vals[0]));
- ldap_value_free (vals);
- }
-
- es_fputc (':', fp);
-
- vals = ldap_get_values (ldap_conn, each, "pgpkeyexpiretime");
- if (vals && strlen (vals[0]) == 15)
- {
- es_fprintf (fp, "%u",
- (unsigned int) ldap2epochtime (vals[0]));
- ldap_value_free (vals);
- }
-
- es_fputc (':', fp);
-
- vals = ldap_get_values (ldap_conn, each, "pgprevoked");
- if (vals)
- {
- if (atoi (vals[0]) == 1)
- es_fprintf (fp, "r");
- ldap_value_free (vals);
- }
-
- vals = ldap_get_values (ldap_conn, each, "pgpdisabled");
- if (vals)
- {
- if (atoi (vals[0]) ==1)
- es_fprintf (fp, "d");
- ldap_value_free (vals);
- }
+ vals = ldap_get_values (ldap_conn, each, "pgpkeytype");
+ if (vals)
+ {
+ /* The LDAP server doesn't exactly handle this
+ well. */
+ if (strcasecmp (vals[0], "RSA") == 0)
+ es_fputs ("1", fp);
+ else if (strcasecmp (vals[0], "DSS/DH") == 0)
+ es_fputs ("17", fp);
+ ldap_value_free (vals);
+ }
+
+ es_fputc (':', fp);
+
+ vals = ldap_get_values (ldap_conn, each, "pgpkeysize");
+ if (vals)
+ {
+ /* Not sure why, but some keys are listed with a
+ key size of 0. Treat that like an unknown. */
+ if (atoi (vals[0]) > 0)
+ es_fprintf (fp, "%d", atoi (vals[0]));
+ ldap_value_free (vals);
+ }
+
+ es_fputc (':', fp);
+
+ /* YYYYMMDDHHmmssZ */
+
+ vals = ldap_get_values (ldap_conn, each, "pgpkeycreatetime");
+ if(vals && strlen (vals[0]) == 15)
+ {
+ es_fprintf (fp, "%u",
+ (unsigned int) ldap2epochtime(vals[0]));
+ ldap_value_free (vals);
+ }
+
+ es_fputc (':', fp);
+
+ vals = ldap_get_values (ldap_conn, each, "pgpkeyexpiretime");
+ if (vals && strlen (vals[0]) == 15)
+ {
+ es_fprintf (fp, "%u",
+ (unsigned int) ldap2epochtime (vals[0]));
+ ldap_value_free (vals);
+ }
+
+ es_fputc (':', fp);
+
+ vals = ldap_get_values (ldap_conn, each, "pgprevoked");
+ if (vals)
+ {
+ if (atoi (vals[0]) == 1)
+ es_fprintf (fp, "r");
+ ldap_value_free (vals);
+ }
+
+ vals = ldap_get_values (ldap_conn, each, "pgpdisabled");
+ if (vals)
+ {
+ if (atoi (vals[0]) ==1)
+ es_fprintf (fp, "d");
+ ldap_value_free (vals);
+ }
#if 0
- /* This is not yet specified in the keyserver
- protocol, but may be someday. */
- es_fputc (':', fp);
-
- vals = ldap_get_values (ldap_conn, each, "modifytimestamp");
- if(vals && strlen (vals[0]) == 15)
- {
- es_fprintf (fp, "%u",
- (unsigned int) ldap2epochtime (vals[0]));
- ldap_value_free (vals);
- }
+ /* This is not yet specified in the keyserver
+ protocol, but may be someday. */
+ es_fputc (':', fp);
+
+ vals = ldap_get_values (ldap_conn, each, "modifytimestamp");
+ if(vals && strlen (vals[0]) == 15)
+ {
+ es_fprintf (fp, "%u",
+ (unsigned int) ldap2epochtime (vals[0]));
+ ldap_value_free (vals);
+ }
#endif
- es_fprintf (fp, "\n");
-
- /* Now print all the uids that have this certid */
- for (uids = ldap_first_entry (ldap_conn, res);
- uids;
- uids = ldap_next_entry (ldap_conn, uids))
- {
- vals = ldap_get_values (ldap_conn, uids, "pgpcertid");
- if (! vals)
- continue;
-
- if (strcasecmp (certid[0], vals[0]) == 0)
- {
- char **uidvals;
-
- es_fprintf (fp, "uid:");
-
- uidvals = ldap_get_values (ldap_conn,
- uids, "pgpuserid");
- if (uidvals)
- {
- /* Need to escape any colons */
- char *quoted = percent_escape (uidvals[0], NULL);
- es_fputs (quoted, fp);
- xfree (quoted);
- ldap_value_free (uidvals);
- }
-
- es_fprintf (fp, "\n");
- }
-
- ldap_value_free(vals);
- }
+ es_fprintf (fp, "\n");
+
+ /* Now print all the uids that have this certid */
+ for (uids = ldap_first_entry (ldap_conn, res);
+ uids;
+ uids = ldap_next_entry (ldap_conn, uids))
+ {
+ vals = ldap_get_values (ldap_conn, uids, "pgpcertid");
+ if (! vals)
+ continue;
+
+ if (strcasecmp (certid[0], vals[0]) == 0)
+ {
+ char **uidvals;
+
+ es_fprintf (fp, "uid:");
+
+ uidvals = ldap_get_values (ldap_conn,
+ uids, "pgpuserid");
+ if (uidvals)
+ {
+ /* Need to escape any colons */
+ char *quoted = percent_escape (uidvals[0], NULL);
+ es_fputs (quoted, fp);
+ xfree (quoted);
+ ldap_value_free (uidvals);
+ }
+
+ es_fprintf (fp, "\n");
+ }
+
+ ldap_value_free(vals);
+ }
}
ldap_value_free (certid);
/* Dump a modlist to a file. This is useful for debugging. */
static estream_t modlist_dump (LDAPMod **modlist, estream_t output)
- GNUPG_GCC_A_USED;
+ GPGRT_ATTR_USED;
static estream_t
modlist_dump (LDAPMod **modlist, estream_t output)
for ((ptr = (*m)->mod_values), (i = 1); ptr && *ptr; ptr++, i ++)
{
- /* At most about 10 lines. */
+ /* Assuming terminals are about 80 characters wide,
+ display at most about 10 lines of debugging
+ output. If we do trim the buffer, append '...' to
+ the end. */
const int max_len = 10 * 70;
size_t value_len = strlen (*ptr);
- char buffer[max_len + 4];
- char *temp;
- int elided = 0;
- if (value_len > max_len)
- {
- temp = buffer;
- memcpy (temp, *ptr, max_len);
- temp[max_len] = temp[max_len + 1] = temp[max_len + 2] = '.';
- temp[max_len + 3] = 0;
- elided = 1;
- }
- else
- temp = *ptr;
+ int elide = value_len > max_len;
if (multi)
es_fprintf (output, " %d. ", i);
- es_fprintf (output, "`%s'", temp);
- if (elided)
- es_fprintf (output, " (%zd bytes elided)",
+ es_fprintf (output, "`%.*s", max_len, *ptr);
+ if (elide)
+ es_fprintf (output, "...' (%zd bytes elided)",
value_len - max_len);
+ else
+ es_fprintf (output, "'");
es_fprintf (output, "\n");
}
}
fields = strsplit (line, ':', '\0', &field_count);
if (field_count == 1)
- /* We only have a single field. There is definately nothing to
+ /* We only have a single field. There is definitely nothing to
do. */
goto out;
if (is_pub || is_sub)
{
- char *size = fields[2];
- int val = atoi (size);
- size = NULL;
+ char padded[6];
+ int val;
- if (val > 0)
- {
- /* We zero pad this on the left to make PGP happy. */
- char padded[6];
- if (val < 99999 && val > 0)
- {
- snprintf (padded, sizeof padded, "%05u", val);
- size = padded;
- }
- }
-
- if (size)
- {
- if (is_pub || is_sub)
- modlist_add (modlist, "pgpKeySize", size);
- }
+ val = atoi (fields[2]);
+ if (val < 99999 && val > 0)
+ {
+ /* We zero pad this on the left to make PGP happy. */
+ snprintf (padded, sizeof padded, "%05u", val);
+ modlist_add (modlist, "pgpKeySize", padded);
+ }
}
if (is_pub)
}
if (algo)
- {
- if (is_pub)
- modlist_add (modlist, "pgpKeyType", algo);
- }
+ modlist_add (modlist, "pgpKeyType", algo);
}
if (is_pub || is_sub || is_sig)
Check that first and then if it fails, then try
parse_timestamp. */
- if (strptime (create_time, "%Y-%m-%d", &tm))
+ if (!isodate_human_to_tm (create_time, &tm))
create_time = tm2ldaptime (&tm);
else if ((t = parse_timestamp (create_time, &end)) != (time_t) -1
&& *end == '\0')
{
- if (! gmtime_r (&t, &tm))
+
+ if (!gnupg_gmtime (&t, &tm))
create_time = NULL;
else
create_time = tm2ldaptime (&tm);
Check that first and then if it fails, then try
parse_timestamp. */
- if (strptime (expire_time, "%Y-%m-%d", &tm))
+ if (!isodate_human_to_tm (expire_time, &tm))
expire_time = tm2ldaptime (&tm);
else if ((t = parse_timestamp (expire_time, &end)) != (time_t) -1
&& *end == '\0')
{
- if (! gmtime_r (&t, &tm))
+ if (!gnupg_gmtime (&t, &tm))
expire_time = NULL;
else
expire_time = tm2ldaptime (&tm);
/* Elide a warning. */
(void) ctrl;
- ldap_err = ldap_connect (uri, &ldap_conn, &basedn, &pgpkeyattr, &real_ldap);
+ if (dirmngr_use_tor ())
+ {
+ /* For now we do not support LDAP over Tor. */
+ log_error (_("LDAP access not possible due to Tor mode\n"));
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+ }
+
+ ldap_err = my_ldap_connect (uri,
+ &ldap_conn, &basedn, &pgpkeyattr, &real_ldap);
if (ldap_err || !basedn)
{
if (ldap_err)
/* The last line is not \n terminated! Make a copy so we can
add a NUL terminator. */
{
- temp = alloca (infolen + 1);
+ temp = xmalloc (infolen + 1);
memcpy (temp, info, infolen);
info = temp;
newline = (char *) info + infolen;
if (! temp)
assert ((char *) info + infolen - 1 == infoend);
else
- assert (infolen == -1);
+ {
+ assert (infolen == -1);
+ xfree (temp);
+ }
}
modlist_add (&addlist, "objectClass", "pgpKeyInfo");