/* ks-action.c - OpenPGP keyserver actions
* Copyright (C) 2011 Free Software Foundation, Inc.
* Copyright (C) 2011, 2014 Werner Koch
+ * Copyright (C) 2015 g10 Code GmbH
*
* This file is part of GnuPG.
*
#include "misc.h"
#include "ks-engine.h"
#include "ks-action.h"
-
-
-/* Copy all data from IN to OUT. */
-static gpg_error_t
-copy_stream (estream_t in, estream_t out)
-{
- char buffer[512];
- size_t nread;
-
- while (!es_read (in, buffer, sizeof buffer, &nread))
- {
- if (!nread)
- return 0; /* EOF */
- if (es_write (out, buffer, nread, NULL))
- break;
-
- }
- return gpg_error_from_syserror ();
-}
-
+#if USE_LDAP
+# include "ldap-parse-uri.h"
+#endif
/* Called by the engine's help functions to print the actual help. */
gpg_error_t
}
else
{
- err = http_parse_uri (&parsed_uri, url, 1);
+#if USE_LDAP
+ if (ldap_uri_p (url))
+ err = ldap_parse_uri (&parsed_uri, url);
+ else
+#endif
+ {
+ err = http_parse_uri (&parsed_uri, url, 1);
+ }
+
if (err)
return err;
}
err = ks_finger_help (ctrl, parsed_uri);
if (!err)
err = ks_kdns_help (ctrl, parsed_uri);
+#if USE_LDAP
+ if (!err)
+ err = ks_ldap_help (ctrl, parsed_uri);
+#endif
if (!parsed_uri)
ks_print_help (ctrl,
/* Resolve all host names. This is useful for looking at the status
of configured keyservers. */
gpg_error_t
-ks_action_resolve (ctrl_t ctrl)
+ks_action_resolve (ctrl_t ctrl, uri_item_t keyservers)
{
gpg_error_t err = 0;
int any_server = 0;
uri_item_t uri;
- for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+ for (uri = keyservers; !err && uri; uri = uri->next)
{
if (uri->parsed_uri->is_http)
{
/* Search all configured keyservers for keys matching PATTERNS and
write the result to the provided output stream. */
gpg_error_t
-ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
+ks_action_search (ctrl_t ctrl, uri_item_t keyservers,
+ strlist_t patterns, estream_t outfp)
{
gpg_error_t err = 0;
int any_server = 0;
errors - it might not be the best idea to ignore an error from
one server and silently continue with another server. For now we
stop at the first error. */
- for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+ for (uri = keyservers; !err && uri; uri = uri->next)
{
- if (uri->parsed_uri->is_http)
+ int is_http = uri->parsed_uri->is_http;
+ int is_ldap = 0;
+#if USE_LDAP
+ is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0
+ || strcmp (uri->parsed_uri->scheme, "ldaps") == 0
+ || strcmp (uri->parsed_uri->scheme, "ldapi") == 0);
+#endif
+ if (is_http || is_ldap)
{
any_server = 1;
- err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d, &infp);
+#if USE_LDAP
+ if (is_ldap)
+ err = ks_ldap_search (ctrl, uri->parsed_uri, patterns->d, &infp);
+ else
+#endif
+ {
+ err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d, &infp);
+ }
+
if (!err)
{
err = copy_stream (infp, outfp);
/* Get the requested keys (matching PATTERNS) using all configured
keyservers and write the result to the provided output stream. */
gpg_error_t
-ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
+ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
+ strlist_t patterns, estream_t outfp)
{
gpg_error_t err = 0;
gpg_error_t first_err = 0;
keyservers might not all be fully synced thus it is not clear
whether the first keyserver has the freshest copy of the key.
Need to think about a better strategy. */
- for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+ for (uri = keyservers; !err && uri; uri = uri->next)
{
- if (uri->parsed_uri->is_http)
+ int is_http = uri->parsed_uri->is_http;
+ int is_ldap = 0;
+
+#if USE_LDAP
+ is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0
+ || strcmp (uri->parsed_uri->scheme, "ldaps") == 0
+ || strcmp (uri->parsed_uri->scheme, "ldapi") == 0);
+#endif
+
+ if (is_http || is_ldap)
{
any_server = 1;
for (sl = patterns; !err && sl; sl = sl->next)
{
- err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
+#if USE_LDAP
+ if (is_ldap)
+ err = ks_ldap_get (ctrl, uri->parsed_uri, sl->d, &infp);
+ else
+#endif
+ {
+ err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
+ }
+
if (err)
{
/* It is possible that a server does not carry a
/* Send an OpenPGP key to all keyservers. The key in {DATA,DATALEN}
- is expected in OpenPGP binary transport format. */
+ is expected to be in OpenPGP binary transport format. The metadata
+ in {INFO,INFOLEN} is in colon-separated format (concretely, it is
+ the output of 'for x in keys sigs; do gpg --list-$x --with-colons
+ KEYID; done'. This function may modify DATA and INFO. If this is
+ a problem, then the caller should create a copy. */
gpg_error_t
-ks_action_put (ctrl_t ctrl, const void *data, size_t datalen)
+ks_action_put (ctrl_t ctrl, uri_item_t keyservers,
+ void *data, size_t datalen,
+ void *info, size_t infolen)
{
gpg_error_t err = 0;
gpg_error_t first_err = 0;
int any_server = 0;
uri_item_t uri;
- for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+ (void) info;
+ (void) infolen;
+
+ for (uri = keyservers; !err && uri; uri = uri->next)
{
- if (uri->parsed_uri->is_http)
+ int is_http = uri->parsed_uri->is_http;
+ int is_ldap = 0;
+
+#if USE_LDAP
+ is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0
+ || strcmp (uri->parsed_uri->scheme, "ldaps") == 0
+ || strcmp (uri->parsed_uri->scheme, "ldapi") == 0);
+#endif
+
+ if (is_http || is_ldap)
{
any_server = 1;
- err = ks_hkp_put (ctrl, uri->parsed_uri, data, datalen);
+#if USE_LDAP
+ if (is_ldap)
+ err = ks_ldap_put (ctrl, uri->parsed_uri, data, datalen,
+ info, infolen);
+ else
+#endif
+ {
+ err = ks_hkp_put (ctrl, uri->parsed_uri, data, datalen);
+ }
if (err)
{
first_err = err;