summaryrefslogtreecommitdiff
path: root/keyserver
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2013-03-27 09:15:23 -0700
committerAnas Nashif <anas.nashif@intel.com>2013-03-27 09:15:23 -0700
commit6576640b55777bd811a12a188b9b1f3c63653799 (patch)
tree7dab5ece3a5bf7ed238e8b0824194ce01b61121e /keyserver
downloadgpg2-6576640b55777bd811a12a188b9b1f3c63653799.tar.gz
gpg2-6576640b55777bd811a12a188b9b1f3c63653799.tar.bz2
gpg2-6576640b55777bd811a12a188b9b1f3c63653799.zip
Imported Upstream version 2.0.19upstream/2.0.19
Diffstat (limited to 'keyserver')
-rw-r--r--keyserver/ChangeLog-20111349
-rw-r--r--keyserver/Makefile.am86
-rw-r--r--keyserver/Makefile.in1076
-rw-r--r--keyserver/curl-shim.c382
-rw-r--r--keyserver/curl-shim.h111
-rwxr-xr-xkeyserver/gpg2keys_mailto.in211
-rwxr-xr-xkeyserver/gpg2keys_test.in97
-rw-r--r--keyserver/gpgkeys_curl.c419
-rw-r--r--keyserver/gpgkeys_finger.c500
-rw-r--r--keyserver/gpgkeys_hkp.c977
-rw-r--r--keyserver/gpgkeys_kdns.c444
-rw-r--r--keyserver/gpgkeys_ldap.c2379
-rw-r--r--keyserver/ksutil.c622
-rw-r--r--keyserver/ksutil.h149
-rw-r--r--keyserver/no-libgcrypt.c107
15 files changed, 8909 insertions, 0 deletions
diff --git a/keyserver/ChangeLog-2011 b/keyserver/ChangeLog-2011
new file mode 100644
index 0000000..b3f96a4
--- /dev/null
+++ b/keyserver/ChangeLog-2011
@@ -0,0 +1,1349 @@
+2011-12-02 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2009-08-26 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_hkp.c: Include util.h.
+ (send_key): Use strconcat to build KEY.
+ (appendable_path): New.
+ (get_name): Use strconcat to build REQUEST.
+ (search_key): Ditto.
+
+ * ksutil.c: Include util.h.
+ (parse_ks_options): Use make_filename_try for the ca-cert-file arg.
+
+2009-07-06 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (main, srv_replace): Minor tweaks to use the
+ DNS-SD names ("pgpkey-http" and "pgpkey-https") in SRV lookups
+ instead of "hkp" and "hkps".
+
+2009-06-24 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_ldap.c (send_key): Do not deep free a NULL modlist.
+ Reported by Fabian Keil.
+
+2009-05-28 David Shaw <dshaw@jabberwocky.com>
+
+ From 1.4:
+
+ * curl-shim.c (curl_slist_append, curl_slist_free_all): New.
+ Simple wrappers around strlist_t to emulate the curl way of doing
+ string lists.
+ (curl_easy_setopt): Handle the curl HTTPHEADER option.
+
+ * gpgkeys_curl.c, gpgkeys_hkp.c (main): Avoid caches to get the
+ most recent copy of the key. This is bug #1061.
+
+2009-05-27 David Shaw <dshaw@jabberwocky.com>
+
+ From 1.4:
+
+ * gpgkeys_hkp.c (srv_replace): New function to transform a SRV
+ hostname to a real hostname.
+ (main): Call it from here for the HAVE_LIBCURL case (without
+ libcurl is handled via the curl-shim).
+
+ * curl-shim.h, curl-shim.c (curl_easy_setopt, curl_easy_perform):
+ Add a CURLOPT_SRVTAG_GPG_HACK (passed through the the http
+ engine).
+
+2009-05-10 David Shaw <dshaw@jabberwocky.com>
+
+ From 1.4:
+
+ * gpgkeys_hkp.c (send_key, get_key, get_name, search_key, main):
+ Add support for SSLized HKP.
+
+ * curl-shim.h (curl_version): No need to provide a version for
+ curl-shim as it always matches the GnuPG version.
+
+ * gpgkeys_curl.c, gpgkeys_hkp.c (main): Show which version of curl
+ we're using as part of --version.
+
+ * gpgkeys_curl.c, gpgkeys_finger.c, gpgkeys_hkp.c,
+ gpgkeys_ldap.c (show_help): Document --version.
+
+2009-05-04 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_mailto.in: Set 'mail-from' as a keyserver-option, rather
+ than the ugly ?from= syntax.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (gpg2keys_curl_LDADD, gpg2keys_hkp_LDADD): Add all
+ standard libs.
+
+2008-10-20 Werner Koch <wk@g10code.com>
+
+ * curl-shim.c (curl_global_init): Mark usused arg.
+ (curl_version_info): Ditto.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_kdns.c: Changed copyright notice to the FSF.
+
+2008-04-21 Werner Koch <wk@g10code.com>
+
+ * ksutil.c (w32_init_sockets) [HAVE_W32_SYSTEM]: New.
+ * curl-shim.c (curl_easy_init) [HAVE_W32_SYSTEM]: Call it.
+ * gpgkeys_finger.c: s/_WIN32/HAVE_W32_SYSTEM/.
+ (init_sockets): Remove.
+ (connect_server) [HAVE_W32_SYSTEM]: Call new function.
+
+2008-04-14 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_curl.c (main), gpgkeys_hkp.c (main): Make sure all
+ libcurl number options are passed as long.
+
+ * curl-shim.c (curl_easy_setopt): Minor tweak to match the real
+ curl better - libcurl uses 'long', not 'unsigned int'.
+
+2008-04-07 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_kdns.c: New.
+ * Makefile.am: Support kdns.
+
+ * no-libgcrypt.c (gcry_strdup): Fix. It was not used.
+
+2008-03-25 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_ldap.c (build_attrs): Take care of char defaulting to
+ unsigned when using hextobyte.
+
+2007-10-25 David Shaw <dshaw@jabberwocky.com> (wk)
+
+ From 1.4 (July):
+
+ * gpgkeys_ldap.c (main): Fix bug in setting up whether to verify
+ peer SSL cert. This used to work with older OpenLDAP, but is now
+ more strictly handled.
+
+ * gpgkeys_ldap.c (search_key, main): Fix bug where searching for
+ foo bar (no quotes) on the command line resulted in searching for
+ "foo\2Abar" due to LDAP quoting. The proper search is "foo*bar".
+
+2007-06-11 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_hkp.c (send_key): Rename eof to r_eof as some Windows
+ header defines such a symbol.
+ (main): Likewise.
+
+2007-06-06 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_ldap.c (send_key, send_key_keyserver): Rename eof to
+ r_eof as some Windows file has such a symbol.
+ (main): Likewise.
+
+2007-05-07 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (gpg2keys_ldap_LDADD): Add GPG_ERROR_LIBS.
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_test.in: Rename to ..
+ * gpg2keys_test.in: .. this.
+ * gpgkeys_mailto.in: Rename to ..
+ * gpg2keys_mailto.in: .. this
+ * Makefile.am: Likewise
+
+2007-03-13 David Shaw <dshaw@jabberwocky.com>
+
+ From STABLE-BRANCH-1-4
+
+ * gpgkeys_curl.c (main): Use curl_version_info to verify that the
+ protocol we're about to use is actually available.
+
+ * curl-shim.h, curl-shim.c (curl_free): Make into a macro.
+ (curl_version_info): New. Only advertises "http" for our shim, of
+ course.
+
+2007-03-09 David Shaw <dshaw@jabberwocky.com>
+
+ From STABLE-BRANCH-1-4
+
+ * gpgkeys_ldap.c (send_key): Missing a free().
+
+ * curl-shim.c (curl_easy_perform): Some debugging items that may
+ be handy.
+
+2006-12-03 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (search_key): HKP keyservers like the 0x to be
+ present when searching by keyID.
+
+2006-11-22 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (gpg2keys_ldap_LDADD): Add jnlib. This is needed
+ for some replacement functions.
+
+2006-11-21 Werner Koch <wk@g10code.com>
+
+ * curl-shim.c (curl_easy_perform): Made BUFLEN and MAXLNE a size_t.
+
+2006-11-05 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (curl_mrindex_writer): Revert previous change.
+ Key-not-found still has a HTML response.
+
+2006-10-24 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (gpg2keys_ldap_CPPFLAGS): Rename second instance to ...
+ (gpg2keys_finger_CPPFLAGS): ... this.
+
+2006-10-20 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Reporder macros for better readability.
+ (gpg2keys_finger_LDADD): Add GPG_ERROR_LIBS.
+
+2006-10-19 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (curl_mrindex_writer): Print a warning if we see
+ HTML coming back from a MR hkp query.
+
+2006-10-17 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Removed W32LIBS as they are included in NETLIBS.
+ Removed PTH_LIBS.
+
+2006-09-26 Werner Koch <wk@g10code.com>
+
+ * curl-shim.c: Adjusted for changes in http.c.
+ (curl_easy_perform): Changed LINE from unsigned char* to char*.
+
+ * Makefile.am (gpg2keys_curl_LDADD, gpg2keys_hkp_LDADD)
+ [FAKE_CURL]: Need to link against common_libs and pth.
+
+ * curl-shim.h, curl-shim.c: Removed license exception as not
+ needed here.
+
+2006-09-22 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_curl.c, gpgkeys_hkp.c, gpgkeys_ldap.c, curl-shim.c:
+ * curl-shim.h, ksutil.c, ksutil.h: Add special license exception
+ for OpenSSL. This helps to avoid license conflicts if OpenLDAP or
+ cURL is linked against OpenSSL and we would thus indirectly link
+ to OpenSSL. This is considered a bug fix and forgives all
+ possible violations, pertaining to this issue, possibly occured in
+ the past.
+
+ * no-libgcrypt.c: Changed license to a simple all permissive one.
+
+ * Makefile.am (gpg2keys_ldap_LDADD): For license reasons do not
+ link against common_libs.
+ (gpg2keys_curl_LDADD, gpg2keys_hkp_LDADD): Ditto.
+ * ksutil.c (ks_hextobyte, ks_toupper, ks_strcasecmp): New.
+ Identical to the ascii_foo versions from jnlib.
+ * gpgkeys_ldap.c: Include assert.h.
+ (main): Replace BUG by assert.
+ (build_attrs): Use ks_hextobyte and ks_strcasecmp.
+
+ * gpgkeys_finger.c (get_key): Resolved signed/unisgned char
+ mismatch.
+
+2006-09-19 Werner Koch <wk@g10code.com>
+
+ * no-libgcrypt.c: New. Taken from ../tools.
+ * Makefile.am: Add no-libgcrypt to all sources.
+
+2006-09-06 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (AM_CFLAGS): Add $(GPG_ERROR_CFLAGS).
+
+2006-08-16 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Renamed all binaries to gpg2keys_*.
+ (gpg2keys_ldap_CPPFLAGS): Add AM_CPPFLAGS.
+
+2006-08-15 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Adjusted to the gnupg2 framework.
+
+2006-08-14 Werner Koch <wk@g10code.com>
+
+ * curl-shil.c, curl-shim.h: Changed to make use of the new http.c
+ API.
+
+ * curl-shim.c (curl_easy_perform): Add missing http_close to the
+ POST case.
+
+2006-07-24 David Shaw <dshaw@jabberwocky.com> (wk)
+
+ * curl-shim.c (curl_easy_perform): Minor cleanup of proxy code.
+
+ * gpgkeys_hkp.c (send_key)
+ * gpgkeys_ldap.c (send_key, send_key_keyserver): Fix string
+ matching problem when the ascii armored form of the key happens to
+ match "KEY" at the beginning of the line.
+
+2006-04-26 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_http.c, gpgkeys_oldhkp.c: Removed.
+
+ * Makefile.am: Don't build gpgkeys_http or gpgkeys_(old)hkp any
+ longer as this is done via curl or fake-curl.
+
+ * ksutil.h, ksutil.c, gpgkeys_hkp.c, gpgkeys_curl.c: Minor
+ #include tweaks as FAKE_CURL is no longer meaningful.
+
+2006-04-10 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (ldap_quote, get_name, search_key): LDAP-quote
+ directly into place rather than mallocing temporary buffers.
+
+ * gpgkeys_ldap.c (get_name): Build strings with strcat rather than
+ using sprintf which is harder to read and modify.
+
+ * ksutil.h, ksutil.c (classify_ks_search): Add
+ KS_SEARCH_KEYID_SHORT and KS_SEARCH_KEYID_LONG to search for a key
+ ID.
+
+ * gpgkeys_ldap.c (search_key): Use it here to flip from pgpUserID
+ searches to pgpKeyID or pgpCertID.
+
+2006-03-27 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c: #define LDAP_DEPRECATED for newer OpenLDAPs so
+ they use the regular old API that is compatible with other LDAP
+ libraries.
+
+2006-03-03 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (main): Fix build problem with non-OpenLDAP LDAP
+ libraries that have TLS.
+
+2006-02-23 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.c (init_ks_options): Default include-revoked and
+ include-subkeys to on, as gpg isn't doing this any longer.
+
+2006-02-22 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (get_name): A GETNAME query turns exact=on to cut
+ down on odd matches.
+
+2006-02-21 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (make_one_attr, build_attrs, send_key): Don't
+ allow duplicate attributes as OpenLDAP is now enforcing this.
+
+ * gpgkeys_ldap.c (main): Add binddn and bindpw so users can pass
+ credentials to a remote LDAP server.
+
+ * curl-shim.h, curl-shim.c (curl_easy_init, curl_easy_setopt,
+ curl_easy_perform): Mingw has 'stderr' as a macro?
+
+ * curl-shim.h, curl-shim.c (curl_easy_init, curl_easy_setopt,
+ curl_easy_perform): Add CURLOPT_VERBOSE and CURLOPT_STDERR for
+ easier debugging.
+
+2006-01-16 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (send_key): Do not escape the '=' in the HTTP POST
+ when uploading a key.
+
+2005-12-23 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.h, ksutil.c (parse_ks_options): New keyserver command
+ "getname".
+
+ * gpgkeys_hkp.c (main, get_name), gpgkeys_ldap.c (main, get_name):
+ Use it here to do direct name (rather than key ID) fetches.
+
+2005-12-19 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.h, ksutil.c (curl_armor_writer, curl_writer,
+ curl_writer_finalize): New functionality to handle binary format
+ keys by armoring them for input to GPG.
+
+ * gpgkeys_curl.c (get_key), gpgkeys_hkp.c (get_key): Call it here.
+
+2005-12-07 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_finger.c (get_key), gpgkeys_curl.c (get_key): Better
+ language for the key-not-found error.
+
+ * ksutil.c (curl_err_to_gpg_err): Add CURLE_OK and
+ CURLE_COULDNT_CONNECT.
+
+ * gpgkeys_curl.c (get_key): Give key-not-found error if no data is
+ found (or file itself is not found) during a fetch.
+
+2005-12-06 David Shaw <dshaw@jabberwocky.com>
+
+ * curl-shim.c (curl_easy_perform): Fix build warning (code before
+ declaration).
+
+2005-11-02 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (search_key): Fix warning with typecast (though
+ curl should really have defined that char * as const).
+
+2005-08-25 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.h, ksutil.c (parse_ks_options): Remove exact-name and
+ exact-email.
+ (classify_ks_search): Mimic the gpg search modes instead with *,
+ =, <, and @.
+
+ * gpgkeys_ldap.c (search_key), gpgkeys_hkp.c (search_key): Call
+ them here. Suggested by Jason Harris.
+
+2005-08-18 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.h, ksutil.c (parse_ks_options): New keyserver-option
+ exact-name. The last of exact-name and exact-email overrides the
+ earlier.
+
+ * gpgkeys_ldap.c (search_key), gpgkeys_hkp.c (search_key): Use it
+ here to do a name-only search.
+
+ * gpgkeys_ldap.c (ldap_quote): \-quote a string for LDAP.
+
+ * gpgkeys_ldap.c (search_key): Use it here to escape reserved
+ characters in searches.
+
+2005-08-17 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.h, ksutil.c (parse_ks_options): New keyserver-option
+ exact-email.
+
+ * gpgkeys_ldap.c (search_key), gpgkeys_hkp.c (search_key): Use it
+ here to do an email-only search.
+
+2005-08-08 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: Include LDAP_CPPFLAGS when building LDAP.
+
+2005-08-03 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (main), gpgkeys_curl.c (main), curl-shim.h: Show
+ version of curl (or curl-shim) when debug is set.
+
+2005-07-20 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_curl.c (get_key, main): Don't try and be smart about
+ what protocols we handle. Directly pass them to curl or fake-curl
+ and see if an error comes back.
+
+ * curl-shim.h, curl-shim.c (handle_error), ksutil.c
+ (curl_err_to_gpg_err): Add support for CURLE_UNSUPPORTED_PROTOCOL
+ in fake curl.
+
+ * Makefile.am: Don't need -DFAKE_CURL any longer since it's in
+ config.h.
+
+2005-06-23 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_mailto.in, gpgkeys_test.in: Use @VERSION@ so version
+ string stays up to date.
+
+ * gpgkeys_http.c: Don't need to define HTTP_PROXY_ENV here since
+ it's in ksutil.h.
+
+ * gpgkeys_curl.c (get_key, main), gpgkeys_hkp.c (main): Pass AUTH
+ values to curl or curl-shim.
+
+ * curl-shim.c (curl_easy_perform), gpgkeys_curl.c (main),
+ gpgkeys_hkp.c (main): Use curl-style proxy semantics.
+
+ * curl-shim.h, curl-shim.c (curl_easy_setopt, curl_easy_perform):
+ Add CURLOPT_USERPWD option for HTTP auth.
+
+ * gpgkeys_http.c (get_key), gpgkeys_oldhkp (send_key, get_key,
+ search_key): No longer need to pass a proxyauth.
+
+ * gpgkeys_http.c (get_key): Pass auth outside of the URL.
+
+2005-06-21 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_http.c (get_key), gpgkeys_oldhkp.c (send_key, get_key,
+ search_key): Fix http_open/http_open_document calls to pass NULL
+ for auth and proxyauth since these programs pass them in the URL.
+
+2005-06-20 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (append_path, send_key, get_key, search_key,
+ main), gpgkeys_oldhkp.c (main): Properly handle double slashes in
+ paths.
+
+2005-06-05 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.c (init_ks_options, parse_ks_options): Provide a default
+ "/" path unless overridden by the config. Allow config to specify
+ items multiple times and take the last specified item.
+
+2005-06-04 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c, gpgkeys_oldhkp.c: Add support for HKP servers
+ that aren't at the root path. Suggested by Jack Bates.
+
+2005-06-01 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.c [HAVE_DOSISH_SYSTEM]: Fix warnings on mingw32. Noted
+ by Joe Vender.
+
+2005-05-04 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.h, ksutil.c: #ifdef so we can build without libcurl or
+ fake-curl.
+
+2005-05-03 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_http.c: Need GET defined.
+
+2005-05-01 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c, gpgkeys_oldhkp.c, ksutil.h: Some minor cleanup
+ and comments as to the size of MAX_LINE and MAX_URL.
+
+2005-04-16 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c: New hkp handler that uses curl or curl-shim.
+
+ * Makefile.am: Build new gpgkeys_hkp.
+
+ * curl-shim.c (curl_easy_perform): Cleanup.
+
+ * ksutil.h, ksutil.c (curl_writer), gpgkeys_curl.c (get_key): Pass
+ a context to curl_writer so we can support multiple fetches in a
+ single session.
+
+ * curl-shim.h, curl-shim.c (handle_error, curl_easy_setopt,
+ curl_easy_perform): Add POST functionality to the curl shim.
+
+ * curl-shim.h, curl-shim.c (curl_escape, curl_free): Emulate
+ curl_escape and curl_free.
+
+ * gpgkeys_curl.c (main): If the http-proxy option is given without
+ any arguments, try to get the proxy from the environment.
+
+ * ksutil.h, ksutil.c (curl_err_to_gpg_err, curl_writer): Copy from
+ gpgkeys_curl.c.
+
+ * gpgkeys_oldhkp.c: Copy from gpgkeys_hkp.c.
+
+2005-03-22 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c, ksutil.h, ksutil.c (print_nocr): Moved from
+ gpgkeys_ldap.c. Print a string, but strip out any CRs.
+
+ * gpgkeys_finger.c (get_key), gpgkeys_hkp.c (get_key),
+ gpgkeys_http.c (get_key): Use it here when outputting key material
+ to canonicalize line endings.
+
+2005-03-19 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (main): Fix three wrong calls to fail_all().
+ Noted by Stefan Bellon.
+
+2005-03-17 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.c (parse_ks_options): Handle verbose=nnn.
+
+ * Makefile.am: Calculate GNUPG_LIBEXECDIR directly. Do not
+ redefine $libexecdir.
+
+ * gpgkeys_curl.c, gpgkeys_finger.c, gpgkeys_ldap.c: Start using
+ parse_ks_options and remove a lot of common code.
+
+ * ksutil.h, ksutil.c (parse_ks_options): Parse OPAQUE, and default
+ debug with no arguments to 1.
+
+2005-03-16 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c: Include lber.h if configure determines we need
+ it.
+
+ * ksutil.h, ksutil.c (ks_action_to_string): New.
+ (free_ks_options): Only free if options exist.
+
+ * ksutil.h, ksutil.c (init_ks_options, free_ks_options,
+ parse_ks_options): Pull a lot of duplicated code into a single
+ options parser for all keyserver helpers.
+
+2005-02-11 David Shaw <dshaw@jabberwocky.com>
+
+ * curl-shim.c (curl_easy_perform): Fix compile warning.
+
+ * curl-shim.h, gpgkeys_curl.c (main), gpgkeys_ldap.c (main): Add
+ ca-cert-file option, to pass in the SSL cert.
+
+ * curl-shim.h, curl-shim.c: New. This is code to fake the curl
+ API in terms of the current HTTP iobuf API.
+
+ * gpgkeys_curl.c [FAKE_CURL], Makefile.am: If FAKE_CURL is set,
+ link with the iobuf code rather than libcurl.
+
+2005-02-05 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_finger.c (main), gpgkeys_hkp.c (main): Fix --version
+ output.
+
+ * gpgkeys_curl.c (main): Make sure the curl handle is cleaned up
+ on failure.
+
+2005-02-01 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (get_key), gpgkeys_http.c (get_key): Fix missing
+ http_close() calls. Noted by Phil Pennock.
+
+ * ksutil.h: Up the default timeout to two minutes.
+
+2005-01-24 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (print_nocr): New.
+ (get_key): Call it here to canonicalize line endings.
+
+ * gpgkeys_curl.c (writer): Discard everything outside the BEGIN
+ and END lines when retrieving keys. Canonicalize line endings.
+ (main): Accept FTPS.
+
+2005-01-21 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (main): Add "check-cert" option to disable SSL
+ certificate checking (which is on by default).
+
+ * gpgkeys_curl.c (main): Add "debug" option to match the LDAP
+ helper. Add "check-cert" option to disable SSL certificate
+ checking (which is on by default).
+
+2005-01-18 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_curl.c: Fix typo.
+
+2005-01-18 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_curl.c: s/MAX_PATH/URLMAX_PATH/g to avoid a clash with
+ the W32 defined macro. Removed unneeded initialization of static
+ variables.
+ * gpgkeys_http.c: Ditto.
+ * ksutil.h: s/MAX_PATH/URLMAX_PATH/.
+
+2005-01-17 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_curl.c (main): Only allow specified protocols to use the
+ curl handler.
+
+ * Makefile.am: Use LIBCURL_CPPFLAGS instead of LIBCURL_INCLUDES.
+
+2005-01-13 David Shaw <dshaw@jabberwocky.com>
+
+ * ksutil.h, gpgkeys_curl.c, gpgkeys_hkp.c, gpgkeys_ldap.c,
+ gpgkeys_finger.c, gpgkeys_http.c: Part 2 of the cleanup. Move all
+ the various defines to ksutil.h.
+
+ * gpgkeys_finger.c, gpgkeys_hkp.c, gpgkeys_http.c, gpgkeys_ldap.c:
+ Part 1 of a minor cleanup to use #defines instead of hard-coded
+ sizes.
+
+ * gpgkeys_finger.c (connect_server): Use INADDR_NONE instead of
+ SOCKET_ERROR. Noted by Timo.
+
+2005-01-09 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_curl.c (get_key): Newer versions of libcurl don't define
+ TRUE.
+
+2004-12-24 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_curl.c (main): Use new defines for opting out of certain
+ transfer protocols. Allow setting HTTP proxy via "http-proxy=foo"
+ option (there is natural support in libcurl for the http_proxy
+ environment variable).
+
+ * Makefile.am: Remove the conditional since this is all handled in
+ autoconf now.
+
+2004-12-22 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_curl.c (main): New "follow-redirects" option. Takes an
+ optional numeric value for the maximum number of redirects to
+ allow. Defaults to 5.
+
+ * gpgkeys_curl.c (main), gpgkeys_finger.c (main), gpgkeys_hkp.c
+ (main), gpgkeys_http.c (main), gpgkeys_ldap.c (main): Make sure
+ that a "timeout" option passed with no arguments is properly
+ handled.
+
+ * gpgkeys_curl.c (get_key, writer): New function to wrap around
+ fwrite to avoid DLL access problem on win32.
+
+ * gpgkeys_http.c (main, get_key): Properly pass authentication
+ info through to the http library.
+
+ * Makefile.am: Build gpgkeys_http or gpgkeys_curl as needed.
+
+ * gpgkeys_curl.c (main, get_key): Minor tweaks to work with either
+ FTP or HTTP.
+
+ * gpgkeys_ftp.c: renamed to gpgkeys_curl.c.
+
+ * gpgkeys_ftp.c (main, get_key): Use auth data as passed by gpg.
+ Use CURLOPT_FILE instead of CURLOPT_WRITEDATA (same option, but
+ backwards compatible).
+
+2004-12-21 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ftp.c: New.
+
+ * Makefile.am: Build it if requested.
+
+2004-12-14 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (install-exec-hook, uninstall-hook): Removed. For
+ Windows reasons we can't use the symlink trick.
+
+2004-12-03 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: The harmless "ignored error" on gpgkeys_ldap
+ install on top of an existing install is bound to confuse people.
+ Use ln -s -f to force the overwrite.
+
+2004-10-28 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_finger.c [_WIN32] (connect_server): Fix typo.
+
+2004-10-28 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (other_libs): New. Also include LIBICONV. Noted by
+ Tim Mooney.
+
+2004-10-28 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (other_libs):
+
+2004-10-18 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (send_key, get_key, search_key): Use "hkp" instead
+ of "x-hkp" so it can be used as a SRV tag.
+
+2004-10-16 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_finger.c [_WIN32] (connect_server): Fix typo.
+
+2004-10-15 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_ldap.c (main, show_help): Kludge to implement standard
+ GNU options. Factored help printing out.
+ * gpgkeys_finger.c (main, show_help): Ditto.
+ * gpgkeys_hkp.c (main, show_help): Ditto.
+ * gpgkeys_http.c (main, show_help): Ditto.
+ * gpgkeys_test.in, gpgkeys_mailto.in: Implement --version and --help.
+
+ * Makefile.am: Add ksutil.h.
+
+2004-10-14 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_finger.c (main): We do not support relay fingering
+ (i.e. "finger://relayhost/user@example.com"), but finger URLs are
+ occasionally miswritten that way. Give an error in this case.
+
+2004-10-14 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_finger.c (get_key): s/unsigned char/byte/ due
+ to a strange typedef for RISC OS. Noted by Stefan.
+
+2004-10-13 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (main), gpgkeys_hkp.c (main), gpgkeys_http.c
+ (main), gpgkeys_finger.c (main): Call timeout functions before
+ performing an action that could block for a long time.
+
+ * ksutil.h, ksutil.c: New. Right now just contains timeout
+ functions.
+
+2004-10-11 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_finger.c, gpgkeys_hkp.c, gpgkeys_http.c, gpgkeys_ldap.c:
+ Fix a few occurances of "filename" to `filename'.
+
+2004-10-11 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_finger.c: New.
+
+2004-08-27 Stefan Bellon <sbellon@sbellon.de>
+
+ * gpgkeys_hkp.c (search_key): Fix the prior faulty fix by
+ introducing a cast but leaving skey unsigned.
+
+ * gpgkeys_hkp.c (search_key): Change type of variable skey from
+ unsigned char* to char* to fix type incompatibility.
+
+2004-08-23 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (get_key, search_key), gpgkeys_hkp.c (get_key,
+ search_key), gpgkeys_http.c (get_key): Do not give informational
+ logs since this is now done inside gpg.
+
+ * gpgkeys_hkp.c (dehtmlize): Understand the quote character
+ (i.e. "&quot;") in HTML responses.
+ (search_key): Search key must be unsigned for url encoder to work
+ properly for 8-bit values.
+
+ * gpgkeys_ldap.c (get_key): Factor out informational display into
+ new function build_info().
+
+ * gpgkeys_ldap.c (build_attrs): Properly terminate user ID strings
+ that got shrunk due to encoding.
+
+2004-08-22 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (find_basekeyspacedn): Use LDAP_SCOPE_BASE along
+ with a full DN rather than LDAP_SCOPE_ONELEVEL plus a filter to
+ find the pgpServerInfo object. Some LDAP setups don't like the
+ search.
+ (main): Stop binding to the server since it seems no server really
+ requires it, and some require it not be there.
+
+2004-07-29 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (main): Add "debug" option. This is only really
+ useful with OpenLDAP, but it's practically vital to debug SSL and
+ TLS setups. Add "basedn" option. This allows users to override
+ the autodetection for base DN. SSL overrides TLS, so TLS will not
+ be started on SSL connections (starting an already started car).
+
+2004-07-28 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (build_attrs): Add "pgpKeySize" and "pgpSubKeyID"
+ attributes so we can do subkey searches.
+
+ * gpgkeys_ldap.c (main): Under certain error conditions, we might
+ try and unbind twice. Don't.
+
+ * gpgkeys_ldap.c (join_two_modlists): New.
+ (send_key): Use new function so we can try a modify operation
+ first, and fail over to an add if that fails. Add cannot cope
+ with the NULLs at the head of the modify request, so we jump into
+ the list in the middle.
+
+2004-07-27 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (main): Don't try and error out before making a
+ ldaps connection to the NAI keyserver since we cannot tell if it
+ is a NAI keyserver until we connect. Fail if we cannot find a
+ base keyspace DN. Fix a false success message for TLS being
+ enabled.
+
+2004-07-20 Werner Koch <wk@gnupg.org>
+
+ * gpgkeys_ldap.c [_WIN32]: Include Windows specific header files.
+ Suggested by Brian Gladman.
+
+2004-05-26 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_http.c: General polish and removal of leftover stuff
+ from gpgkeys_hkp.c.
+
+2004-05-21 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_http.c (get_key): Cosmetic fix - make sure that URLs
+ with no path use a path of "/".
+
+ * gpgkeys_ldap.c (ldap2epochtime): We can always rely on timegm()
+ being available now, since it's a replacement function.
+
+2004-05-20 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_http.c: New program to do a simple HTTP file fetch using
+ the keyserver interface.
+
+ * Makefile.am: Build it.
+
+2004-02-28 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: Don't split LDADD across two lines since some make
+ programs can't handle blank lines after a \ continuation. Noted
+ by Christoph Moench-Tegeder.
+
+2004-02-25 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (send_key): List pgpCertID as one of the deleted
+ attributes. This guarantees that if something goes wrong, we
+ won't be able to complete the transaction, thus leaving any key
+ already existing on the server intact.
+
+2004-02-23 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (delete_one_attr): Removed.
+ (make_one_attr): Delete functionality added. Optional deduping
+ functionality added (currently only used for pgpSignerID).
+ (build_attrs): Translate sig entries into pgpSignerID. Properly
+ build the timestamp for pgpKeyCreateTime and pgpKeyExpireTime.
+
+2004-02-22 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (delete_one_attr): New function to replace
+ attributes with NULL (a "delete" that works even for nonexistant
+ attributes).
+ (send_key): Use it here to remove attributes so a modify operation
+ starts with a clean playing field. Bias sends to modify before
+ add, since (I suspect) people update their existing keys more
+ often than they make and send new keys to the server.
+
+2004-02-21 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (epoch2ldaptime): New. Converse of
+ ldap2epochtime.
+ (make_one_attr): New. Build a modification list in memory to send
+ to the LDAP server.
+ (build_attrs): New. Parse INFO lines sent over by gpg.
+ (free_mod_values): New. Unwinds a modification list.
+ (send_key_keyserver): Renamed from old send_key().
+ (send_key): New function to send a key to a LDAP server.
+ (main): Use send_key() for real LDAP servers, send_key_keyserver()
+ otherwise.
+
+2004-02-20 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c: Replacement prototypes for setenv and unsetenv.
+ (search_key): Catch a SIZELIMIT_EXCEEDED error and show the user
+ whatever the server did give us.
+ (find_basekeyspacedn): There is no guarantee that namingContexts
+ will be readable.
+
+ * Makefile.am: Link gpgkeys_ldap with libutil.a to get the
+ replacement functions (and eventually translations, etc).
+
+2004-02-19 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (ldap2epochtime): LDAP timestamps are UTC, so do
+ not correct for timezones.
+ (main): Find the basekeyspacedn before we try to start TLS, so we
+ can give a better error message when a user tries to use TLS with
+ a LDAP keyserver.
+
+ * Makefile.am: Add automake conditionals to symlink gpgkeys_ldaps
+ to gpgkeys_ldap when needed.
+
+ * gpgkeys_ldap.c (main): Add support for LDAPS and TLS
+ connections. These are only useful and usable when talking to
+ real LDAP keyservers. Add new "tls" option to tune TLS use from
+ off, to try quietly, to try loudly, or to require TLS.
+
+ * gpgkeys_ldap.c (find_basekeyspacedn): New function to figure out
+ what kind of LDAP server we're talking to (either real LDAP or the
+ LDAP keyserver), and return the baseKeySpaceDN to find keys under.
+ (main): Call it from here, and remove the old code that only
+ handled the LDAP keyserver.
+
+2004-02-18 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (ldap_to_gpg_err): Make sure that
+ LDAP_OPT_ERROR_NUMBER is defined before we use it.
+
+ * gpgkeys_mailto.in: Fix VERSION number.
+
+2004-01-13 Werner Koch <wk@gnupg.org>
+
+ * gpgkeys_hkp.c (send_key): Add a content type.
+
+2004-01-11 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (search_key): Catch a mangled input file (useful
+ if something other than GnuPG is calling the program).
+ (main): Avoid possible pre-string write. Noted by Christian
+ Biere.
+
+ * gpgkeys_ldap.c (main): Avoid possible pre-string write.
+
+2003-12-28 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (send_key, get_key, main): Work with new HTTP code
+ that passes the proxy in from the outside. If the command file
+ sends a proxy, use it. If it sends "http-proxy" with no
+ arguments, use $http_proxy from the environment. Suggested by
+ Christian Biere.
+
+2003-12-28 Stefan Bellon <sbellon@sbellon.de>
+
+ * gpgkeys_hkp.c, gpgkeys_ldap.c [__riscos__]: Removal of
+ unnecessary #ifdef __riscos__ sections.
+
+2003-11-27 Werner Koch <wk@gnupg.org>
+
+ * gpgkeys_hkp.c (get_key): Fixed invalid use of fprintf without
+ format string.
+
+2003-10-25 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (gpgkeys_hkp_LDADD): Replaced INTLLIBS by LIBINTL.
+
+2003-07-10 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: Use W32LIBS where appropriate.
+
+2003-05-30 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c, gpgkeys_ldap.c: #include <getopt.h> if it is
+ available. Also include extern references for optarg and optind
+ since there is no guarantee that any header file will include
+ them. Standards? We don't need no stinkin' standards.
+
+ * Makefile.am: Use @GETOPT@ to pull in libiberty on those
+ platforms that need it.
+
+2003-04-08 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (dehtmlize, parse_hkp_index): Fix memory
+ corruption bug on some platforms.
+
+2003-03-11 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (get_key): Properly handle CRLF line endings in
+ the armored key.
+ (main): Accept "try-dns-srv" option.
+
+ * Makefile.am: Use @CAPLIBS@ to link in -lcap if we are using
+ capabilities. Use @SRVLIBS@ to link in the resolver if we are
+ using DNS SRV.
+
+2003-02-11 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: Use a local copy of libexecdir along with @PACKAGE@
+ so it can be easily overridden at make time.
+
+2003-01-29 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_mailto.in: Fix regexp to work properly if the "keyid" is
+ not a keyid, but rather a text string from the user ID.
+
+2003-01-06 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (get_key): Use options=mr when getting a key so
+ keyserver doesn't attach the HTML header which we will just have
+ to discard.
+
+2002-11-17 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (main), gpgkeys_hkp.c (main): Use new keyserver
+ protocol version.
+
+2002-11-14 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (get_key): The deduping code requires
+ "pgpcertid", but that was not available when running without
+ verbose on. Noted by Stefan.
+
+2002-11-10 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (get_key): Fix typo in deduping code.
+
+2002-11-05 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (key_in_keylist, add_key_to_keylist,
+ free_keylist, get_key, search_key): The LDAP keyserver doesn't
+ remove duplicates, so remove them locally. Do not include the key
+ modification time in the search response.
+
+2002-11-04 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (send_key), gpgkeys_ldap.c (send_key): Properly
+ handle an input file that does not include any key data at all.
+
+2002-10-24 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (main), gpgkeys_ldap.c (main): Add -V flag to
+ output protocol and program version.
+
+2002-10-21 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: Anything linking with libutil.a needs INTLLIBS as
+ well on platforms where INTLLIBS is set.
+
+2002-10-14 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (write_quoted): Use %-encoding instead of
+ \-encoding.
+ (parse_hkp_index): Use new keyserver key listing format, and add
+ support for disabled keys via include-disabled.
+
+ * gpgkeys_ldap.c (get_key): Don't print keysize unless it's >0.
+ (printquoted): Use %-encoding instead of \-encoding.
+ (search_key): Use new keyserver key listing format.
+
+2002-10-08 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (search_key, main): Make sure LDAP values are
+ freed in case of error.
+
+ * gpgkeys_ldap.c (fail_all): New function to unwind a keylist and
+ error each item.
+ (main): Call fail_all from here, as needed. Also add a NO_MEMORY
+ error in an appropriate place and fix error return code.
+ (ldap_err_to_gpg_err): Add KEYSERVER_UNREACHABLE.
+
+ * gpgkeys_hkp.c (fail_all): New function to unwind a keylist and
+ error each item.
+ (main): Call fail_all from here. Also add a NO_MEMORY error in an
+ appropriate place.
+ (get_key): Use new UNREACHABLE error for network errors.
+
+2002-09-26 Werner Koch <wk@gnupg.org>
+
+ * gpgkeys_ldap.c (send_key): Removed non-constant initializers.
+
+2002-09-24 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (ldap_err_to_gpg_err, ldap_to_gpg_err, send_key,
+ get_key, search_key, main): Some minor error reporting
+ enhancements for use with GPA (show reasons for KEY FAILED).
+
+ * gpgkeys_hkp.c (send_key, get_key, search_key, main): Some minor
+ error reporting enhancements for use with GPA (show reasons for
+ KEY FAILED).
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ * gpgkeys_hkp.c (handle_old_hkp_index): s/input/inp/ to avoid
+ shadowing warning.
+
+2002-09-19 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (get_key, handle_old_hkp_index, search_key):
+ Properly handle line truncation.
+
+2002-09-16 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_mailto.in: Add quasi-RFC-2368 mailto:email@addr?from=
+ syntax so people can set their own email address to respond to.
+
+ * gpgkeys_hkp.c (get_key): Properly respond with KEY FAILED (to
+ gpg) and "key not found" (to user) on failure.
+
+2002-09-13 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c: (search_key, handle_old_hkp_index): Try and
+ request a machine-readable key index. If the server supports
+ this, pass it through. If the server does not support it, parse
+ the "index" page.
+
+2002-09-12 Stefan Bellon <sbellon@sbellon.de>
+
+ * gpgkeys_hkp.c: Tidied up RISC OS initializations.
+
+2002-09-12 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (main): Remove warning - this is no longer
+ experimental code.
+
+2002-09-09 Werner Koch <wk@gnupg.org>
+
+ * gpgkeys_hkp.c (send_key, get_key, search_key): Check return
+ value of malloc.
+ (dehtmlize): Use ascii_tolower to protect against weird locales.
+ Cast the argument for isspace for the sake of broken HP/UXes.
+ (search_key): Check return value of realloc.
+
+2002-09-09 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (get_key): Some compilers (RISC OS, HPUX c89)
+ don't like using variables as array initializers.
+
+ * gpgkeys_hkp.c (send_key): Use CRLF in headers.
+
+2002-08-28 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (parse_hkp_index): Use same types on all
+ platforms. This was probably leftover from earlier code where the
+ typing mattered.
+
+ * gpgkeys_hkp.c: Overall cleanup from iobuf conversion. Be
+ consistent in m_alloc and malloc usage. Remove include-disabled
+ (meaningless on HKP). RISC OS tweak.
+
+2002-08-27 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c, Makefile.am: Convert over to using iobufs.
+
+ * gpgkeys_hkp.c (http_get, http_post): Use CRLF for line endings.
+
+ * gpgkeys_hkp.c: Include util.h on RISC OS as per Stefan. Include
+ a replacement for hstrerror() for those platforms (such as RISC
+ OS) that don't have it.
+
+2002-08-26 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: May as well include gpgkeys_hkp.c in the
+ distribution now. It works well enough without proxies, and isn't
+ built by default. It would be good to get some test experience
+ with it.
+
+ * gpgkeys_hkp.c (main): Don't warn about include-subkeys - it
+ isn't unsupported, it's actually non-meaningful in the context of
+ HKP (yet).
+
+ * gpgkeys_hkp.c (parse_hkp_index, dehtmlize): Move HTML
+ functionality into new "dehtmlize" function. Remove HTML before
+ trying to parse each line from the keyserver. If the keyserver
+ provides key type information in the listing, use it. (Copy over
+ from g10/hkp.c).
+
+2002-08-19 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (get_key, parse_hkp_index): Bring over latest code
+ from g10/hkp.c.
+
+ * gpgkeys_ldap.c (get_key): Fix cosmetic URL display problem
+ (extra ":" at the end).
+
+2002-08-03 Stefan Bellon <sbellon@sbellon.de>
+
+ * gpgkeys_ldap.c: Tidied up RISC OS initializations.
+
+2002-07-25 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c: "Warning" -> "WARNING"
+
+2002-07-24 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: Install keyserver helpers in @GNUPG_LIBEXECDIR@
+
+2002-07-15 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (send_key, get_key, main): Consult the server
+ version string to determine whether to use pgpKey or pgpKeyV2.
+
+2002-07-09 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_mailto.in: Use new OPAQUE tag for non net-path URIs.
+ Fail more elegantly if there is no email address to send to. Show
+ the GnuPG version in the message body.
+
+2002-07-04 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (get_key), gpgkeys_hkp.c (get_key): Display
+ keyserver URI as a URI, but only if verbose.
+
+2002-07-01 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (parse_hkp_index): Error if the keyserver returns
+ an unparseable HKP response.
+
+ * gpgkeys_hkp.c (main): Warn on honor-http-proxy,
+ broken-http-proxy, and include-subkeys (not supported yet).
+
+ * gpgkeys_ldap.c (main), gpgkeys_hkp.c (http_connect, main): Fix
+ some shadowing warnings.
+
+2002-06-11 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am: Don't hard-code the LDAP libraries - get them from
+ LDAPLIBS via configure. Also, gpgkeys_hkp is a program, not a
+ script.
+
+2002-06-10 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (include_subkeys): Default "include-subkeys" to
+ off, since GnuPG now defaults it to on.
+
+2002-06-06 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_hkp.c (parse_hkp_index): Type tweaks.
+
+ * gpgkeys_hkp.c (main): Add experimental code warning.
+
+2002-06-05 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am, gpgkeys_hkp.c (new): Experimental HKP keyserver
+ interface.
+
+2002-05-08 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c: Include <lber.h> if we absolutely must. This
+ helps when compiling against a very old OpenLDAP.
+
+2002-04-29 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_mailto.in: Properly handle key requests in full
+ fingerprint form.
+
+2002-03-29 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (printquoted): Quote backslashes within keyserver
+ search responses.
+
+2002-02-25 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap (get_key): LDAP keyservers do not support v3
+ fingerprints, so error out if someone tries. Actually, they don't
+ support any fingerprints, but at least we can calculate a keyid
+ from a v4 fingerprint.
+
+2002-02-23 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap: Clarify the notion of a partial failure. This is
+ possible if more than one key is being handled in a batch, and one
+ fails while the other succeeds. Note that a search that comes up
+ with no results is not a failure - that is a valid response of "no
+ answer".
+
+ * gpgkeys_ldap.c (get_key): Allow GnuPG to send us full v4
+ fingerprints, long key ids, or short key ids while fetching.
+ Since the LDAP server doesn't actually handle fingerprints, chop
+ them down to long key ids for actual use.
+
+ * gpgkeys_ldap.c (main, get_key): When searching for a keyid,
+ search for subkeys as well as primary keys. This is mostly
+ significant when automatically fetching the key based on the id in
+ a header (i.e. "signature made by...."). "no-include-subkeys"
+ disables.
+
+2002-02-14 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c: Fix compiler warning.
+
+ * gpgkeys_ldap.c: Be much more robust with mangled input files.
+
+2001-12-28 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_mailto.in: Use the new OUTOFBAND indicator so gpg knows
+ not to try and import anything. Also turn on perl -w for
+ warnings.
+
+ * gpgkeys_ldap.c (main): If we're using temp files (rather than
+ stdin/stdout), make sure the file is closed when we're done.
+
+2001-12-20 David Shaw <dshaw@jabberwocky.com>
+
+ * Properly free the LDAP response when we're done with it.
+
+ * Now that we handle multiple keys, we must remove duplicates as
+ the LDAP keyserver returns keys with multiple user IDs multiple
+ times.
+
+ * Properly handle multiple keys with the same key ID (it's really
+ rare, so fetch "0xDEADBEEF" to test this).
+
+2001-12-17 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c, gpgkeys_mailto.in: Fix GNU capitalization
+ issues. Prefix log messages with "gpgkeys" to clarify which
+ program is generating them.
+
+2001-12-14 David Shaw <dshaw@jabberwocky.com>
+
+ * gpgkeys_ldap.c (search_key): Use unsigned int rather than uint
+ for portability.
+
+2001-12-04 David Shaw <dshaw@jabberwocky.com>
+
+ * Initial version of gpgkeys_ldap (LDAP keyserver helper) and
+ gpgkeys_mailto (email keyserver helper)
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2007 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/keyserver/Makefile.am b/keyserver/Makefile.am
new file mode 100644
index 0000000..e625127
--- /dev/null
+++ b/keyserver/Makefile.am
@@ -0,0 +1,86 @@
+# Makefile.am - Makefile for keyservers
+# Copyright (C) 2001, 2002, 2004, 2005, 2006,
+# 2009 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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/>.
+## Process this file with automake to produce Makefile.in
+
+# Note that we have renamed the resulting binaries to from gpgkeys_foo
+# to gpg2keys_foo to allow for a non-conflicting installation of
+# gnupg1 and gnupg2. Having the same names for the helpers would
+# otherwise lead to trouble when to uninstall one of them.
+EXTRA_PROGRAMS = gpg2keys_ldap gpg2keys_hkp gpg2keys_finger gpg2keys_curl \
+ gpg2keys_kdns
+EXTRA_SCRIPTS = gpg2keys_mailto
+
+EXTRA_DIST = ChangeLog-2011
+
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl
+
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
+
+include $(top_srcdir)/am/cmacros.am
+
+libexec_PROGRAMS = $(GPGKEYS_LDAP) $(GPGKEYS_HKP) $(GPGKEYS_FINGER) \
+ $(GPGKEYS_CURL) $(GPGKEYS_KDNS)
+libexec_SCRIPTS = $(GPGKEYS_MAILTO)
+noinst_SCRIPTS = gpg2keys_test
+
+common_libs = ../gl/libgnu.a ../common/libcommon.a ../jnlib/libjnlib.a
+other_libs = $(LIBICONV) $(LIBINTL) $(CAPLIBS)
+
+gpg2keys_ldap_SOURCES = gpgkeys_ldap.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_ldap_CPPFLAGS = $(LDAP_CPPFLAGS) $(AM_CPPFLAGS)
+gpg2keys_ldap_LDADD = ../jnlib/libjnlib.a $(LDAPLIBS) $(GPG_ERROR_LIBS) \
+ $(NETLIBS) $(other_libs)
+
+gpg2keys_finger_SOURCES = gpgkeys_finger.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_finger_CPPFLAGS = $(AM_CPPFLAGS)
+gpg2keys_finger_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
+ $(NETLIBS) $(other_libs)
+
+gpg2keys_kdns_SOURCES = gpgkeys_kdns.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_kdns_CPPFLAGS = $(AM_CPPFLAGS)
+gpg2keys_kdns_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
+ $(ADNSLIBS) $(NETLIBS) $(other_libs)
+
+
+gpg2keys_curl_SOURCES = gpgkeys_curl.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_hkp_SOURCES = gpgkeys_hkp.c ksutil.c ksutil.h no-libgcrypt.c
+if FAKE_CURL
+gpg2keys_curl_SOURCES += curl-shim.c curl-shim.h
+gpg2keys_curl_CPPFLAGS = $(AM_CPPFLAGS)
+gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+ $(other_libs)
+gpg2keys_hkp_SOURCES += curl-shim.c curl-shim.h
+gpg2keys_hkp_CPPFLAGS = $(AM_CPPFLAGS)
+gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+ $(other_libs)
+else
+# Note that we need to include all other libs here as well because
+# some compilers don't care about inline functions and insert
+# references to symbols used in unused inline functions.
+gpg2keys_curl_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS)
+gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+ $(other_libs) $(LIBCURL) $(GETOPT)
+gpg2keys_hkp_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS)
+gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+ $(other_libs) $(LIBCURL) $(GETOPT)
+endif
+
+# Make sure that all libs are build before we use them. This is
+# important for things like make -j2.
+$(PROGRAMS): $(common_libs)
diff --git a/keyserver/Makefile.in b/keyserver/Makefile.in
new file mode 100644
index 0000000..f1789df
--- /dev/null
+++ b/keyserver/Makefile.in
@@ -0,0 +1,1076 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am - Makefile for keyservers
+# Copyright (C) 2001, 2002, 2004, 2005, 2006,
+# 2009 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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/>.
+
+# cmacros.am - C macro definitions
+# Copyright (C) 2004 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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/>.
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+EXTRA_PROGRAMS = gpg2keys_ldap$(EXEEXT) gpg2keys_hkp$(EXEEXT) \
+ gpg2keys_finger$(EXEEXT) gpg2keys_curl$(EXEEXT) \
+ gpg2keys_kdns$(EXEEXT)
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/gpg2keys_mailto.in $(srcdir)/gpg2keys_test.in \
+ $(top_srcdir)/am/cmacros.am
+@HAVE_DOSISH_SYSTEM_FALSE@am__append_1 = -DGNUPG_BINDIR="\"$(bindir)\"" \
+@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \
+@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \
+@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \
+@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\""
+
+
+# If a specific protect tool program has been defined, pass its name
+# to cc. Note that these macros should not be used directly but via
+# the gnupg_module_name function.
+@GNUPG_AGENT_PGM_TRUE@am__append_2 = -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\""
+@GNUPG_PINENTRY_PGM_TRUE@am__append_3 = -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\""
+@GNUPG_SCDAEMON_PGM_TRUE@am__append_4 = -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\""
+@GNUPG_DIRMNGR_PGM_TRUE@am__append_5 = -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\""
+@GNUPG_PROTECT_TOOL_PGM_TRUE@am__append_6 = -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\""
+@FAKE_CURL_TRUE@am__append_7 = curl-shim.c curl-shim.h
+@FAKE_CURL_TRUE@am__append_8 = curl-shim.c curl-shim.h
+subdir = keyserver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/gl/m4/absolute-header.m4 \
+ $(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/allocsa.m4 \
+ $(top_srcdir)/gl/m4/eealloc.m4 \
+ $(top_srcdir)/gl/m4/gnulib-comp.m4 \
+ $(top_srcdir)/gl/m4/gnulib-tool.m4 \
+ $(top_srcdir)/gl/m4/mkdtemp.m4 $(top_srcdir)/gl/m4/setenv.m4 \
+ $(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/strpbrk.m4 \
+ $(top_srcdir)/gl/m4/unistd_h.m4 $(top_srcdir)/m4/autobuild.m4 \
+ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/estream.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gnupg-pth.m4 \
+ $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \
+ $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \
+ $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \
+ $(top_srcdir)/m4/longdouble.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/size_max.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/m4/xsize.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = gpg2keys_mailto gpg2keys_test
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libexecdir)"
+PROGRAMS = $(libexec_PROGRAMS)
+am__gpg2keys_curl_SOURCES_DIST = gpgkeys_curl.c ksutil.c ksutil.h \
+ no-libgcrypt.c curl-shim.c curl-shim.h
+@FAKE_CURL_TRUE@am__objects_1 = gpg2keys_curl-curl-shim.$(OBJEXT)
+am_gpg2keys_curl_OBJECTS = gpg2keys_curl-gpgkeys_curl.$(OBJEXT) \
+ gpg2keys_curl-ksutil.$(OBJEXT) \
+ gpg2keys_curl-no-libgcrypt.$(OBJEXT) $(am__objects_1)
+gpg2keys_curl_OBJECTS = $(am_gpg2keys_curl_OBJECTS)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+@FAKE_CURL_FALSE@gpg2keys_curl_DEPENDENCIES = $(common_libs) \
+@FAKE_CURL_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@FAKE_CURL_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
+@FAKE_CURL_FALSE@ $(am__DEPENDENCIES_1)
+@FAKE_CURL_TRUE@gpg2keys_curl_DEPENDENCIES = $(common_libs) \
+@FAKE_CURL_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@FAKE_CURL_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+am_gpg2keys_finger_OBJECTS = gpg2keys_finger-gpgkeys_finger.$(OBJEXT) \
+ gpg2keys_finger-ksutil.$(OBJEXT) \
+ gpg2keys_finger-no-libgcrypt.$(OBJEXT)
+gpg2keys_finger_OBJECTS = $(am_gpg2keys_finger_OBJECTS)
+gpg2keys_finger_DEPENDENCIES = $(common_libs) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+am__gpg2keys_hkp_SOURCES_DIST = gpgkeys_hkp.c ksutil.c ksutil.h \
+ no-libgcrypt.c curl-shim.c curl-shim.h
+@FAKE_CURL_TRUE@am__objects_2 = gpg2keys_hkp-curl-shim.$(OBJEXT)
+am_gpg2keys_hkp_OBJECTS = gpg2keys_hkp-gpgkeys_hkp.$(OBJEXT) \
+ gpg2keys_hkp-ksutil.$(OBJEXT) \
+ gpg2keys_hkp-no-libgcrypt.$(OBJEXT) $(am__objects_2)
+gpg2keys_hkp_OBJECTS = $(am_gpg2keys_hkp_OBJECTS)
+@FAKE_CURL_FALSE@gpg2keys_hkp_DEPENDENCIES = $(common_libs) \
+@FAKE_CURL_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@FAKE_CURL_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
+@FAKE_CURL_FALSE@ $(am__DEPENDENCIES_1)
+@FAKE_CURL_TRUE@gpg2keys_hkp_DEPENDENCIES = $(common_libs) \
+@FAKE_CURL_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@FAKE_CURL_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+am_gpg2keys_kdns_OBJECTS = gpg2keys_kdns-gpgkeys_kdns.$(OBJEXT) \
+ gpg2keys_kdns-ksutil.$(OBJEXT) \
+ gpg2keys_kdns-no-libgcrypt.$(OBJEXT)
+gpg2keys_kdns_OBJECTS = $(am_gpg2keys_kdns_OBJECTS)
+gpg2keys_kdns_DEPENDENCIES = $(common_libs) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_2)
+am_gpg2keys_ldap_OBJECTS = gpg2keys_ldap-gpgkeys_ldap.$(OBJEXT) \
+ gpg2keys_ldap-ksutil.$(OBJEXT) \
+ gpg2keys_ldap-no-libgcrypt.$(OBJEXT)
+gpg2keys_ldap_OBJECTS = $(am_gpg2keys_ldap_OBJECTS)
+gpg2keys_ldap_DEPENDENCIES = ../jnlib/libjnlib.a $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_2)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+SCRIPTS = $(libexec_SCRIPTS) $(noinst_SCRIPTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(gpg2keys_curl_SOURCES) $(gpg2keys_finger_SOURCES) \
+ $(gpg2keys_hkp_SOURCES) $(gpg2keys_kdns_SOURCES) \
+ $(gpg2keys_ldap_SOURCES)
+DIST_SOURCES = $(am__gpg2keys_curl_SOURCES_DIST) \
+ $(gpg2keys_finger_SOURCES) $(am__gpg2keys_hkp_SOURCES_DIST) \
+ $(gpg2keys_kdns_SOURCES) $(gpg2keys_ldap_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABSOLUTE_STDINT_H = @ABSOLUTE_STDINT_H@
+ACLOCAL = @ACLOCAL@
+ADNSLIBS = @ADNSLIBS@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DL_LIBS = @DL_LIBS@
+DNSLIBS = @DNSLIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FAQPROG = @FAQPROG@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUPG_AGENT_PGM = @GNUPG_AGENT_PGM@
+GNUPG_DIRMNGR_PGM = @GNUPG_DIRMNGR_PGM@
+GNUPG_PINENTRY_PGM = @GNUPG_PINENTRY_PGM@
+GNUPG_PROTECT_TOOL_PGM = @GNUPG_PROTECT_TOOL_PGM@
+GNUPG_SCDAEMON_PGM = @GNUPG_SCDAEMON_PGM@
+GPGKEYS_CURL = @GPGKEYS_CURL@
+GPGKEYS_FINGER = @GPGKEYS_FINGER@
+GPGKEYS_HKP = @GPGKEYS_HKP@
+GPGKEYS_KDNS = @GPGKEYS_KDNS@
+GPGKEYS_LDAP = @GPGKEYS_LDAP@
+GPGKEYS_MAILTO = @GPGKEYS_MAILTO@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+KSBA_CFLAGS = @KSBA_CFLAGS@
+KSBA_CONFIG = @KSBA_CONFIG@
+KSBA_LIBS = @KSBA_LIBS@
+LDAPLIBS = @LDAPLIBS@
+LDAP_CPPFLAGS = @LDAP_CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBASSUAN_CFLAGS = @LIBASSUAN_CFLAGS@
+LIBASSUAN_CONFIG = @LIBASSUAN_CONFIG@
+LIBASSUAN_LIBS = @LIBASSUAN_LIBS@
+LIBCURL = @LIBCURL@
+LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@
+LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBREADLINE = @LIBREADLINE@
+LIBS = @LIBS@
+LIBUSB_LIBS = @LIBUSB_LIBS@
+LIBUTIL_LIBS = @LIBUTIL_LIBS@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NETLIBS = @NETLIBS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_GT = @PACKAGE_GT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+POSUB = @POSUB@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+SENDMAIL = @SENDMAIL@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHRED = @SHRED@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+TAR = @TAR@
+UNISTD_H = @UNISTD_H@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+W32SOCKLIBS = @W32SOCKLIBS@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINDRES = @WINDRES@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+ZLIBS = @ZLIBS@
+_libcurl_config = @_libcurl_config@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = $(datadir)/locale
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_SCRIPTS = gpg2keys_mailto
+EXTRA_DIST = ChangeLog-2011
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common \
+ -I$(top_srcdir)/intl -DLOCALEDIR=\"$(localedir)\" \
+ $(am__append_1) $(am__append_2) $(am__append_3) \
+ $(am__append_4) $(am__append_5) $(am__append_6)
+AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
+
+# Convenience macros
+libcommon = ../common/libcommon.a
+libcommonpth = ../common/libcommonpth.a
+libexec_PROGRAMS = $(GPGKEYS_LDAP) $(GPGKEYS_HKP) $(GPGKEYS_FINGER) \
+ $(GPGKEYS_CURL) $(GPGKEYS_KDNS)
+
+libexec_SCRIPTS = $(GPGKEYS_MAILTO)
+noinst_SCRIPTS = gpg2keys_test
+common_libs = ../gl/libgnu.a ../common/libcommon.a ../jnlib/libjnlib.a
+other_libs = $(LIBICONV) $(LIBINTL) $(CAPLIBS)
+gpg2keys_ldap_SOURCES = gpgkeys_ldap.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_ldap_CPPFLAGS = $(LDAP_CPPFLAGS) $(AM_CPPFLAGS)
+gpg2keys_ldap_LDADD = ../jnlib/libjnlib.a $(LDAPLIBS) $(GPG_ERROR_LIBS) \
+ $(NETLIBS) $(other_libs)
+
+gpg2keys_finger_SOURCES = gpgkeys_finger.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_finger_CPPFLAGS = $(AM_CPPFLAGS)
+gpg2keys_finger_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
+ $(NETLIBS) $(other_libs)
+
+gpg2keys_kdns_SOURCES = gpgkeys_kdns.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_kdns_CPPFLAGS = $(AM_CPPFLAGS)
+gpg2keys_kdns_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
+ $(ADNSLIBS) $(NETLIBS) $(other_libs)
+
+gpg2keys_curl_SOURCES = gpgkeys_curl.c ksutil.c ksutil.h \
+ no-libgcrypt.c $(am__append_7)
+gpg2keys_hkp_SOURCES = gpgkeys_hkp.c ksutil.c ksutil.h no-libgcrypt.c \
+ $(am__append_8)
+# Note that we need to include all other libs here as well because
+# some compilers don't care about inline functions and insert
+# references to symbols used in unused inline functions.
+@FAKE_CURL_FALSE@gpg2keys_curl_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS)
+@FAKE_CURL_TRUE@gpg2keys_curl_CPPFLAGS = $(AM_CPPFLAGS)
+@FAKE_CURL_FALSE@gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+@FAKE_CURL_FALSE@ $(other_libs) $(LIBCURL) $(GETOPT)
+
+@FAKE_CURL_TRUE@gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+@FAKE_CURL_TRUE@ $(other_libs)
+
+@FAKE_CURL_FALSE@gpg2keys_hkp_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS)
+@FAKE_CURL_TRUE@gpg2keys_hkp_CPPFLAGS = $(AM_CPPFLAGS)
+@FAKE_CURL_FALSE@gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+@FAKE_CURL_FALSE@ $(other_libs) $(LIBCURL) $(GETOPT)
+
+@FAKE_CURL_TRUE@gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \
+@FAKE_CURL_TRUE@ $(other_libs)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/am/cmacros.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu keyserver/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu keyserver/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+gpg2keys_mailto: $(top_builddir)/config.status $(srcdir)/gpg2keys_mailto.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+gpg2keys_test: $(top_builddir)/config.status $(srcdir)/gpg2keys_test.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+gpg2keys_curl$(EXEEXT): $(gpg2keys_curl_OBJECTS) $(gpg2keys_curl_DEPENDENCIES)
+ @rm -f gpg2keys_curl$(EXEEXT)
+ $(LINK) $(gpg2keys_curl_OBJECTS) $(gpg2keys_curl_LDADD) $(LIBS)
+gpg2keys_finger$(EXEEXT): $(gpg2keys_finger_OBJECTS) $(gpg2keys_finger_DEPENDENCIES)
+ @rm -f gpg2keys_finger$(EXEEXT)
+ $(LINK) $(gpg2keys_finger_OBJECTS) $(gpg2keys_finger_LDADD) $(LIBS)
+gpg2keys_hkp$(EXEEXT): $(gpg2keys_hkp_OBJECTS) $(gpg2keys_hkp_DEPENDENCIES)
+ @rm -f gpg2keys_hkp$(EXEEXT)
+ $(LINK) $(gpg2keys_hkp_OBJECTS) $(gpg2keys_hkp_LDADD) $(LIBS)
+gpg2keys_kdns$(EXEEXT): $(gpg2keys_kdns_OBJECTS) $(gpg2keys_kdns_DEPENDENCIES)
+ @rm -f gpg2keys_kdns$(EXEEXT)
+ $(LINK) $(gpg2keys_kdns_OBJECTS) $(gpg2keys_kdns_LDADD) $(LIBS)
+gpg2keys_ldap$(EXEEXT): $(gpg2keys_ldap_OBJECTS) $(gpg2keys_ldap_DEPENDENCIES)
+ @rm -f gpg2keys_ldap$(EXEEXT)
+ $(LINK) $(gpg2keys_ldap_OBJECTS) $(gpg2keys_ldap_LDADD) $(LIBS)
+install-libexecSCRIPTS: $(libexec_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
+ @list='$(libexec_SCRIPTS)'; test -n "$(libexecdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-libexecSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_SCRIPTS)'; test -n "$(libexecdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_curl-curl-shim.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_curl-gpgkeys_curl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_curl-ksutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_curl-no-libgcrypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_finger-gpgkeys_finger.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_finger-ksutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_finger-no-libgcrypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_hkp-curl-shim.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_hkp-gpgkeys_hkp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_hkp-ksutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_hkp-no-libgcrypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_kdns-gpgkeys_kdns.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_kdns-ksutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_kdns-no-libgcrypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_ldap-gpgkeys_ldap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_ldap-ksutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg2keys_ldap-no-libgcrypt.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+gpg2keys_curl-gpgkeys_curl.o: gpgkeys_curl.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-gpgkeys_curl.o -MD -MP -MF $(DEPDIR)/gpg2keys_curl-gpgkeys_curl.Tpo -c -o gpg2keys_curl-gpgkeys_curl.o `test -f 'gpgkeys_curl.c' || echo '$(srcdir)/'`gpgkeys_curl.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-gpgkeys_curl.Tpo $(DEPDIR)/gpg2keys_curl-gpgkeys_curl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_curl.c' object='gpg2keys_curl-gpgkeys_curl.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-gpgkeys_curl.o `test -f 'gpgkeys_curl.c' || echo '$(srcdir)/'`gpgkeys_curl.c
+
+gpg2keys_curl-gpgkeys_curl.obj: gpgkeys_curl.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-gpgkeys_curl.obj -MD -MP -MF $(DEPDIR)/gpg2keys_curl-gpgkeys_curl.Tpo -c -o gpg2keys_curl-gpgkeys_curl.obj `if test -f 'gpgkeys_curl.c'; then $(CYGPATH_W) 'gpgkeys_curl.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_curl.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-gpgkeys_curl.Tpo $(DEPDIR)/gpg2keys_curl-gpgkeys_curl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_curl.c' object='gpg2keys_curl-gpgkeys_curl.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-gpgkeys_curl.obj `if test -f 'gpgkeys_curl.c'; then $(CYGPATH_W) 'gpgkeys_curl.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_curl.c'; fi`
+
+gpg2keys_curl-ksutil.o: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-ksutil.o -MD -MP -MF $(DEPDIR)/gpg2keys_curl-ksutil.Tpo -c -o gpg2keys_curl-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-ksutil.Tpo $(DEPDIR)/gpg2keys_curl-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_curl-ksutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+
+gpg2keys_curl-ksutil.obj: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-ksutil.obj -MD -MP -MF $(DEPDIR)/gpg2keys_curl-ksutil.Tpo -c -o gpg2keys_curl-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-ksutil.Tpo $(DEPDIR)/gpg2keys_curl-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_curl-ksutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+
+gpg2keys_curl-no-libgcrypt.o: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-no-libgcrypt.o -MD -MP -MF $(DEPDIR)/gpg2keys_curl-no-libgcrypt.Tpo -c -o gpg2keys_curl-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_curl-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_curl-no-libgcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+
+gpg2keys_curl-no-libgcrypt.obj: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-no-libgcrypt.obj -MD -MP -MF $(DEPDIR)/gpg2keys_curl-no-libgcrypt.Tpo -c -o gpg2keys_curl-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_curl-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_curl-no-libgcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+
+gpg2keys_curl-curl-shim.o: curl-shim.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-curl-shim.o -MD -MP -MF $(DEPDIR)/gpg2keys_curl-curl-shim.Tpo -c -o gpg2keys_curl-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-curl-shim.Tpo $(DEPDIR)/gpg2keys_curl-curl-shim.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpg2keys_curl-curl-shim.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c
+
+gpg2keys_curl-curl-shim.obj: curl-shim.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_curl-curl-shim.obj -MD -MP -MF $(DEPDIR)/gpg2keys_curl-curl-shim.Tpo -c -o gpg2keys_curl-curl-shim.obj `if test -f 'curl-shim.c'; then $(CYGPATH_W) 'curl-shim.c'; else $(CYGPATH_W) '$(srcdir)/curl-shim.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_curl-curl-shim.Tpo $(DEPDIR)/gpg2keys_curl-curl-shim.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpg2keys_curl-curl-shim.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_curl-curl-shim.obj `if test -f 'curl-shim.c'; then $(CYGPATH_W) 'curl-shim.c'; else $(CYGPATH_W) '$(srcdir)/curl-shim.c'; fi`
+
+gpg2keys_finger-gpgkeys_finger.o: gpgkeys_finger.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_finger-gpgkeys_finger.o -MD -MP -MF $(DEPDIR)/gpg2keys_finger-gpgkeys_finger.Tpo -c -o gpg2keys_finger-gpgkeys_finger.o `test -f 'gpgkeys_finger.c' || echo '$(srcdir)/'`gpgkeys_finger.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_finger-gpgkeys_finger.Tpo $(DEPDIR)/gpg2keys_finger-gpgkeys_finger.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_finger.c' object='gpg2keys_finger-gpgkeys_finger.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_finger-gpgkeys_finger.o `test -f 'gpgkeys_finger.c' || echo '$(srcdir)/'`gpgkeys_finger.c
+
+gpg2keys_finger-gpgkeys_finger.obj: gpgkeys_finger.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_finger-gpgkeys_finger.obj -MD -MP -MF $(DEPDIR)/gpg2keys_finger-gpgkeys_finger.Tpo -c -o gpg2keys_finger-gpgkeys_finger.obj `if test -f 'gpgkeys_finger.c'; then $(CYGPATH_W) 'gpgkeys_finger.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_finger.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_finger-gpgkeys_finger.Tpo $(DEPDIR)/gpg2keys_finger-gpgkeys_finger.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_finger.c' object='gpg2keys_finger-gpgkeys_finger.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_finger-gpgkeys_finger.obj `if test -f 'gpgkeys_finger.c'; then $(CYGPATH_W) 'gpgkeys_finger.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_finger.c'; fi`
+
+gpg2keys_finger-ksutil.o: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_finger-ksutil.o -MD -MP -MF $(DEPDIR)/gpg2keys_finger-ksutil.Tpo -c -o gpg2keys_finger-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_finger-ksutil.Tpo $(DEPDIR)/gpg2keys_finger-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_finger-ksutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_finger-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+
+gpg2keys_finger-ksutil.obj: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_finger-ksutil.obj -MD -MP -MF $(DEPDIR)/gpg2keys_finger-ksutil.Tpo -c -o gpg2keys_finger-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_finger-ksutil.Tpo $(DEPDIR)/gpg2keys_finger-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_finger-ksutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_finger-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+
+gpg2keys_finger-no-libgcrypt.o: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_finger-no-libgcrypt.o -MD -MP -MF $(DEPDIR)/gpg2keys_finger-no-libgcrypt.Tpo -c -o gpg2keys_finger-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_finger-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_finger-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_finger-no-libgcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_finger-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+
+gpg2keys_finger-no-libgcrypt.obj: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_finger-no-libgcrypt.obj -MD -MP -MF $(DEPDIR)/gpg2keys_finger-no-libgcrypt.Tpo -c -o gpg2keys_finger-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_finger-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_finger-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_finger-no-libgcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_finger-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+
+gpg2keys_hkp-gpgkeys_hkp.o: gpgkeys_hkp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-gpgkeys_hkp.o -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-gpgkeys_hkp.Tpo -c -o gpg2keys_hkp-gpgkeys_hkp.o `test -f 'gpgkeys_hkp.c' || echo '$(srcdir)/'`gpgkeys_hkp.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-gpgkeys_hkp.Tpo $(DEPDIR)/gpg2keys_hkp-gpgkeys_hkp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_hkp.c' object='gpg2keys_hkp-gpgkeys_hkp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-gpgkeys_hkp.o `test -f 'gpgkeys_hkp.c' || echo '$(srcdir)/'`gpgkeys_hkp.c
+
+gpg2keys_hkp-gpgkeys_hkp.obj: gpgkeys_hkp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-gpgkeys_hkp.obj -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-gpgkeys_hkp.Tpo -c -o gpg2keys_hkp-gpgkeys_hkp.obj `if test -f 'gpgkeys_hkp.c'; then $(CYGPATH_W) 'gpgkeys_hkp.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_hkp.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-gpgkeys_hkp.Tpo $(DEPDIR)/gpg2keys_hkp-gpgkeys_hkp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_hkp.c' object='gpg2keys_hkp-gpgkeys_hkp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-gpgkeys_hkp.obj `if test -f 'gpgkeys_hkp.c'; then $(CYGPATH_W) 'gpgkeys_hkp.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_hkp.c'; fi`
+
+gpg2keys_hkp-ksutil.o: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-ksutil.o -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-ksutil.Tpo -c -o gpg2keys_hkp-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-ksutil.Tpo $(DEPDIR)/gpg2keys_hkp-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_hkp-ksutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+
+gpg2keys_hkp-ksutil.obj: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-ksutil.obj -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-ksutil.Tpo -c -o gpg2keys_hkp-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-ksutil.Tpo $(DEPDIR)/gpg2keys_hkp-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_hkp-ksutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+
+gpg2keys_hkp-no-libgcrypt.o: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-no-libgcrypt.o -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-no-libgcrypt.Tpo -c -o gpg2keys_hkp-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_hkp-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_hkp-no-libgcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+
+gpg2keys_hkp-no-libgcrypt.obj: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-no-libgcrypt.obj -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-no-libgcrypt.Tpo -c -o gpg2keys_hkp-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_hkp-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_hkp-no-libgcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+
+gpg2keys_hkp-curl-shim.o: curl-shim.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-curl-shim.o -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-curl-shim.Tpo -c -o gpg2keys_hkp-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-curl-shim.Tpo $(DEPDIR)/gpg2keys_hkp-curl-shim.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpg2keys_hkp-curl-shim.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c
+
+gpg2keys_hkp-curl-shim.obj: curl-shim.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_hkp-curl-shim.obj -MD -MP -MF $(DEPDIR)/gpg2keys_hkp-curl-shim.Tpo -c -o gpg2keys_hkp-curl-shim.obj `if test -f 'curl-shim.c'; then $(CYGPATH_W) 'curl-shim.c'; else $(CYGPATH_W) '$(srcdir)/curl-shim.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_hkp-curl-shim.Tpo $(DEPDIR)/gpg2keys_hkp-curl-shim.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpg2keys_hkp-curl-shim.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_hkp-curl-shim.obj `if test -f 'curl-shim.c'; then $(CYGPATH_W) 'curl-shim.c'; else $(CYGPATH_W) '$(srcdir)/curl-shim.c'; fi`
+
+gpg2keys_kdns-gpgkeys_kdns.o: gpgkeys_kdns.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_kdns-gpgkeys_kdns.o -MD -MP -MF $(DEPDIR)/gpg2keys_kdns-gpgkeys_kdns.Tpo -c -o gpg2keys_kdns-gpgkeys_kdns.o `test -f 'gpgkeys_kdns.c' || echo '$(srcdir)/'`gpgkeys_kdns.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_kdns-gpgkeys_kdns.Tpo $(DEPDIR)/gpg2keys_kdns-gpgkeys_kdns.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_kdns.c' object='gpg2keys_kdns-gpgkeys_kdns.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_kdns-gpgkeys_kdns.o `test -f 'gpgkeys_kdns.c' || echo '$(srcdir)/'`gpgkeys_kdns.c
+
+gpg2keys_kdns-gpgkeys_kdns.obj: gpgkeys_kdns.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_kdns-gpgkeys_kdns.obj -MD -MP -MF $(DEPDIR)/gpg2keys_kdns-gpgkeys_kdns.Tpo -c -o gpg2keys_kdns-gpgkeys_kdns.obj `if test -f 'gpgkeys_kdns.c'; then $(CYGPATH_W) 'gpgkeys_kdns.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_kdns.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_kdns-gpgkeys_kdns.Tpo $(DEPDIR)/gpg2keys_kdns-gpgkeys_kdns.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_kdns.c' object='gpg2keys_kdns-gpgkeys_kdns.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_kdns-gpgkeys_kdns.obj `if test -f 'gpgkeys_kdns.c'; then $(CYGPATH_W) 'gpgkeys_kdns.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_kdns.c'; fi`
+
+gpg2keys_kdns-ksutil.o: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_kdns-ksutil.o -MD -MP -MF $(DEPDIR)/gpg2keys_kdns-ksutil.Tpo -c -o gpg2keys_kdns-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_kdns-ksutil.Tpo $(DEPDIR)/gpg2keys_kdns-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_kdns-ksutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_kdns-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+
+gpg2keys_kdns-ksutil.obj: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_kdns-ksutil.obj -MD -MP -MF $(DEPDIR)/gpg2keys_kdns-ksutil.Tpo -c -o gpg2keys_kdns-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_kdns-ksutil.Tpo $(DEPDIR)/gpg2keys_kdns-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_kdns-ksutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_kdns-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+
+gpg2keys_kdns-no-libgcrypt.o: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_kdns-no-libgcrypt.o -MD -MP -MF $(DEPDIR)/gpg2keys_kdns-no-libgcrypt.Tpo -c -o gpg2keys_kdns-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_kdns-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_kdns-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_kdns-no-libgcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_kdns-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+
+gpg2keys_kdns-no-libgcrypt.obj: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_kdns-no-libgcrypt.obj -MD -MP -MF $(DEPDIR)/gpg2keys_kdns-no-libgcrypt.Tpo -c -o gpg2keys_kdns-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_kdns-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_kdns-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_kdns-no-libgcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_kdns_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_kdns-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+
+gpg2keys_ldap-gpgkeys_ldap.o: gpgkeys_ldap.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_ldap-gpgkeys_ldap.o -MD -MP -MF $(DEPDIR)/gpg2keys_ldap-gpgkeys_ldap.Tpo -c -o gpg2keys_ldap-gpgkeys_ldap.o `test -f 'gpgkeys_ldap.c' || echo '$(srcdir)/'`gpgkeys_ldap.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_ldap-gpgkeys_ldap.Tpo $(DEPDIR)/gpg2keys_ldap-gpgkeys_ldap.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_ldap.c' object='gpg2keys_ldap-gpgkeys_ldap.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_ldap-gpgkeys_ldap.o `test -f 'gpgkeys_ldap.c' || echo '$(srcdir)/'`gpgkeys_ldap.c
+
+gpg2keys_ldap-gpgkeys_ldap.obj: gpgkeys_ldap.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_ldap-gpgkeys_ldap.obj -MD -MP -MF $(DEPDIR)/gpg2keys_ldap-gpgkeys_ldap.Tpo -c -o gpg2keys_ldap-gpgkeys_ldap.obj `if test -f 'gpgkeys_ldap.c'; then $(CYGPATH_W) 'gpgkeys_ldap.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_ldap.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_ldap-gpgkeys_ldap.Tpo $(DEPDIR)/gpg2keys_ldap-gpgkeys_ldap.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_ldap.c' object='gpg2keys_ldap-gpgkeys_ldap.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_ldap-gpgkeys_ldap.obj `if test -f 'gpgkeys_ldap.c'; then $(CYGPATH_W) 'gpgkeys_ldap.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_ldap.c'; fi`
+
+gpg2keys_ldap-ksutil.o: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_ldap-ksutil.o -MD -MP -MF $(DEPDIR)/gpg2keys_ldap-ksutil.Tpo -c -o gpg2keys_ldap-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_ldap-ksutil.Tpo $(DEPDIR)/gpg2keys_ldap-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_ldap-ksutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_ldap-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c
+
+gpg2keys_ldap-ksutil.obj: ksutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_ldap-ksutil.obj -MD -MP -MF $(DEPDIR)/gpg2keys_ldap-ksutil.Tpo -c -o gpg2keys_ldap-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_ldap-ksutil.Tpo $(DEPDIR)/gpg2keys_ldap-ksutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpg2keys_ldap-ksutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_ldap-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`
+
+gpg2keys_ldap-no-libgcrypt.o: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_ldap-no-libgcrypt.o -MD -MP -MF $(DEPDIR)/gpg2keys_ldap-no-libgcrypt.Tpo -c -o gpg2keys_ldap-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_ldap-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_ldap-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_ldap-no-libgcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_ldap-no-libgcrypt.o `test -f 'no-libgcrypt.c' || echo '$(srcdir)/'`no-libgcrypt.c
+
+gpg2keys_ldap-no-libgcrypt.obj: no-libgcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpg2keys_ldap-no-libgcrypt.obj -MD -MP -MF $(DEPDIR)/gpg2keys_ldap-no-libgcrypt.Tpo -c -o gpg2keys_ldap-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg2keys_ldap-no-libgcrypt.Tpo $(DEPDIR)/gpg2keys_ldap-no-libgcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='no-libgcrypt.c' object='gpg2keys_ldap-no-libgcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpg2keys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpg2keys_ldap-no-libgcrypt.obj `if test -f 'no-libgcrypt.c'; then $(CYGPATH_W) 'no-libgcrypt.c'; else $(CYGPATH_W) '$(srcdir)/no-libgcrypt.c'; fi`
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+installdirs:
+ for dir in "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libexecdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libexecPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libexecPROGRAMS install-libexecSCRIPTS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libexecPROGRAMS uninstall-libexecSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libexecPROGRAMS ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libexecPROGRAMS install-libexecSCRIPTS \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+ ps ps-am tags uninstall uninstall-am uninstall-libexecPROGRAMS \
+ uninstall-libexecSCRIPTS
+
+
+# Make sure that all libs are build before we use them. This is
+# important for things like make -j2.
+$(PROGRAMS): $(common_libs)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/keyserver/curl-shim.c b/keyserver/curl-shim.c
new file mode 100644
index 0000000..500d9f5
--- /dev/null
+++ b/keyserver/curl-shim.c
@@ -0,0 +1,382 @@
+/* curl-shim.c - Implement a small subset of the curl API in terms of
+ * the iobuf HTTP API
+ *
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ */
+
+#include <config.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "util.h"
+#include "http.h"
+#include "ksutil.h"
+#include "curl-shim.h"
+
+static CURLcode
+handle_error(CURL *curl,CURLcode err,const char *str)
+{
+ if(curl->errorbuffer)
+ {
+ /* Make sure you never exceed CURL_ERROR_SIZE, currently set to
+ 256 in curl-shim.h */
+ switch(err)
+ {
+ case CURLE_OK:
+ strcpy(curl->errorbuffer,"okay");
+ break;
+
+ case CURLE_UNSUPPORTED_PROTOCOL:
+ strcpy(curl->errorbuffer,"unsupported protocol");
+ break;
+
+ case CURLE_COULDNT_CONNECT:
+ strcpy(curl->errorbuffer,"couldn't connect");
+ break;
+
+ case CURLE_WRITE_ERROR:
+ strcpy(curl->errorbuffer,"write error");
+ break;
+
+ case CURLE_HTTP_RETURNED_ERROR:
+ sprintf(curl->errorbuffer,"url returned error %u",curl->status);
+ break;
+
+ default:
+ strcpy(curl->errorbuffer,"generic error");
+ break;
+ }
+
+ if(str && (strlen(curl->errorbuffer)+2+strlen(str)+1)<=CURL_ERROR_SIZE)
+ {
+ strcat(curl->errorbuffer,": ");
+ strcat(curl->errorbuffer,str);
+ }
+ }
+
+ return err;
+}
+
+CURLcode
+curl_global_init(long flags)
+{
+ (void)flags;
+ return CURLE_OK;
+}
+
+void
+curl_global_cleanup(void) {}
+
+CURL *
+curl_easy_init(void)
+{
+ CURL *handle;
+
+#ifdef HAVE_W32_SYSTEM
+ w32_init_sockets ();
+#endif
+
+ handle=calloc(1,sizeof(CURL));
+ if(handle)
+ handle->errors=stderr;
+
+ return handle;
+}
+
+void
+curl_easy_cleanup(CURL *curl)
+{
+ if (curl)
+ {
+ http_close (curl->hd, 0);
+ free(curl);
+ }
+}
+
+CURLcode
+curl_easy_setopt(CURL *curl,CURLoption option,...)
+{
+ va_list ap;
+
+ va_start(ap,option);
+
+ switch(option)
+ {
+ case CURLOPT_URL:
+ curl->url=va_arg(ap,char *);
+ break;
+ case CURLOPT_USERPWD:
+ curl->auth=va_arg(ap,char *);
+ break;
+ case CURLOPT_WRITEFUNCTION:
+ curl->writer=va_arg(ap,write_func);
+ break;
+ case CURLOPT_FILE:
+ curl->file=va_arg(ap,void *);
+ break;
+ case CURLOPT_ERRORBUFFER:
+ curl->errorbuffer=va_arg(ap,char *);
+ break;
+ case CURLOPT_PROXY:
+ curl->proxy=va_arg(ap,char *);
+ break;
+ case CURLOPT_POST:
+ curl->flags.post=va_arg(ap,long)?1:0;
+ break;
+ case CURLOPT_POSTFIELDS:
+ curl->postfields=va_arg(ap,char *);
+ break;
+ case CURLOPT_SRVTAG_GPG_HACK:
+ curl->srvtag=va_arg(ap,char *);
+ break;
+ case CURLOPT_FAILONERROR:
+ curl->flags.failonerror=va_arg(ap,long)?1:0;
+ break;
+ case CURLOPT_VERBOSE:
+ curl->flags.verbose=va_arg(ap,long)?1:0;
+ break;
+ case CURLOPT_STDERR:
+ curl->errors=va_arg(ap,FILE *);
+ break;
+ case CURLOPT_HTTPHEADER:
+ curl->headers=va_arg(ap,struct curl_slist *);
+ break;
+ default:
+ /* We ignore the huge majority of curl options */
+ break;
+ }
+
+ return handle_error(curl,CURLE_OK,NULL);
+}
+
+CURLcode
+curl_easy_perform(CURL *curl)
+{
+ int rc;
+ CURLcode err=CURLE_OK;
+ const char *errstr=NULL;
+ char *proxy=NULL;
+
+ /* Emulate the libcurl proxy behavior. If the calling program set a
+ proxy, use it. If it didn't set a proxy or set it to NULL, check
+ for one in the environment. If the calling program explicitly
+ set a null-string proxy the http code doesn't use a proxy at
+ all. */
+
+ if(curl->proxy)
+ proxy=curl->proxy;
+ else
+ proxy=getenv(HTTP_PROXY_ENV);
+
+ if(curl->flags.verbose)
+ {
+ fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null");
+ fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url);
+ fprintf(curl->errors,"* HTTP auth is \"%s\"\n",
+ curl->auth?curl->auth:"null");
+ fprintf(curl->errors,"* HTTP method is %s\n",
+ curl->flags.post?"POST":"GET");
+ }
+
+ if(curl->flags.post)
+ {
+ rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth,
+ 0, proxy, NULL, curl->srvtag,
+ curl->headers?curl->headers->list:NULL);
+ if (!rc)
+ {
+ unsigned int post_len = strlen(curl->postfields);
+
+ es_fprintf (http_get_write_ptr (curl->hd),
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: %u\r\n", post_len);
+ http_start_data (curl->hd);
+ es_write (http_get_write_ptr (curl->hd),
+ curl->postfields, post_len, NULL);
+
+ rc = http_wait_response (curl->hd);
+ curl->status = http_get_status_code (curl->hd);
+ if (!rc && curl->flags.failonerror && curl->status>=300)
+ err = CURLE_HTTP_RETURNED_ERROR;
+ http_close (curl->hd, 0);
+ curl->hd = NULL;
+ }
+ }
+ else
+ {
+ rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth,
+ 0, proxy, NULL, curl->srvtag,
+ curl->headers?curl->headers->list:NULL);
+ if (!rc)
+ {
+ rc = http_wait_response (curl->hd);
+ curl->status = http_get_status_code (curl->hd);
+ if (!rc)
+ {
+ if (curl->flags.failonerror && curl->status>=300)
+ err = CURLE_HTTP_RETURNED_ERROR;
+ else
+ {
+ size_t maxlen = 1024;
+ size_t buflen;
+ unsigned int len;
+ char *line = NULL;
+
+ while ((len = es_read_line (http_get_read_ptr (curl->hd),
+ &line, &buflen, &maxlen)))
+ {
+ size_t ret;
+
+ maxlen=1024;
+
+ ret=(curl->writer)(line,len,1,curl->file);
+ if(ret!=len)
+ {
+ err=CURLE_WRITE_ERROR;
+ break;
+ }
+ }
+
+ es_free (line);
+ http_close(curl->hd, 0);
+ curl->hd = NULL;
+ }
+ }
+ else
+ {
+ http_close (curl->hd, 0);
+ curl->hd = NULL;
+ }
+ }
+ }
+
+ switch(gpg_err_code (rc))
+ {
+ case 0:
+ break;
+
+ case GPG_ERR_INV_URI:
+ err=CURLE_UNSUPPORTED_PROTOCOL;
+ break;
+
+ default:
+ errstr=gpg_strerror (rc);
+ err=CURLE_COULDNT_CONNECT;
+ break;
+ }
+
+ return handle_error(curl,err,errstr);
+}
+
+/* This is not the same exact set that is allowed according to
+ RFC-2396, but it is what the real curl uses. */
+#define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ "0123456789"
+
+char *
+curl_escape(char *str,int length)
+{
+ int len,max,idx,enc_idx=0;
+ char *enc;
+
+ if(length)
+ len=length;
+ else
+ len=strlen(str);
+
+ enc=malloc(len+1);
+ if(!enc)
+ return enc;
+
+ max=len;
+
+ for(idx=0;idx<len;idx++)
+ {
+ if(enc_idx+3>max)
+ {
+ char *tmp;
+
+ max+=100;
+
+ tmp=realloc(enc,max+1);
+ if(!tmp)
+ {
+ free(enc);
+ return NULL;
+ }
+
+ enc=tmp;
+ }
+
+ if(strchr(VALID_URI_CHARS,str[idx]))
+ enc[enc_idx++]=str[idx];
+ else
+ {
+ char numbuf[5];
+ sprintf(numbuf,"%%%02X",str[idx]);
+ strcpy(&enc[enc_idx],numbuf);
+ enc_idx+=3;
+ }
+ }
+
+ enc[enc_idx]='\0';
+
+ return enc;
+}
+
+curl_version_info_data *
+curl_version_info(int type)
+{
+ static curl_version_info_data data;
+ static const char *protocols[]={"http",NULL};
+
+ (void)type;
+
+ data.protocols=protocols;
+
+ return &data;
+}
+
+struct curl_slist *
+curl_slist_append(struct curl_slist *list,const char *string)
+{
+ if(!list)
+ {
+ list=calloc(1,sizeof(*list));
+ if(!list)
+ return NULL;
+ }
+
+ add_to_strlist(&list->list,string);
+
+ return list;
+}
+
+void
+curl_slist_free_all(struct curl_slist *list)
+{
+ if(list)
+ {
+ free_strlist(list->list);
+ free(list);
+ }
+}
diff --git a/keyserver/curl-shim.h b/keyserver/curl-shim.h
new file mode 100644
index 0000000..e37d816
--- /dev/null
+++ b/keyserver/curl-shim.h
@@ -0,0 +1,111 @@
+/* curl-shim.h
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ */
+
+#ifndef _CURL_SHIM_H_
+#define _CURL_SHIM_H_
+
+#include "util.h"
+#include "http.h"
+
+typedef enum
+ {
+ CURLE_OK=0,
+ CURLE_UNSUPPORTED_PROTOCOL=1,
+ CURLE_COULDNT_CONNECT=7,
+ CURLE_FTP_COULDNT_RETR_FILE=19,
+ CURLE_HTTP_RETURNED_ERROR=22,
+ CURLE_WRITE_ERROR=23
+ } CURLcode;
+
+typedef enum
+ {
+ CURLOPT_URL,
+ CURLOPT_USERPWD,
+ CURLOPT_WRITEFUNCTION,
+ CURLOPT_FILE,
+ CURLOPT_ERRORBUFFER,
+ CURLOPT_FOLLOWLOCATION,
+ CURLOPT_MAXREDIRS,
+ CURLOPT_STDERR,
+ CURLOPT_VERBOSE,
+ CURLOPT_SSL_VERIFYPEER,
+ CURLOPT_PROXY,
+ CURLOPT_CAINFO,
+ CURLOPT_POST,
+ CURLOPT_POSTFIELDS,
+ CURLOPT_FAILONERROR,
+ CURLOPT_HTTPHEADER,
+ CURLOPT_SRVTAG_GPG_HACK
+ } CURLoption;
+
+typedef size_t (*write_func)(char *buffer,size_t size,
+ size_t nitems,void *outstream);
+
+typedef struct
+{
+ char *url;
+ char *auth;
+ char *errorbuffer;
+ char *proxy;
+ write_func writer;
+ void *file;
+ char *postfields;
+ char *srvtag;
+ unsigned int status;
+ FILE *errors;
+ struct curl_slist *headers;
+ struct
+ {
+ unsigned int post:1;
+ unsigned int failonerror:1;
+ unsigned int verbose:1;
+ } flags;
+ http_t hd;
+} CURL;
+
+typedef struct
+{
+ const char **protocols;
+} curl_version_info_data;
+
+#define CURL_ERROR_SIZE 256
+#define CURL_GLOBAL_DEFAULT 0
+#define CURLVERSION_NOW 0
+
+CURLcode curl_global_init(long flags);
+void curl_global_cleanup(void);
+CURL *curl_easy_init(void);
+CURLcode curl_easy_setopt(CURL *curl,CURLoption option,...);
+CURLcode curl_easy_perform(CURL *curl);
+void curl_easy_cleanup(CURL *curl);
+char *curl_escape(char *str,int len);
+#define curl_free(x) free(x)
+#define curl_version() "GnuPG curl-shim"
+curl_version_info_data *curl_version_info(int type);
+
+struct curl_slist
+{
+ strlist_t list;
+};
+
+struct curl_slist *curl_slist_append(struct curl_slist *list,
+ const char *string);
+void curl_slist_free_all(struct curl_slist *list);
+
+#endif /* !_CURL_SHIM_H_ */
diff --git a/keyserver/gpg2keys_mailto.in b/keyserver/gpg2keys_mailto.in
new file mode 100755
index 0000000..959f0e7
--- /dev/null
+++ b/keyserver/gpg2keys_mailto.in
@@ -0,0 +1,211 @@
+#!@PERL@ -w
+
+# gpg2keys_mailto - talk to a email keyserver
+# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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/>.
+use Getopt::Std;
+$Getopt::Std::STANDARD_HELP_VERSION=1;
+$sendmail="@SENDMAIL@ -t";
+
+###
+
+sub VERSION_MESSAGE ()
+{
+ print STDOUT "gpg2keys_mailto (GnuPG) @VERSION@\n";
+}
+
+sub HELP_MESSAGE ()
+{
+ print STDOUT <<EOT
+
+--help Print this help
+--version Print the version
+-o FILE Write output to FILE
+EOT
+}
+
+
+
+getopts('o:');
+
+if(defined($opt_o))
+{
+ open(STDOUT,">$opt_o") || die "Can't open output file $opt_o\n";
+}
+
+if(@ARGV)
+{
+ open(STDIN,$ARGV[0]) || die "Can't open input file $ARGV[0]\n";
+}
+
+while(<STDIN>)
+{
+ last if($_ eq "\n");
+
+ if(/^COMMAND (\S+)/)
+ {
+ $command=$1;
+ }
+
+ if(/^OPAQUE (\S+)/)
+ {
+ $address=$1;
+ }
+
+ if(/^PROGRAM (\S+)/)
+ {
+ $program=$1;
+ }
+
+ if(/^OPTION (\S+)/)
+ {
+ if($1=~/^verbose$/i)
+ {
+ $verbose++;
+ }
+ elsif($1=~/^no-verbose$/i)
+ {
+ $verbose--;
+ }
+ elsif($1=~/^mail-from=(.+)$/i)
+ {
+ $from=$1;
+ }
+ elsif($1=~/^no-mail-from$/i)
+ {
+ undef $from;
+ }
+
+ }
+}
+
+if(!defined($from))
+{
+ ($login,$name)=(getpwuid($<))[0,6];
+ $from="$name <$login>";
+}
+
+$program="(unknown)" if(!defined($program));
+
+if(!defined($address))
+{
+ print STDERR "gpgkeys: no address provided\n";
+ exit(1);
+}
+
+while(<STDIN>)
+{
+ last if($_ eq "\n");
+
+ chomp;
+
+ push(@keys,$_);
+}
+
+# Send response
+
+print "VERSION 1\n";
+print "OPTION OUTOFBAND\n\n";
+
+# Email keyservers get and search the same way
+
+if($command=~/get/i || $command=~/search/i)
+{
+ if($command=~/search/i)
+ {
+ print "COUNT 0\n";
+ }
+
+ foreach $key (@keys)
+ {
+ open(MAIL,"|$sendmail") || die "ERROR: Can't open $sendmail\n";
+ print MAIL "From: $from\n";
+ print MAIL "To: $address\n";
+ if($command=~/get/i)
+ {
+ # mail keyservers don't like long-form keyids
+
+ if(substr($key,0,2) eq "0x")
+ {
+ $key=substr($key,2);
+ }
+
+ if(length($key)>8)
+ {
+ $key=substr($key,-8);
+ }
+
+ print MAIL "Subject: GET 0x$key\n\n";
+ }
+ else
+ {
+ print MAIL "Subject: GET $key\n\n";
+ }
+ print MAIL "GnuPG $program email keyserver request\n";
+ close(MAIL);
+
+ # Tell GnuPG not to expect a key
+ print "KEY $key OUTOFBAND\n";
+
+ if($verbose)
+ {
+ print STDERR "gpgkeys: key $key requested from $address\n";
+ }
+ }
+}
+
+if($command=~/send/i)
+{
+ while(!eof(STDIN))
+ {
+ open(MAIL,"|$sendmail") || die "ERROR: Can't open $sendmail\n";
+ print MAIL "From: $name <$login>\n";
+ print MAIL "To: $address\n";
+ print MAIL "Subject: ADD\n\n";
+
+ while(<STDIN>)
+ {
+ if(/^KEY (\S+) BEGIN$/)
+ {
+ $key=$1;
+ last;
+ }
+ }
+
+ while(<STDIN>)
+ {
+ if(/^KEY \S+ END$/)
+ {
+ last;
+ }
+
+ print MAIL;
+ }
+
+ close(MAIL);
+
+ if($verbose)
+ {
+ print STDERR "gpgkeys: key $key sent to $address\n";
+ }
+ }
+}
+
+
+# Local Variables:
+# mode:perl
+# End:
diff --git a/keyserver/gpg2keys_test.in b/keyserver/gpg2keys_test.in
new file mode 100755
index 0000000..9f2c0b6
--- /dev/null
+++ b/keyserver/gpg2keys_test.in
@@ -0,0 +1,97 @@
+#!@PERL@
+
+# gpg2keys_test - keyserver code tester
+# Copyright (C) 2001 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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/>.
+use Getopt::Std;
+$Getopt::Std::STANDARD_HELP_VERSION=1;
+
+$|=1;
+
+sub VERSION_MESSAGE ()
+{
+ print STDOUT "gpg2keys_test (GnuPG) @VERSION@\n";
+}
+
+sub HELP_MESSAGE ()
+{
+ print STDOUT <<EOT
+
+--help Print this help
+--version Print the version
+EOT
+}
+
+
+getopts('o:');
+
+print STDERR "gpgkeys_test starting\n";
+
+if(defined($opt_o))
+{
+ print STDERR "Using output file $opt_o\n";
+ open(STDOUT,">$opt_o") || die "Can't open output file $opt_o\n";
+}
+
+if(@ARGV)
+{
+ print STDERR "Using input file $ARGV[0]\n";
+ open(STDIN,$ARGV[0]) || die "Can't open input file $ARGV[0]\n";
+}
+
+# Get the command block
+
+print STDERR "Command block:\n";
+
+while(<STDIN>)
+{
+ last if($_ eq "\n");
+ print STDERR "--command-> $_";
+
+ if(/^COMMAND (\w+)/)
+ {
+ $command=$1;
+ }
+}
+
+# Get the keylist block
+
+print STDERR "Keylist block:\n";
+
+while(<STDIN>)
+{
+ last if($_ eq "\n");
+ print STDERR "--keylist-> $_";
+}
+
+# If it's a SEND, then get the key material
+
+if($command eq "SEND")
+{
+ print STDERR "Key material to send:\n";
+
+ while(<STDIN>)
+ {
+ print STDERR "$_";
+ }
+}
+
+printf STDERR "gpgkeys_test finished\n";
+
+# Local Variables:
+# mode:perl
+# End:
diff --git a/keyserver/gpgkeys_curl.c b/keyserver/gpgkeys_curl.c
new file mode 100644
index 0000000..28ec698
--- /dev/null
+++ b/keyserver/gpgkeys_curl.c
@@ -0,0 +1,419 @@
+/* gpgkeys_curl.c - fetch a key via libcurl
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ *
+ * In addition, as a special exception, the Free Software Foundation
+ * gives permission to link the code of the keyserver helper tools:
+ * gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
+ * project's "OpenSSL" library (or with modified versions of it that
+ * use the same license as the "OpenSSL" library), and distribute the
+ * linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If
+ * you modify this file, you may extend this exception to your version
+ * of the file, but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#else
+#include "curl-shim.h"
+#endif
+#include "keyserver.h"
+#include "ksutil.h"
+
+extern char *optarg;
+extern int optind;
+
+static FILE *input,*output,*console;
+static CURL *curl;
+static struct ks_options *opt;
+
+static int
+get_key(char *getkey)
+{
+ CURLcode res;
+ char errorbuffer[CURL_ERROR_SIZE];
+ char request[MAX_URL];
+ struct curl_writer_ctx ctx;
+
+ memset(&ctx,0,sizeof(ctx));
+
+ if(strncmp(getkey,"0x",2)==0)
+ getkey+=2;
+
+ fprintf(output,"KEY 0x%s BEGIN\n",getkey);
+
+ sprintf(request,"%s://%s%s%s%s",opt->scheme,opt->host,
+ opt->port?":":"",opt->port?opt->port:"",opt->path?opt->path:"/");
+
+ curl_easy_setopt(curl,CURLOPT_URL,request);
+ curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer);
+ ctx.stream=output;
+ curl_easy_setopt(curl,CURLOPT_FILE,&ctx);
+ curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer);
+
+ res=curl_easy_perform(curl);
+ if(res!=CURLE_OK)
+ {
+ fprintf(console,"gpgkeys: %s fetch error %d: %s\n",opt->scheme,
+ res,errorbuffer);
+ fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res));
+ }
+ else
+ {
+ curl_writer_finalize(&ctx);
+ if(!ctx.flags.done)
+ {
+ fprintf(console,"gpgkeys: no key data found for %s\n",request);
+ fprintf(output,"\nKEY 0x%s FAILED %d\n",
+ getkey,KEYSERVER_KEY_NOT_FOUND);
+ }
+ else
+ fprintf(output,"\nKEY 0x%s END\n",getkey);
+ }
+
+ return curl_err_to_gpg_err(res);
+}
+
+static void
+show_help (FILE *fp)
+{
+ fprintf (fp,"-h, --help\thelp\n");
+ fprintf (fp,"-V\t\tmachine readable version\n");
+ fprintf (fp,"--version\thuman readable version\n");
+ fprintf (fp,"-o\t\toutput to this file\n");
+}
+
+int
+main(int argc,char *argv[])
+{
+ int arg,ret=KEYSERVER_INTERNAL_ERROR,i;
+ char line[MAX_LINE];
+ char *thekey=NULL;
+ long follow_redirects=5;
+ char *proxy=NULL;
+ curl_version_info_data *curldata;
+ struct curl_slist *headers=NULL;
+
+ console=stderr;
+
+ /* Kludge to implement standard GNU options. */
+ if (argc > 1 && !strcmp (argv[1], "--version"))
+ {
+ printf ("gpgkeys_curl (GnuPG) %s\n", VERSION);
+ printf ("Uses: %s\n", curl_version());
+ return 0;
+ }
+ else if (argc > 1 && !strcmp (argv[1], "--help"))
+ {
+ show_help (stdout);
+ return 0;
+ }
+
+ while((arg=getopt(argc,argv,"hVo:"))!=-1)
+ switch(arg)
+ {
+ default:
+ case 'h':
+ show_help (console);
+ return KEYSERVER_OK;
+
+ case 'V':
+ fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
+ return KEYSERVER_OK;
+
+ case 'o':
+ output=fopen(optarg,"wb");
+ if(output==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+ optarg,strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ break;
+ }
+
+ if(argc>optind)
+ {
+ input=fopen(argv[optind],"r");
+ if(input==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+ argv[optind],strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ }
+
+ if(input==NULL)
+ input=stdin;
+
+ if(output==NULL)
+ output=stdout;
+
+ opt=init_ks_options();
+ if(!opt)
+ return KEYSERVER_NO_MEMORY;
+
+ /* Get the command and info block */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ {
+ int err;
+ char option[MAX_OPTION+1];
+
+ if(line[0]=='\n')
+ break;
+
+ err=parse_ks_options(line,opt);
+ if(err>0)
+ {
+ ret=err;
+ goto fail;
+ }
+ else if(err==0)
+ continue;
+
+ if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "s\n",option)==1)
+ {
+ int no=0;
+ char *start=&option[0];
+
+ option[MAX_OPTION]='\0';
+
+ if(strncasecmp(option,"no-",3)==0)
+ {
+ no=1;
+ start=&option[3];
+ }
+
+ if(strncasecmp(start,"http-proxy",10)==0)
+ {
+ /* Safe to not check the return code of strdup() here.
+ If it fails, we simply won't use a proxy. */
+ if(no)
+ {
+ free(proxy);
+ proxy=strdup("");
+ }
+ else if(start[10]=='=')
+ {
+ if(strlen(&start[11])<MAX_PROXY)
+ {
+ free(proxy);
+ proxy=strdup(&start[11]);
+ }
+ }
+ }
+ else if(strncasecmp(start,"follow-redirects",16)==0)
+ {
+ if(no)
+ follow_redirects=0;
+ else if(start[16]=='=')
+ follow_redirects=atoi(&start[17]);
+ else if(start[16]=='\0')
+ follow_redirects=-1;
+ }
+
+ continue;
+ }
+ }
+
+ if(!opt->scheme)
+ {
+ fprintf(console,"gpgkeys: no scheme supplied!\n");
+ ret=KEYSERVER_SCHEME_NOT_FOUND;
+ goto fail;
+ }
+
+ if(!opt->host)
+ {
+ fprintf(console,"gpgkeys: no keyserver host provided\n");
+ goto fail;
+ }
+
+ if(opt->timeout && register_timeout()==-1)
+ {
+ fprintf(console,"gpgkeys: unable to register timeout handler\n");
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl=curl_easy_init();
+ if(!curl)
+ {
+ fprintf(console,"gpgkeys: unable to initialize curl\n");
+ ret=KEYSERVER_INTERNAL_ERROR;
+ goto fail;
+ }
+
+ /* Make sure we have the protocol the user is asking for so we can
+ print a nicer error message. */
+ curldata=curl_version_info(CURLVERSION_NOW);
+ for(i=0;curldata->protocols[i];i++)
+ if(strcasecmp(curldata->protocols[i],opt->scheme)==0)
+ break;
+
+ if(curldata->protocols[i]==NULL)
+ {
+ fprintf(console,"gpgkeys: protocol `%s' not supported\n",opt->scheme);
+ ret=KEYSERVER_SCHEME_NOT_FOUND;
+ goto fail;
+ }
+
+ if(follow_redirects)
+ {
+ curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L);
+ if(follow_redirects>0)
+ curl_easy_setopt(curl,CURLOPT_MAXREDIRS,follow_redirects);
+ }
+
+ if(opt->auth)
+ curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth);
+
+ if(opt->debug)
+ {
+ fprintf(console,"gpgkeys: curl version = %s\n",curl_version());
+ curl_easy_setopt(curl,CURLOPT_STDERR,console);
+ curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
+ }
+
+ curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert);
+ curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file);
+
+ /* Avoid caches to get the most recent copy of the key. This is bug
+ #1061. In pre-curl versions of the code, we didn't do it. Then
+ we did do it (as a curl default) until curl changed the default.
+ Now we're doing it again, but in such a way that changing
+ defaults in the future won't impact us. We set both the Pragma
+ and Cache-Control versions of the header, so we're good with both
+ HTTP 1.0 and 1.1. */
+ headers=curl_slist_append(headers,"Pragma: no-cache");
+ if(headers)
+ headers=curl_slist_append(headers,"Cache-Control: no-cache");
+
+ if(!headers)
+ {
+ fprintf(console,"gpgkeys: out of memory when building HTTP headers\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
+
+ if(proxy)
+ curl_easy_setopt(curl,CURLOPT_PROXY,proxy);
+
+ /* If it's a GET or a SEARCH, the next thing to come in is the
+ keyids. If it's a SEND, then there are no keyids. */
+
+ if(opt->action==KS_GET)
+ {
+ /* Eat the rest of the file */
+ for(;;)
+ {
+ if(fgets(line,MAX_LINE,input)==NULL)
+ break;
+ else
+ {
+ if(line[0]=='\n' || line[0]=='\0')
+ break;
+
+ if(!thekey)
+ {
+ thekey=strdup(line);
+ if(!thekey)
+ {
+ fprintf(console,"gpgkeys: out of memory while "
+ "building key list\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ /* Trim the trailing \n */
+ thekey[strlen(line)-1]='\0';
+ }
+ }
+ }
+ }
+ else
+ {
+ fprintf(console,
+ "gpgkeys: this keyserver type only supports key retrieval\n");
+ goto fail;
+ }
+
+ if(!thekey)
+ {
+ fprintf(console,"gpgkeys: invalid keyserver instructions\n");
+ goto fail;
+ }
+
+ /* Send the response */
+
+ fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
+ fprintf(output,"PROGRAM %s\n\n",VERSION);
+
+ if(opt->verbose)
+ {
+ fprintf(console,"Scheme:\t\t%s\n",opt->scheme);
+ fprintf(console,"Host:\t\t%s\n",opt->host);
+ if(opt->port)
+ fprintf(console,"Port:\t\t%s\n",opt->port);
+ if(opt->path)
+ fprintf(console,"Path:\t\t%s\n",opt->path);
+ fprintf(console,"Command:\tGET\n");
+ }
+
+ set_timeout(opt->timeout);
+
+ ret=get_key(thekey);
+
+ fail:
+
+ free(thekey);
+
+ if(input!=stdin)
+ fclose(input);
+
+ if(output!=stdout)
+ fclose(output);
+
+ free_ks_options(opt);
+
+ curl_slist_free_all(headers);
+
+ if(curl)
+ curl_easy_cleanup(curl);
+
+ free(proxy);
+
+ curl_global_cleanup();
+
+ return ret;
+}
diff --git a/keyserver/gpgkeys_finger.c b/keyserver/gpgkeys_finger.c
new file mode 100644
index 0000000..721cb9a
--- /dev/null
+++ b/keyserver/gpgkeys_finger.c
@@ -0,0 +1,500 @@
+/* gpgkeys_finger.c - fetch a key via finger
+ * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif
+
+#define INCLUDED_BY_MAIN_MODULE 1
+#include "util.h"
+#include "keyserver.h"
+#include "ksutil.h"
+#include "iobuf.h"
+
+#ifdef HAVE_W32_SYSTEM
+#define sock_close(a) closesocket(a)
+#else
+#define sock_close(a) close(a)
+#endif
+
+extern char *optarg;
+extern int optind;
+
+static FILE *input,*output,*console;
+static struct ks_options *opt;
+
+
+/* Connect to SERVER at PORT and return a file descriptor or -1 on
+ error. */
+static int
+connect_server (const char *server, unsigned short port)
+{
+ int sock = -1;
+
+#ifdef HAVE_W32_SYSTEM
+ struct hostent *hp;
+ struct sockaddr_in addr;
+ unsigned long l;
+
+ w32_init_sockets ();
+
+ memset (&addr, 0, sizeof addr);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons (port);
+
+ /* Win32 gethostbyname doesn't handle IP addresses internally, so we
+ try inet_addr first on that platform only. */
+ if ((l = inet_addr (server)) != INADDR_NONE)
+ memcpy (&addr.sin_addr, &l, sizeof l);
+ else if ((hp = gethostbyname (server)))
+ {
+ if (hp->h_addrtype != AF_INET)
+ {
+ fprintf (console, "gpgkeys: unknown address family for `%s'\n",
+ server);
+ return -1;
+ }
+ if (hp->h_length != 4)
+ {
+ fprintf (console, "gpgkeys: illegal address length for `%s'\n",
+ server);
+ return -1;
+ }
+ memcpy (&addr.sin_addr, hp->h_addr, hp->h_length);
+ }
+ else
+ {
+ fprintf (console, "gpgkeys: host `%s' not found: ec=%d\n",
+ server, (int)WSAGetLastError ());
+ return -1;
+ }
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock == INVALID_SOCKET)
+ {
+ fprintf (console, "gpgkeys: error creating socket: ec=%d\n",
+ (int)WSAGetLastError ());
+ return -1;
+ }
+
+ if (connect (sock, (struct sockaddr *)&addr, sizeof addr))
+ {
+ fprintf (console, "gpgkeys: error connecting `%s': ec=%d\n",
+ server, (int)WSAGetLastError ());
+ sock_close (sock);
+ return -1;
+ }
+
+#else
+
+ struct sockaddr_in addr;
+ struct hostent *host;
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons (port);
+ host = gethostbyname ((char*)server);
+ if (!host)
+ {
+ fprintf (console, "gpgkeys: host `%s' not found: %s\n",
+ server, strerror (errno));
+ return -1;
+ }
+
+ addr.sin_addr = *(struct in_addr*)host->h_addr;
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock == -1)
+ {
+ fprintf (console, "gpgkeys: error creating socket: %s\n",
+ strerror (errno));
+ return -1;
+ }
+
+ if (connect (sock, (struct sockaddr *)&addr, sizeof addr) == -1)
+ {
+ fprintf (console, "gpgkeys: error connecting `%s': %s\n",
+ server, strerror (errno));
+ close (sock);
+ return -1;
+ }
+#endif
+
+ return sock;
+}
+
+static int
+write_server (int sock, const char *data, size_t length)
+{
+ int nleft;
+
+ nleft = length;
+ while (nleft > 0)
+ {
+ int nwritten;
+
+#ifdef HAVE_W32_SYSTEM
+ nwritten = send (sock, data, nleft, 0);
+ if ( nwritten == SOCKET_ERROR )
+ {
+ fprintf (console, "gpgkeys: write failed: ec=%d\n",
+ (int)WSAGetLastError ());
+ return -1;
+ }
+#else
+ nwritten = write (sock, data, nleft);
+ if (nwritten == -1)
+ {
+ if (errno == EINTR)
+ continue;
+ if (errno == EAGAIN)
+ {
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000;
+ select(0, NULL, NULL, NULL, &tv);
+ continue;
+ }
+ fprintf (console, "gpgkeys: write failed: %s\n", strerror(errno));
+ return -1;
+ }
+#endif
+ nleft -=nwritten;
+ data += nwritten;
+ }
+
+ return 0;
+}
+
+
+/* Send the finger REQUEST to the server. Returns 0 and a file descriptor
+ in R_SOCK if the request was sucessful. */
+static int
+send_request (const char *request, int *r_sock)
+{
+ char *server;
+ char *name;
+ int sock;
+
+ *r_sock = -1;
+ name = strdup (request);
+ if (!name)
+ {
+ fprintf(console,"gpgkeys: out of memory\n");
+ return KEYSERVER_NO_MEMORY;
+ }
+
+ server = strchr (name, '@');
+ if (!server)
+ {
+ fprintf (console, "gpgkeys: no name included in request\n");
+ free (name);
+ return KEYSERVER_GENERAL_ERROR;
+ }
+ *server++ = 0;
+
+ sock = connect_server (server, 79);
+ if (sock == -1)
+ {
+ free (name);
+ return KEYSERVER_UNREACHABLE;
+ }
+
+ if (write_server (sock, name, strlen (name))
+ || write_server (sock, "\r\n", 2))
+ {
+ free (name);
+ sock_close (sock);
+ return KEYSERVER_GENERAL_ERROR;
+ }
+ free (name);
+ *r_sock = sock;
+ return 0;
+}
+
+
+
+static int
+get_key (char *getkey)
+{
+ int rc;
+ int sock;
+ iobuf_t fp_read;
+ unsigned int maxlen, buflen, gotit=0;
+ byte *line = NULL;
+
+ if (strncmp (getkey,"0x",2)==0)
+ getkey+=2;
+
+ /* Frankly we don't know what keys the server will return; we
+ indicated the requested key anyway. */
+ fprintf(output,"KEY 0x%s BEGIN\n",getkey);
+
+ rc=send_request(opt->opaque,&sock);
+ if(rc)
+ {
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey, rc);
+ sock_close (sock);
+ return KEYSERVER_OK;
+ }
+
+ /* Hmmm, we use iobuf here only to cope with Windows socket
+ peculiarities (we can't used fdopen). */
+ fp_read = iobuf_sockopen (sock , "r");
+ if (!fp_read)
+ {
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey, KEYSERVER_INTERNAL_ERROR);
+ sock_close (sock);
+ return KEYSERVER_OK;
+ }
+
+ while ( iobuf_read_line ( fp_read, &line, &buflen, &maxlen))
+ {
+ maxlen=1024;
+
+ if(gotit)
+ {
+ print_nocr(output, (const char*)line);
+ if (!strncmp((char*)line,END,strlen(END)))
+ break;
+ }
+ else if(!strncmp((char*)line,BEGIN,strlen(BEGIN)))
+ {
+ print_nocr(output, (const char*)line);
+ gotit=1;
+ }
+ }
+
+ if(gotit)
+ fprintf (output,"KEY 0x%s END\n", getkey);
+ else
+ {
+ fprintf(console,"gpgkeys: no key data found for finger:%s\n",
+ opt->opaque);
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
+ }
+
+ xfree(line);
+ iobuf_close (fp_read);
+
+ return KEYSERVER_OK;
+}
+
+
+static void
+show_help (FILE *fp)
+{
+ fprintf (fp,"-h, --help\thelp\n");
+ fprintf (fp,"-V\t\tmachine readable version\n");
+ fprintf (fp,"--version\thuman readable version\n");
+ fprintf (fp,"-o\t\toutput to this file\n");
+}
+
+int
+main(int argc,char *argv[])
+{
+ int arg,ret=KEYSERVER_INTERNAL_ERROR;
+ char line[MAX_LINE];
+ char *thekey=NULL;
+
+ console=stderr;
+
+ /* Kludge to implement standard GNU options. */
+ if (argc > 1 && !strcmp (argv[1], "--version"))
+ {
+ fputs ("gpgkeys_finger (GnuPG) " VERSION"\n", stdout);
+ return 0;
+ }
+ else if (argc > 1 && !strcmp (argv[1], "--help"))
+ {
+ show_help (stdout);
+ return 0;
+ }
+
+ while((arg=getopt(argc,argv,"hVo:"))!=-1)
+ switch(arg)
+ {
+ default:
+ case 'h':
+ show_help (console);
+ return KEYSERVER_OK;
+
+ case 'V':
+ fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
+ return KEYSERVER_OK;
+
+ case 'o':
+ output=fopen(optarg,"w");
+ if(output==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+ optarg,strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ break;
+ }
+
+ if(argc>optind)
+ {
+ input=fopen(argv[optind],"r");
+ if(input==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+ argv[optind],strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ }
+
+ if(input==NULL)
+ input=stdin;
+
+ if(output==NULL)
+ output=stdout;
+
+ opt=init_ks_options();
+ if(!opt)
+ return KEYSERVER_NO_MEMORY;
+
+ /* Get the command and info block */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ {
+ int err;
+
+ if(line[0]=='\n')
+ break;
+
+ err=parse_ks_options(line,opt);
+ if(err>0)
+ {
+ ret=err;
+ goto fail;
+ }
+ else if(err==0)
+ continue;
+ }
+
+ if(opt->host)
+ {
+ fprintf(console,"gpgkeys: finger://relay/user syntax is not"
+ " supported. Use finger:user instead.\n");
+ ret=KEYSERVER_NOT_SUPPORTED;
+ goto fail;
+ }
+
+ if(opt->timeout && register_timeout()==-1)
+ {
+ fprintf(console,"gpgkeys: unable to register timeout handler\n");
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ /* If it's a GET or a SEARCH, the next thing to come in is the
+ keyids. If it's a SEND, then there are no keyids. */
+
+ if(opt->action==KS_GET)
+ {
+ /* Eat the rest of the file */
+ for(;;)
+ {
+ if(fgets(line,MAX_LINE,input)==NULL)
+ break;
+ else
+ {
+ if(line[0]=='\n' || line[0]=='\0')
+ break;
+
+ if(!thekey)
+ {
+ thekey=strdup(line);
+ if(!thekey)
+ {
+ fprintf(console,"gpgkeys: out of memory while "
+ "building key list\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ /* Trim the trailing \n */
+ thekey[strlen(line)-1]='\0';
+ }
+ }
+ }
+ }
+ else
+ {
+ fprintf(console,
+ "gpgkeys: this keyserver type only supports key retrieval\n");
+ goto fail;
+ }
+
+ if(!thekey || !opt->opaque)
+ {
+ fprintf(console,"gpgkeys: invalid keyserver instructions\n");
+ goto fail;
+ }
+
+ /* Send the response */
+
+ fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
+ fprintf(output,"PROGRAM %s\n\n",VERSION);
+
+ if(opt->verbose>1)
+ {
+ fprintf(console,"User:\t\t%s\n",opt->opaque);
+ fprintf(console,"Command:\tGET\n");
+ }
+
+ set_timeout(opt->timeout);
+
+ ret=get_key(thekey);
+
+ fail:
+
+ free(thekey);
+
+ if(input!=stdin)
+ fclose(input);
+
+ if(output!=stdout)
+ fclose(output);
+
+ free_ks_options(opt);
+
+ return ret;
+}
diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c
new file mode 100644
index 0000000..ee6421a
--- /dev/null
+++ b/keyserver/gpgkeys_hkp.c
@@ -0,0 +1,977 @@
+/* gpgkeys_hkp.c - talk to an HKP keyserver
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ * 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ *
+ * In addition, as a special exception, the Free Software Foundation
+ * gives permission to link the code of the keyserver helper tools:
+ * gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
+ * project's "OpenSSL" library (or with modified versions of it that
+ * use the same license as the "OpenSSL" library), and distribute the
+ * linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If
+ * you modify this file, you may extend this exception to your version
+ * of the file, but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#else
+#include "curl-shim.h"
+#endif
+#include "util.h"
+#ifdef USE_DNS_SRV
+#include "srv.h"
+#endif
+#include "keyserver.h"
+#include "ksutil.h"
+
+extern char *optarg;
+extern int optind;
+
+static FILE *input,*output,*console;
+static CURL *curl;
+static struct ks_options *opt;
+static char errorbuffer[CURL_ERROR_SIZE];
+static char *proto,*port;
+
+static size_t
+curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream)
+{
+ static int checked=0,swallow=0;
+
+ if(!checked)
+ {
+ /* If the document begins with a '<', assume it's a HTML
+ response, which we don't support. Discard the whole message
+ body. GPG can handle it, but this is an optimization to deal
+ with it on this side of the pipe. */
+ const char *buf=ptr;
+ if(buf[0]=='<')
+ swallow=1;
+
+ checked=1;
+ }
+
+ if(swallow || fwrite(ptr,size,nmemb,stream)==nmemb)
+ return size*nmemb;
+ else
+ return 0;
+}
+
+/* Append but avoid creating a double slash // in the path. */
+static char *
+append_path(char *dest,const char *src)
+{
+ size_t n=strlen(dest);
+
+ if(src[0]=='/' && n>0 && dest[n-1]=='/')
+ dest[n-1]='\0';
+
+ return strcat(dest,src);
+}
+
+/* Return a pointer into STRING so that appending PATH to STRING will
+ not yield a duplicated slash. */
+static const char *
+appendable_path (const char *string, const char *path)
+{
+ size_t n;
+
+ if (path[0] == '/' && (n=strlen (string)) && string[n-1] == '/')
+ return path+1;
+ else
+ return path;
+}
+
+
+int
+send_key(int *r_eof)
+{
+ CURLcode res;
+ char request[MAX_URL+15];
+ int begin=0,end=0,ret=KEYSERVER_INTERNAL_ERROR;
+ char keyid[17],state[6];
+ char line[MAX_LINE];
+ char *key=NULL,*encoded_key=NULL;
+ size_t keylen=0,keymax=0;
+
+ /* Read and throw away input until we see the BEGIN */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
+ && strcmp(state,"BEGIN")==0)
+ {
+ begin=1;
+ break;
+ }
+
+ if(!begin)
+ {
+ /* i.e. eof before the KEY BEGIN was found. This isn't an
+ error. */
+ *r_eof=1;
+ ret=KEYSERVER_OK;
+ goto fail;
+ }
+
+ /* Now slurp up everything until we see the END */
+
+ while(fgets(line,MAX_LINE,input))
+ if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
+ && strcmp(state,"END")==0)
+ {
+ end=1;
+ break;
+ }
+ else
+ {
+ if(strlen(line)+keylen>keymax)
+ {
+ char *tmp;
+
+ keymax+=200;
+ tmp=realloc(key,keymax+1);
+ if(!tmp)
+ {
+ free(key);
+ fprintf(console,"gpgkeys: out of memory\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ key=tmp;
+ }
+
+ strcpy(&key[keylen],line);
+ keylen+=strlen(line);
+ }
+
+ if(!end)
+ {
+ fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
+ *r_eof=1;
+ ret=KEYSERVER_KEY_INCOMPLETE;
+ goto fail;
+ }
+
+ encoded_key=curl_escape(key,keylen);
+ if(!encoded_key)
+ {
+ fprintf(console,"gpgkeys: out of memory\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ free(key);
+
+ key = strconcat ("keytext=", encoded_key, NULL);
+ if(!key)
+ {
+ fprintf(console,"gpgkeys: out of memory\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ strcpy(request,proto);
+ strcat(request,"://");
+ strcat(request,opt->host);
+ strcat(request,":");
+ strcat(request,port);
+ strcat(request,opt->path);
+ /* request is MAX_URL+15 bytes long - MAX_URL covers the whole URL,
+ including any supplied path. The 15 covers /pks/add. */
+ append_path(request,"/pks/add");
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+
+ curl_easy_setopt(curl,CURLOPT_URL,request);
+ curl_easy_setopt(curl,CURLOPT_POST,1L);
+ curl_easy_setopt(curl,CURLOPT_POSTFIELDS,key);
+ curl_easy_setopt(curl,CURLOPT_FAILONERROR,1L);
+
+ res=curl_easy_perform(curl);
+ if(res!=0)
+ {
+ fprintf(console,"gpgkeys: HTTP post error %d: %s\n",res,errorbuffer);
+ ret=curl_err_to_gpg_err(res);
+ goto fail;
+ }
+ else
+ fprintf(output,"\nKEY %s SENT\n",keyid);
+
+ ret=KEYSERVER_OK;
+
+ fail:
+ xfree (key);
+ curl_free(encoded_key);
+
+ if(ret!=0 && begin)
+ fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
+
+ return ret;
+}
+
+static int
+get_key(char *getkey)
+{
+ CURLcode res;
+ char request[MAX_URL+92];
+ char *offset;
+ struct curl_writer_ctx ctx;
+ size_t keylen;
+
+ memset(&ctx,0,sizeof(ctx));
+
+ /* Build the search string. HKP only uses the short key IDs. */
+
+ if(strncmp(getkey,"0x",2)==0)
+ getkey+=2;
+
+ fprintf(output,"KEY 0x%s BEGIN\n",getkey);
+
+ if(strlen(getkey)==32)
+ {
+ fprintf(console,
+ "gpgkeys: HKP keyservers do not support v3 fingerprints\n");
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED);
+ return KEYSERVER_NOT_SUPPORTED;
+ }
+
+ strcpy(request,proto);
+ strcat(request,"://");
+ strcat(request,opt->host);
+ strcat(request,":");
+ strcat(request,port);
+ strcat(request,opt->path);
+ /* request is MAX_URL+55 bytes long - MAX_URL covers the whole URL,
+ including any supplied path. The 92 overcovers this /pks/... etc
+ string plus the 8, 16, or 40 bytes of key id/fingerprint */
+ append_path(request,"/pks/lookup?op=get&options=mr&search=0x");
+
+ /* send only fingerprint, long key id, or short keyid. see:
+ https://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-3.1.1.1 */
+ keylen = strlen(getkey);
+ if(keylen >= 40)
+ offset=&getkey[keylen-40];
+ else if(keylen >= 16)
+ offset=&getkey[keylen-16];
+ else if(keylen >= 8)
+ offset=&getkey[keylen-8];
+ else
+ offset=getkey;
+
+ strcat(request,offset);
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+
+ curl_easy_setopt(curl,CURLOPT_URL,request);
+ curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer);
+ ctx.stream=output;
+ curl_easy_setopt(curl,CURLOPT_FILE,&ctx);
+
+ res=curl_easy_perform(curl);
+ if(res!=CURLE_OK)
+ {
+ fprintf(console,"gpgkeys: HTTP fetch error %d: %s\n",res,errorbuffer);
+ fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res));
+ }
+ else
+ {
+ curl_writer_finalize(&ctx);
+ if(!ctx.flags.done)
+ {
+ fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
+ fprintf(output,"\nKEY 0x%s FAILED %d\n",
+ getkey,KEYSERVER_KEY_NOT_FOUND);
+ }
+ else
+ fprintf(output,"\nKEY 0x%s END\n",getkey);
+ }
+
+ return KEYSERVER_OK;
+}
+
+static int
+get_name(const char *getkey)
+{
+ CURLcode res;
+ char *request=NULL;
+ char *searchkey_encoded;
+ int ret=KEYSERVER_INTERNAL_ERROR;
+ struct curl_writer_ctx ctx;
+
+ memset(&ctx,0,sizeof(ctx));
+
+ searchkey_encoded=curl_escape((char *)getkey,0);
+ if(!searchkey_encoded)
+ {
+ fprintf(console,"gpgkeys: out of memory\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ request = strconcat
+ (proto,
+ "://",
+ opt->host,
+ ":",
+ port,
+ opt->path,
+ appendable_path (opt->path,"/pks/lookup?op=get&options=mr&search="),
+ searchkey_encoded,
+ opt->action == KS_GETNAME? "&exact=on":"",
+ NULL);
+ if(!request)
+ {
+ fprintf(console,"gpgkeys: out of memory\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ fprintf(output,"NAME %s BEGIN\n",getkey);
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+
+ curl_easy_setopt(curl,CURLOPT_URL,request);
+ curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer);
+ ctx.stream=output;
+ curl_easy_setopt(curl,CURLOPT_FILE,&ctx);
+
+ res=curl_easy_perform(curl);
+ if(res!=CURLE_OK)
+ {
+ fprintf(console,"gpgkeys: HTTP fetch error %d: %s\n",res,errorbuffer);
+ ret=curl_err_to_gpg_err(res);
+ }
+ else
+ {
+ curl_writer_finalize(&ctx);
+ if(!ctx.flags.done)
+ {
+ fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
+ ret=KEYSERVER_KEY_NOT_FOUND;
+ }
+ else
+ {
+ fprintf(output,"\nNAME %s END\n",getkey);
+ ret=KEYSERVER_OK;
+ }
+ }
+
+ fail:
+ curl_free(searchkey_encoded);
+ xfree (request);
+
+ if(ret!=KEYSERVER_OK)
+ fprintf(output,"\nNAME %s FAILED %d\n",getkey,ret);
+
+ return ret;
+}
+
+static int
+search_key(const char *searchkey)
+{
+ CURLcode res;
+ char *request=NULL;
+ char *searchkey_encoded;
+ int ret=KEYSERVER_INTERNAL_ERROR;
+ enum ks_search_type search_type;
+ const char *hexprefix;
+
+ search_type=classify_ks_search(&searchkey);
+
+ if(opt->debug)
+ fprintf(console,"gpgkeys: search type is %d, and key is \"%s\"\n",
+ search_type,searchkey);
+
+ searchkey_encoded=curl_escape((char *)searchkey,0);
+ if(!searchkey_encoded)
+ {
+ fprintf(console,"gpgkeys: out of memory\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ /* HKP keyservers like the 0x to be present when searching by
+ keyid. */
+ hexprefix = (search_type==KS_SEARCH_KEYID_SHORT
+ || search_type==KS_SEARCH_KEYID_LONG)? "0x":"";
+
+ request = strconcat
+ (proto,
+ "://",
+ opt->host,
+ ":",
+ port,
+ opt->path,
+ appendable_path (opt->path, "/pks/lookup?op=index&options=mr&search="),
+ hexprefix,
+ searchkey_encoded,
+ opt->action == KS_GETNAME? "&exact=on":"",
+ NULL);
+ if(!request)
+ {
+ fprintf(console,"gpgkeys: out of memory\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ fprintf(output,"SEARCH %s BEGIN\n",searchkey);
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: HTTP URL is `%s'\n",request);
+
+ curl_easy_setopt(curl,CURLOPT_URL,request);
+ curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_mrindex_writer);
+ curl_easy_setopt(curl,CURLOPT_FILE,output);
+
+ res=curl_easy_perform(curl);
+ if(res!=0)
+ {
+ fprintf(console,"gpgkeys: HTTP search error %d: %s\n",res,errorbuffer);
+ ret=curl_err_to_gpg_err(res);
+ }
+ else
+ {
+ fprintf(output,"\nSEARCH %s END\n",searchkey);
+ ret=KEYSERVER_OK;
+ }
+
+ fail:
+ curl_free(searchkey_encoded);
+ xfree (request);
+
+ if(ret!=KEYSERVER_OK)
+ fprintf(output,"\nSEARCH %s FAILED %d\n",searchkey,ret);
+
+ return ret;
+}
+
+void
+fail_all(struct keylist *keylist,int err)
+{
+ if(!keylist)
+ return;
+
+ if(opt->action==KS_SEARCH)
+ {
+ fprintf(output,"SEARCH ");
+ while(keylist)
+ {
+ fprintf(output,"%s ",keylist->str);
+ keylist=keylist->next;
+ }
+ fprintf(output,"FAILED %d\n",err);
+ }
+ else
+ while(keylist)
+ {
+ fprintf(output,"KEY %s FAILED %d\n",keylist->str,err);
+ keylist=keylist->next;
+ }
+}
+
+#ifdef HAVE_LIBCURL
+/* If there is a SRV record, take the highest ranked possibility.
+ This is a hack, as we don't proceed downwards. */
+static void
+srv_replace(const char *srvtag)
+{
+#ifdef USE_DNS_SRV
+ struct srventry *srvlist=NULL;
+ int srvcount;
+
+ if(!srvtag)
+ return;
+
+ if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME)
+ {
+ char srvname[MAXDNAME];
+
+ strcpy(srvname,"_");
+ strcat(srvname,srvtag);
+ strcat(srvname,"._tcp.");
+ strcat(srvname,opt->host);
+ srvcount=getsrv(srvname,&srvlist);
+ }
+
+ if(srvlist)
+ {
+ char *newname,*newport;
+
+ newname=strdup(srvlist->target);
+ newport=malloc(MAX_PORT);
+ if(newname && newport)
+ {
+ free(opt->host);
+ free(opt->port);
+ opt->host=newname;
+ snprintf(newport,MAX_PORT,"%u",srvlist->port);
+ opt->port=newport;
+ }
+ else
+ {
+ free(newname);
+ free(newport);
+ }
+ }
+#endif
+}
+#endif
+
+static void
+show_help (FILE *fp)
+{
+ fprintf (fp,"-h, --help\thelp\n");
+ fprintf (fp,"-V\t\tmachine readable version\n");
+ fprintf (fp,"--version\thuman readable version\n");
+ fprintf (fp,"-o\t\toutput to this file\n");
+}
+
+int
+main(int argc,char *argv[])
+{
+ int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1;
+ char line[MAX_LINE];
+ int failed=0;
+ struct keylist *keylist=NULL,*keyptr=NULL;
+ char *proxy=NULL;
+ struct curl_slist *headers=NULL;
+
+ console=stderr;
+
+ /* Kludge to implement standard GNU options. */
+ if (argc > 1 && !strcmp (argv[1], "--version"))
+ {
+ printf ("gpgkeys_hkp (GnuPG) %s\n", VERSION);
+ printf ("Uses: %s\n", curl_version());
+ return 0;
+ }
+ else if (argc > 1 && !strcmp (argv[1], "--help"))
+ {
+ show_help (stdout);
+ return 0;
+ }
+
+ while((arg=getopt(argc,argv,"hVo:"))!=-1)
+ switch(arg)
+ {
+ default:
+ case 'h':
+ show_help (console);
+ return KEYSERVER_OK;
+
+ case 'V':
+ fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
+ return KEYSERVER_OK;
+
+ case 'o':
+ output=fopen(optarg,"w");
+ if(output==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+ optarg,strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ break;
+ }
+
+ if(argc>optind)
+ {
+ input=fopen(argv[optind],"r");
+ if(input==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+ argv[optind],strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ }
+
+ if(input==NULL)
+ input=stdin;
+
+ if(output==NULL)
+ output=stdout;
+
+ opt=init_ks_options();
+ if(!opt)
+ return KEYSERVER_NO_MEMORY;
+
+ /* Get the command and info block */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ {
+ int err;
+ char option[MAX_OPTION+1];
+
+ if(line[0]=='\n')
+ break;
+
+ err=parse_ks_options(line,opt);
+ if(err>0)
+ {
+ ret=err;
+ goto fail;
+ }
+ else if(err==0)
+ continue;
+
+ if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "s\n",option)==1)
+ {
+ int no=0;
+ char *start=&option[0];
+
+ option[MAX_OPTION]='\0';
+
+ if(strncasecmp(option,"no-",3)==0)
+ {
+ no=1;
+ start=&option[3];
+ }
+
+ if(strncasecmp(start,"http-proxy",10)==0)
+ {
+ if(no)
+ {
+ free(proxy);
+ proxy=strdup("");
+ }
+ else if(start[10]=='=')
+ {
+ if(strlen(&start[11])<MAX_PROXY)
+ {
+ free(proxy);
+ proxy=strdup(&start[11]);
+ }
+ }
+ }
+ else if(strcasecmp(start,"try-dns-srv")==0)
+ {
+ if(no)
+ try_srv=0;
+ else
+ try_srv=1;
+ }
+
+ continue;
+ }
+ }
+
+ if(!opt->scheme)
+ {
+ fprintf(console,"gpgkeys: no scheme supplied!\n");
+ ret=KEYSERVER_SCHEME_NOT_FOUND;
+ goto fail;
+ }
+
+ if(ks_strcasecmp(opt->scheme,"hkps")==0)
+ {
+ proto="https";
+ port="443";
+ }
+ else
+ {
+ proto="http";
+ port="11371";
+ }
+
+ if(!opt->host)
+ {
+ fprintf(console,"gpgkeys: no keyserver host provided\n");
+ goto fail;
+ }
+
+ if(opt->timeout && register_timeout()==-1)
+ {
+ fprintf(console,"gpgkeys: unable to register timeout handler\n");
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+ curl=curl_easy_init();
+ if(!curl)
+ {
+ fprintf(console,"gpgkeys: unable to initialize curl\n");
+ ret=KEYSERVER_INTERNAL_ERROR;
+ goto fail;
+ }
+
+ /* If the user gives a :port, then disable SRV. The semantics of a
+ specified port and SRV do not play well together. */
+ if(opt->port)
+ port=opt->port;
+ else if(try_srv)
+ {
+ char *srvtag;
+
+ if(ks_strcasecmp(opt->scheme,"hkp")==0)
+ srvtag="pgpkey-http";
+ else if(ks_strcasecmp(opt->scheme,"hkps")==0)
+ srvtag="pgpkey-https";
+ else
+ srvtag=NULL;
+
+#ifdef HAVE_LIBCURL
+ /* We're using libcurl, so fake SRV support via our wrapper.
+ This isn't as good as true SRV support, as we do not try all
+ possible targets at one particular level and work our way
+ down the list, but it's better than nothing. */
+ srv_replace(srvtag);
+#else
+ /* We're using our internal curl shim, so we can use its (true)
+ SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real
+ libcurl option. It's specific to our shim. */
+ curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,srvtag);
+#endif
+ }
+
+ curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer);
+
+ if(opt->auth)
+ curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth);
+
+ if(opt->debug)
+ {
+ fprintf(console,"gpgkeys: curl version = %s\n",curl_version());
+ curl_easy_setopt(curl,CURLOPT_STDERR,console);
+ curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
+ }
+
+ curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert);
+ curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file);
+
+ /* Avoid caches to get the most recent copy of the key. This is bug
+ #1061. In pre-curl versions of the code, we didn't do it. Then
+ we did do it (as a curl default) until curl changed the default.
+ Now we're doing it again, but in such a way that changing
+ defaults in the future won't impact us. We set both the Pragma
+ and Cache-Control versions of the header, so we're good with both
+ HTTP 1.0 and 1.1. */
+ headers=curl_slist_append(headers,"Pragma: no-cache");
+ if(headers)
+ headers=curl_slist_append(headers,"Cache-Control: no-cache");
+
+ if(!headers)
+ {
+ fprintf(console,"gpgkeys: out of memory when building HTTP headers\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
+
+ if(proxy)
+ curl_easy_setopt(curl,CURLOPT_PROXY,proxy);
+
+ /* If it's a GET or a SEARCH, the next thing to come in is the
+ keyids. If it's a SEND, then there are no keyids. */
+
+ if(opt->action==KS_SEND)
+ while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
+ else if(opt->action==KS_GET
+ || opt->action==KS_GETNAME || opt->action==KS_SEARCH)
+ {
+ for(;;)
+ {
+ struct keylist *work;
+
+ if(fgets(line,MAX_LINE,input)==NULL)
+ break;
+ else
+ {
+ if(line[0]=='\n' || line[0]=='\0')
+ break;
+
+ work=malloc(sizeof(struct keylist));
+ if(work==NULL)
+ {
+ fprintf(console,"gpgkeys: out of memory while "
+ "building key list\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ strcpy(work->str,line);
+
+ /* Trim the trailing \n */
+ work->str[strlen(line)-1]='\0';
+
+ work->next=NULL;
+
+ /* Always attach at the end to keep the list in proper
+ order for searching */
+ if(keylist==NULL)
+ keylist=work;
+ else
+ keyptr->next=work;
+
+ keyptr=work;
+ }
+ }
+ }
+ else
+ {
+ fprintf(console,"gpgkeys: no keyserver command specified\n");
+ goto fail;
+ }
+
+ /* Send the response */
+
+ fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
+ fprintf(output,"PROGRAM %s\n\n",VERSION);
+
+ if(opt->verbose>1)
+ {
+ fprintf(console,"Host:\t\t%s\n",opt->host);
+ if(opt->port)
+ fprintf(console,"Port:\t\t%s\n",opt->port);
+ if(strcmp(opt->path,"/")!=0)
+ fprintf(console,"Path:\t\t%s\n",opt->path);
+ fprintf(console,"Command:\t%s\n",ks_action_to_string(opt->action));
+ }
+
+ if(opt->action==KS_GET)
+ {
+ keyptr=keylist;
+
+ while(keyptr!=NULL)
+ {
+ set_timeout(opt->timeout);
+
+ if(get_key(keyptr->str)!=KEYSERVER_OK)
+ failed++;
+
+ keyptr=keyptr->next;
+ }
+ }
+ else if(opt->action==KS_GETNAME)
+ {
+ keyptr=keylist;
+
+ while(keyptr!=NULL)
+ {
+ set_timeout(opt->timeout);
+
+ if(get_name(keyptr->str)!=KEYSERVER_OK)
+ failed++;
+
+ keyptr=keyptr->next;
+ }
+ }
+ else if(opt->action==KS_SEND)
+ {
+ int myeof=0;
+
+ do
+ {
+ set_timeout(opt->timeout);
+
+ if(send_key(&myeof)!=KEYSERVER_OK)
+ failed++;
+ }
+ while(!myeof);
+ }
+ else if(opt->action==KS_SEARCH)
+ {
+ char *searchkey=NULL;
+ int len=0;
+
+ set_timeout(opt->timeout);
+
+ /* To search, we stick a space in between each key to search
+ for. */
+
+ keyptr=keylist;
+ while(keyptr!=NULL)
+ {
+ len+=strlen(keyptr->str)+1;
+ keyptr=keyptr->next;
+ }
+
+ searchkey=malloc(len+1);
+ if(searchkey==NULL)
+ {
+ ret=KEYSERVER_NO_MEMORY;
+ fail_all(keylist,KEYSERVER_NO_MEMORY);
+ goto fail;
+ }
+
+ searchkey[0]='\0';
+
+ keyptr=keylist;
+ while(keyptr!=NULL)
+ {
+ strcat(searchkey,keyptr->str);
+ strcat(searchkey," ");
+ keyptr=keyptr->next;
+ }
+
+ /* Nail that last space */
+ if(*searchkey)
+ searchkey[strlen(searchkey)-1]='\0';
+
+ if(search_key(searchkey)!=KEYSERVER_OK)
+ failed++;
+
+ free(searchkey);
+ }
+ else
+ abort();
+
+ if(!failed)
+ ret=KEYSERVER_OK;
+
+ fail:
+ while(keylist!=NULL)
+ {
+ struct keylist *current=keylist;
+ keylist=keylist->next;
+ free(current);
+ }
+
+ if(input!=stdin)
+ fclose(input);
+
+ if(output!=stdout)
+ fclose(output);
+
+ free_ks_options(opt);
+
+ curl_slist_free_all(headers);
+
+ if(curl)
+ curl_easy_cleanup(curl);
+
+ free(proxy);
+
+ return ret;
+}
diff --git a/keyserver/gpgkeys_kdns.c b/keyserver/gpgkeys_kdns.c
new file mode 100644
index 0000000..5979b06
--- /dev/null
+++ b/keyserver/gpgkeys_kdns.c
@@ -0,0 +1,444 @@
+/* gpgkeys_kdns.c - Fetch a key via the GnuPG specific KDNS scheme.
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+#include <assert.h>
+#ifdef HAVE_ADNS_H
+# include <adns.h>
+# ifndef HAVE_ADNS_FREE
+# define adns_free free
+# endif
+#endif
+
+#define INCLUDED_BY_MAIN_MODULE 1
+#include "util.h"
+#include "keyserver.h"
+#include "ksutil.h"
+
+/* Our own name. */
+#define PGM "gpgkeys_kdns"
+
+/* getopt(3) requires declarion of some global variables. */
+extern char *optarg;
+extern int optind;
+
+/* Convenience variables usually intialized withn std{in,out,err}. */
+static FILE *input, *output, *console;
+
+/* Standard keyserver module options. */
+static struct ks_options *opt;
+
+/* The flags we pass to adns_init: Do not allow any environment
+ variables and for now enable debugging. */
+#define MY_ADNS_INITFLAGS (adns_if_noenv)
+
+
+/* ADNS has no support for CERT yes. */
+#define my_adns_r_cert 37
+
+/* The root of the KDNS tree. */
+static const char *kdns_root;
+
+/* The replacement string for the at sign. */
+static const char *kdns_at_repl;
+
+/* Flag indicating that a TCP conenction should be used. */
+static int kdns_usevc;
+
+
+
+/* Retrieve one key. ADDRESS should be an RFC-2822 addr-spec. */
+static int
+get_key (adns_state adns_ctx, char *address)
+{
+ int ret = KEYSERVER_INTERNAL_ERROR;
+ const char *domain;
+ char *name = NULL;
+ adns_answer *answer = NULL;
+ const unsigned char *data;
+ int datalen;
+ struct b64state b64state;
+ char *p;
+
+ domain = strrchr (address, '@');
+ if (!domain || domain == address || !domain[1])
+ {
+ fprintf (console, PGM": invalid mail address `%s'\n", address);
+ ret = KEYSERVER_GENERAL_ERROR;
+ goto leave;
+ }
+ name = xtrymalloc (strlen (address) + strlen (kdns_at_repl)
+ + 1 + strlen (kdns_root) + 1);
+ if (!name)
+ goto leave;
+ memcpy (name, address, domain - address);
+ p = stpcpy (name + (domain-address), ".");
+ if (*kdns_at_repl)
+ p = stpcpy (stpcpy (p, kdns_at_repl), ".");
+ p = stpcpy (p, domain+1);
+ if (*kdns_root)
+ strcpy (stpcpy (p, "."), kdns_root);
+
+ fprintf (output,"NAME %s BEGIN\n", address);
+ if (opt->verbose > 2)
+ fprintf(console, PGM": looking up `%s'\n", name);
+
+ if ( adns_synchronous (adns_ctx, name, (adns_r_unknown | my_adns_r_cert),
+ adns_qf_quoteok_query|(kdns_usevc?adns_qf_usevc:0),
+ &answer) )
+ {
+ fprintf (console, PGM": DNS query failed: %s\n", strerror (errno));
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+ if (answer->status != adns_s_ok)
+ {
+ fprintf (console, PGM": DNS query returned: %s (%s)\n",
+ adns_strerror (answer->status),
+ adns_errabbrev (answer->status));
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+ datalen = answer->rrs.byteblock->len;
+ data = answer->rrs.byteblock->data;
+
+ if ( opt->debug > 1 )
+ {
+ int i;
+
+ fprintf (console, "got %d bytes of data:", datalen);
+ for (i=0; i < datalen; i++)
+ {
+ if (!(i % 32))
+ fprintf (console, "\n%08x ", i);
+ fprintf (console, "%02x", data[i]);
+ }
+ putc ('\n', console);
+ }
+ if ( datalen < 5 )
+ {
+ fprintf (console, PGM": error: truncated CERT record\n");
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+
+ switch ( ((data[0]<<8)|data[1]) )
+ {
+ case 3: /* CERT type is PGP. */
+ /* (key tag and algorithm fields are ignored for this CERT type). */
+ data += 5;
+ datalen -= 5;
+ if ( datalen < 11 )
+ {
+ /* Gpg checks for a minium length of 11, thus we do the same. */
+ fprintf (console, PGM": error: OpenPGP data to short\n");
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+ if (b64enc_start (&b64state, output, "PGP PUBLIC KEY BLOCK")
+ || b64enc_write (&b64state, data, datalen)
+ || b64enc_finish (&b64state))
+ goto leave; /* Oops, base64 encoder failed. */
+ break;
+
+ default:
+ fprintf (console, PGM": CERT type %d ignored\n", (data[0] <<8|data[1]));
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+
+ ret = 0; /* All fine. */
+
+ leave:
+ if (ret)
+ fprintf (output, "\nNAME %s FAILED %d\n", address, ret);
+ else
+ fprintf (output, "\nNAME %s END\n", address);
+ adns_free (answer);
+ xfree (name);
+ return ret;
+}
+
+
+/* Print some help. */
+static void
+show_help (FILE *fp)
+{
+ fputs (PGM" (GnuPG) " VERSION"\n\n", fp);
+ fputs (" -h\thelp\n"
+ " -V\tversion\n"
+ " -o\toutput to this file\n"
+ "\n", fp);
+ fputs ("This keyserver helper accepts URLs of the form:\n"
+ " kdns://[NAMESERVER]/[ROOT][?at=STRING]\n"
+ "with\n"
+ " NAMESERVER used for queries (default: system standard)\n"
+ " ROOT a DNS name appended to the query (default: none)\n"
+ " STRING a string to replace the '@' (default: \".\")\n"
+ "If a long answer is expected add the parameter \"usevc=1\".\n"
+ "\n", fp);
+ fputs ("Example: A query for \"hacker@gnupg.org\" with\n"
+ " kdns://10.0.0.1/example.net?at=_key&usevc=1\n"
+ "setup as --auto-key-lookup does a CERT record query\n"
+ "with type PGP on the nameserver 10.0.0.1 for\n"
+ " hacker._key_.gnupg.org.example.net\n"
+ "\n", fp);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int arg;
+ int ret = KEYSERVER_INTERNAL_ERROR;
+ char line[MAX_LINE];
+ struct keylist *keylist = NULL;
+ struct keylist **keylist_tail = &keylist;
+ struct keylist *akey;
+ int failed = 0;
+ adns_state adns_ctx = NULL;
+ adns_initflags my_adns_initflags = MY_ADNS_INITFLAGS;
+ int tmprc;
+
+ /* The defaults for the KDNS name mangling. */
+ kdns_root = "";
+ kdns_at_repl = "";
+
+ console = stderr;
+
+ /* Kludge to implement standard GNU options. */
+ if (argc > 1 && !strcmp (argv[1], "--version"))
+ {
+ fputs (PGM" (GnuPG) " VERSION"\n", stdout);
+ return 0;
+ }
+ else if (argc > 1 && !strcmp (argv[1], "--help"))
+ {
+ show_help (stdout);
+ return 0;
+ }
+
+ while ( (arg = getopt (argc, argv, "hVo:")) != -1 )
+ {
+ switch(arg)
+ {
+ case 'V':
+ printf ("%d\n%s\n", KEYSERVER_PROTO_VERSION, VERSION);
+ return KEYSERVER_OK;
+
+ case 'o':
+ output = fopen (optarg,"w");
+ if (!output)
+ {
+ fprintf (console, PGM": cannot open output file `%s': %s\n",
+ optarg, strerror(errno) );
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ break;
+
+ case 'h':
+ default:
+ show_help (console);
+ return KEYSERVER_OK;
+ }
+ }
+
+ if (argc > optind)
+ {
+ input = fopen (argv[optind], "r");
+ if (!input)
+ {
+ fprintf (console, PGM": cannot open input file `%s': %s\n",
+ argv[optind], strerror(errno) );
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ }
+
+ if (!input)
+ input = stdin;
+
+ if (!output)
+ output = stdout;
+
+ opt = init_ks_options();
+ if(!opt)
+ return KEYSERVER_NO_MEMORY;
+
+ /* Get the command and info block */
+ while ( fgets(line,MAX_LINE,input) )
+ {
+ int err;
+
+ if(line[0]=='\n')
+ break;
+
+ err = parse_ks_options (line, opt);
+ if (err > 0)
+ {
+ ret = err;
+ goto leave;
+ }
+ else if (!err)
+ continue;
+ }
+
+ if (opt->timeout && register_timeout() == -1 )
+ {
+ fprintf (console, PGM": unable to register timeout handler\n");
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ if (opt->verbose)
+ {
+ fprintf (console, PGM": HOST=%s\n", opt->host? opt->host:"(none)");
+ fprintf (console, PGM": PATH=%s\n", opt->path? opt->path:"(none)");
+ }
+ if (opt->path && *opt->path == '/')
+ {
+ char *p, *pend;
+
+ kdns_root = opt->path+1;
+ p = strchr (opt->path+1, '?');
+ if (p)
+ {
+ *p++ = 0;
+ do
+ {
+ pend = strchr (p, '&');
+ if (pend)
+ *pend++ = 0;
+ if (!strncmp (p, "at=", 3))
+ kdns_at_repl = p+3;
+ else if (!strncmp (p, "usevc=", 6))
+ kdns_usevc = !!atoi (p+6);
+ }
+ while ((p = pend));
+ }
+ }
+ if (strchr (kdns_root, '/'))
+ {
+ fprintf (console, PGM": invalid character in KDNS root\n");
+ return KEYSERVER_GENERAL_ERROR;
+ }
+ if (!strcmp (kdns_at_repl, "."))
+ kdns_at_repl = "";
+
+ if (opt->verbose)
+ {
+ fprintf (console, PGM": kdns_root=%s\n", kdns_root);
+ fprintf (console, PGM": kdns_at=%s\n", kdns_at_repl);
+ fprintf (console, PGM": kdns_usevc=%d\n", kdns_usevc);
+ }
+
+ if (opt->debug)
+ my_adns_initflags |= adns_if_debug;
+ if (opt->host)
+ {
+ char cfgtext[200];
+
+ snprintf (cfgtext, sizeof cfgtext, "nameserver %s\n", opt->host);
+ tmprc = adns_init_strcfg (&adns_ctx, my_adns_initflags, console,cfgtext);
+ }
+ else
+ tmprc = adns_init (&adns_ctx, my_adns_initflags, console);
+ if (tmprc)
+ {
+ fprintf (console, PGM": error initializing ADNS: %s\n",
+ strerror (errno));
+ goto leave;
+ }
+
+ if (opt->action == KS_GETNAME)
+ {
+ while ( fgets (line,MAX_LINE,input) )
+ {
+ if (line[0]=='\n' || !line[0] )
+ break;
+ line[strlen(line)-1] = 0; /* Trim the trailing LF. */
+
+ akey = xtrymalloc (sizeof *akey);
+ if (!akey)
+ {
+ fprintf (console,
+ PGM": out of memory while building key list\n");
+ ret = KEYSERVER_NO_MEMORY;
+ goto leave;
+ }
+ assert (sizeof (akey->str) > strlen(line));
+ strcpy (akey->str, line);
+ akey->next = NULL;
+ *keylist_tail = akey;
+ keylist_tail = &akey->next;
+ }
+ }
+ else
+ {
+ fprintf (console,
+ PGM": this keyserver type only supports "
+ "key retrieval by name\n");
+ goto leave;
+ }
+
+ /* Send the response */
+ fprintf (output, "VERSION %d\n", KEYSERVER_PROTO_VERSION);
+ fprintf (output, "PROGRAM %s\n\n", VERSION);
+
+ if (opt->verbose > 1)
+ {
+ if (opt->opaque)
+ fprintf (console, "User:\t\t%s\n", opt->opaque);
+ fprintf (console, "Command:\tGET\n");
+ }
+
+ for (akey = keylist; akey; akey = akey->next)
+ {
+ set_timeout (opt->timeout);
+ if ( get_key (adns_ctx, akey->str) )
+ failed++;
+ }
+ if (!failed)
+ ret = KEYSERVER_OK;
+
+
+ leave:
+ if (adns_ctx)
+ adns_finish (adns_ctx);
+ while (keylist)
+ {
+ akey = keylist->next;
+ xfree (keylist);
+ keylist = akey;
+ }
+ if (input != stdin)
+ fclose (input);
+ if (output != stdout)
+ fclose (output);
+ kdns_root = "";
+ kdns_at_repl = ".";
+ free_ks_options (opt);
+ return ret;
+}
diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c
new file mode 100644
index 0000000..bd85234
--- /dev/null
+++ b/keyserver/gpgkeys_ldap.c
@@ -0,0 +1,2379 @@
+/* gpgkeys_ldap.c - talk to a LDAP keyserver
+ * Copyright (C) 2001, 2002, 2004, 2005, 2006
+ * 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ *
+ * In addition, as a special exception, the Free Software Foundation
+ * gives permission to link the code of the keyserver helper tools:
+ * gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
+ * project's "OpenSSL" library (or with modified versions of it that
+ * use the same license as the "OpenSSL" library), and distribute the
+ * linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If
+ * you modify this file, you may extend this exception to your version
+ * of the file, but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <winldap.h>
+#else
+#ifdef NEED_LBER_H
+#include <lber.h>
+#endif
+/* For OpenLDAP, to enable the API that we're using. */
+#define LDAP_DEPRECATED 1
+#include <ldap.h>
+#endif
+
+#include "util.h"
+#include "keyserver.h"
+#include "ksutil.h"
+
+#ifdef __riscos__
+#include "util.h"
+#endif
+
+extern char *optarg;
+extern int optind;
+
+static int real_ldap=0;
+static char *basekeyspacedn=NULL;
+static char *pgpkeystr="pgpKey";
+static FILE *input=NULL,*output=NULL,*console=NULL;
+static LDAP *ldap=NULL;
+static struct ks_options *opt;
+
+#ifndef HAVE_TIMEGM
+time_t timegm(struct tm *tm);
+#endif
+
+static int
+ldap_err_to_gpg_err(int err)
+{
+ int ret;
+
+ switch(err)
+ {
+ case LDAP_ALREADY_EXISTS:
+ ret=KEYSERVER_KEY_EXISTS;
+ break;
+
+ case LDAP_SERVER_DOWN:
+ ret=KEYSERVER_UNREACHABLE;
+ break;
+
+ default:
+ ret=KEYSERVER_GENERAL_ERROR;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+ldap_to_gpg_err(LDAP *ld)
+{
+#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
+
+ int err;
+
+ if(ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&err)==0)
+ return ldap_err_to_gpg_err(err);
+ else
+ return KEYSERVER_GENERAL_ERROR;
+
+#elif defined(HAVE_LDAP_LD_ERRNO)
+
+ return ldap_err_to_gpg_err(ld->ld_errno);
+
+#else
+
+ /* We should never get here since the LDAP library should always
+ have either ldap_get_option or ld_errno, but just in case... */
+ return KEYSERVER_GENERAL_ERROR;
+
+#endif
+}
+
+static int
+key_in_keylist(const char *key,struct keylist *list)
+{
+ struct keylist *keyptr=list;
+
+ while(keyptr!=NULL)
+ {
+ if(strcasecmp(key,keyptr->str)==0)
+ return 1;
+
+ keyptr=keyptr->next;
+ }
+
+ return 0;
+}
+
+static int
+add_key_to_keylist(const char *key,struct keylist **list)
+{
+ struct keylist *keyptr=malloc(sizeof(struct keylist));
+
+ if(keyptr==NULL)
+ {
+ fprintf(console,"gpgkeys: out of memory when deduping "
+ "key list\n");
+ return KEYSERVER_NO_MEMORY;
+ }
+
+ strncpy(keyptr->str,key,MAX_LINE);
+ keyptr->str[MAX_LINE-1]='\0';
+ keyptr->next=*list;
+ *list=keyptr;
+
+ return 0;
+}
+
+static void
+free_keylist(struct keylist *list)
+{
+ while(list!=NULL)
+ {
+ struct keylist *keyptr=list;
+
+ list=keyptr->next;
+ free(keyptr);
+ }
+}
+
+static time_t
+ldap2epochtime(const char *timestr)
+{
+ struct tm pgptime;
+ time_t answer;
+
+ memset(&pgptime,0,sizeof(pgptime));
+
+ /* YYYYMMDDHHmmssZ */
+
+ sscanf(timestr,"%4d%2d%2d%2d%2d%2d",
+ &pgptime.tm_year,
+ &pgptime.tm_mon,
+ &pgptime.tm_mday,
+ &pgptime.tm_hour,
+ &pgptime.tm_min,
+ &pgptime.tm_sec);
+
+ pgptime.tm_year-=1900;
+ pgptime.tm_isdst=-1;
+ pgptime.tm_mon--;
+
+ /* mktime() takes the timezone into account, so we use timegm() */
+
+ answer=timegm(&pgptime);
+
+ return answer;
+}
+
+/* Caller must free */
+static char *
+epoch2ldaptime(time_t stamp)
+{
+ struct tm *ldaptime;
+ char buf[16];
+
+ ldaptime=gmtime(&stamp);
+
+ ldaptime->tm_year+=1900;
+ ldaptime->tm_mon++;
+
+ /* YYYYMMDDHHmmssZ */
+
+ sprintf(buf,"%04d%02d%02d%02d%02d%02dZ",
+ ldaptime->tm_year,
+ ldaptime->tm_mon,
+ ldaptime->tm_mday,
+ ldaptime->tm_hour,
+ ldaptime->tm_min,
+ ldaptime->tm_sec);
+
+ return strdup(buf);
+}
+
+/* Append two onto the end of one. Two is not freed, but its pointers
+ are now part of one. Make sure you don't free them both! */
+static int
+join_two_modlists(LDAPMod ***one,LDAPMod **two)
+{
+ int i,one_count=0,two_count=0;
+ LDAPMod **grow;
+
+ for(grow=*one;*grow;grow++)
+ one_count++;
+
+ for(grow=two;*grow;grow++)
+ two_count++;
+
+ grow=realloc(*one,sizeof(LDAPMod *)*(one_count+two_count+1));
+ if(!grow)
+ return 0;
+
+ for(i=0;i<two_count;i++)
+ grow[one_count+i]=two[i];
+
+ grow[one_count+i]=NULL;
+
+ *one=grow;
+
+ return 1;
+}
+
+/* Passing a NULL for value effectively deletes that attribute. This
+ doesn't mean "delete" in the sense of removing something from the
+ modlist, but "delete" in the LDAP sense of adding a modlist item
+ that specifies LDAP_MOD_REPLACE and a null attribute for the given
+ attribute. LDAP_MOD_DELETE doesn't work here as we don't know if
+ the attribute in question exists or not. */
+
+static int
+make_one_attr(LDAPMod ***modlist,char *attr,const char *value)
+{
+ LDAPMod **m;
+ int nummods=0;
+
+ /* Search modlist for the attribute we're playing with. */
+ for(m=*modlist;*m;m++)
+ {
+ if(strcasecmp((*m)->mod_type,attr)==0)
+ {
+ char **ptr=(*m)->mod_values;
+ int numvalues=0;
+
+ /* We have this attribute already, so when the REPLACE
+ happens, the server attributes will be replaced
+ anyway. */
+ if(!value)
+ return 1;
+
+ if(ptr)
+ for(ptr=(*m)->mod_values;*ptr;ptr++)
+ {
+ /* Duplicate value */
+ if(strcmp(*ptr,value)==0)
+ return 1;
+ numvalues++;
+ }
+
+ ptr=realloc((*m)->mod_values,sizeof(char *)*(numvalues+2));
+ if(!ptr)
+ return 0;
+
+ (*m)->mod_values=ptr;
+ ptr[numvalues]=strdup(value);
+ if(!ptr[numvalues])
+ return 0;
+
+ ptr[numvalues+1]=NULL;
+ break;
+ }
+
+ nummods++;
+ }
+
+ /* We didn't find the attr, so make one and add it to the end */
+ if(!*m)
+ {
+ LDAPMod **grow;
+
+ grow=realloc(*modlist,sizeof(LDAPMod *)*(nummods+2));
+ if(!grow)
+ return 0;
+
+ *modlist=grow;
+ grow[nummods]=malloc(sizeof(LDAPMod));
+ if(!grow[nummods])
+ return 0;
+ grow[nummods]->mod_op=LDAP_MOD_REPLACE;
+ grow[nummods]->mod_type=attr;
+ if(value)
+ {
+ grow[nummods]->mod_values=malloc(sizeof(char *)*2);
+ if(!grow[nummods]->mod_values)
+ {
+ grow[nummods]=NULL;
+ return 0;
+ }
+
+ /* Is this the right thing? Can a UTF8-encoded user ID have
+ embedded nulls? */
+ grow[nummods]->mod_values[0]=strdup(value);
+ if(!grow[nummods]->mod_values[0])
+ {
+ free(grow[nummods]->mod_values);
+ grow[nummods]=NULL;
+ return 0;
+ }
+
+ grow[nummods]->mod_values[1]=NULL;
+ }
+ else
+ grow[nummods]->mod_values=NULL;
+
+ grow[nummods+1]=NULL;
+ }
+
+ return 1;
+}
+
+static void
+build_attrs(LDAPMod ***modlist,char *line)
+{
+ char *record;
+ int i;
+
+ /* Remove trailing whitespace */
+ for(i=strlen(line);i>0;i--)
+ if(ascii_isspace(line[i-1]))
+ line[i-1]='\0';
+ else
+ break;
+
+ if((record=strsep(&line,":"))==NULL)
+ return;
+
+ if(ks_strcasecmp("pub",record)==0)
+ {
+ char *tok;
+ int disabled=0,revoked=0;
+
+ /* The long keyid */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(strlen(tok)==16)
+ {
+ make_one_attr(modlist,"pgpCertID",tok);
+ make_one_attr(modlist,"pgpKeyID",&tok[8]);
+ }
+ else
+ return;
+
+ /* The primary pubkey algo */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ switch(atoi(tok))
+ {
+ case 1:
+ make_one_attr(modlist,"pgpKeyType","RSA");
+ break;
+
+ case 17:
+ make_one_attr(modlist,"pgpKeyType","DSS/DH");
+ break;
+ }
+
+ /* Size of primary key */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(atoi(tok)>0)
+ {
+ char padded[6];
+ int val=atoi(tok);
+
+ /* We zero pad this on the left to make PGP happy. */
+
+ if(val<99999 && val>0)
+ {
+ sprintf(padded,"%05u",atoi(tok));
+ make_one_attr(modlist,"pgpKeySize",padded);
+ }
+ }
+
+ /* pk timestamp */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(atoi(tok)>0)
+ {
+ char *stamp=epoch2ldaptime(atoi(tok));
+ if(stamp)
+ {
+ make_one_attr(modlist,"pgpKeyCreateTime",stamp);
+ free(stamp);
+ }
+ }
+
+ /* pk expire */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(atoi(tok)>0)
+ {
+ char *stamp=epoch2ldaptime(atoi(tok));
+ if(stamp)
+ {
+ make_one_attr(modlist,"pgpKeyExpireTime",stamp);
+ free(stamp);
+ }
+ }
+
+ /* flags */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ while(*tok)
+ switch(*tok++)
+ {
+ case 'r':
+ case 'R':
+ revoked=1;
+ break;
+
+ case 'd':
+ case 'D':
+ disabled=1;
+ break;
+ }
+
+ /*
+ Note that we always create the pgpDisabled and pgpRevoked
+ attributes, regardless of whether the key is disabled/revoked
+ or not. This is because a very common search is like
+ "(&(pgpUserID=*isabella*)(pgpDisabled=0))"
+ */
+
+ make_one_attr(modlist,"pgpDisabled",disabled?"1":"0");
+ make_one_attr(modlist,"pgpRevoked",revoked?"1":"0");
+ }
+ else if(ks_strcasecmp("sub",record)==0)
+ {
+ char *tok;
+
+ /* The long keyid */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(strlen(tok)==16)
+ make_one_attr(modlist,"pgpSubKeyID",tok);
+ else
+ return;
+
+ /* The subkey algo */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ /* Size of subkey */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(atoi(tok)>0)
+ {
+ char padded[6];
+ int val=atoi(tok);
+
+ /* We zero pad this on the left to make PGP happy. */
+
+ if(val<99999 && val>0)
+ {
+ sprintf(padded,"%05u",atoi(tok));
+ make_one_attr(modlist,"pgpKeySize",padded);
+ }
+ }
+
+ /* Ignore the rest of the items for subkeys since the LDAP
+ schema doesn't store them. */
+ }
+ else if(ks_strcasecmp("uid",record)==0)
+ {
+ char *userid,*tok;
+
+ /* The user ID string */
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(strlen(tok)==0)
+ return;
+
+ userid=tok;
+
+ /* By definition, de-%-encoding is always smaller than the
+ original string so we can decode in place. */
+
+ i=0;
+
+ while(*tok)
+ if(tok[0]=='%' && tok[1] && tok[2])
+ {
+ int c;
+
+ userid[i] = (c=hextobyte(&tok[1])) == -1 ? '?' : c;
+ i++;
+ tok+=3;
+ }
+ else
+ userid[i++]=*tok++;
+
+ userid[i]='\0';
+
+ /* We don't care about the other info provided in the uid: line
+ since the LDAP schema doesn't need it. */
+
+ make_one_attr(modlist,"pgpUserID",userid);
+ }
+ else if(ks_strcasecmp("sig",record)==0)
+ {
+ char *tok;
+
+ if((tok=strsep(&line,":"))==NULL)
+ return;
+
+ if(strlen(tok)==16)
+ make_one_attr(modlist,"pgpSignerID",tok);
+ }
+}
+
+static void
+free_mod_values(LDAPMod *mod)
+{
+ char **ptr;
+
+ if(!mod->mod_values)
+ return;
+
+ for(ptr=mod->mod_values;*ptr;ptr++)
+ free(*ptr);
+
+ free(mod->mod_values);
+}
+
+static int
+send_key(int *r_eof)
+{
+ int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
+ char *dn=NULL,line[MAX_LINE],*key=NULL;
+ char keyid[17],state[6];
+ LDAPMod **modlist,**addlist,**ml;
+
+ modlist=malloc(sizeof(LDAPMod *));
+ if(!modlist)
+ {
+ fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ *modlist=NULL;
+
+ addlist=malloc(sizeof(LDAPMod *));
+ if(!addlist)
+ {
+ fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ *addlist=NULL;
+
+ /* Start by nulling out all attributes. We try and do a modify
+ operation first, so this ensures that we don't leave old
+ attributes lying around. */
+ make_one_attr(&modlist,"pgpDisabled",NULL);
+ make_one_attr(&modlist,"pgpKeyID",NULL);
+ make_one_attr(&modlist,"pgpKeyType",NULL);
+ make_one_attr(&modlist,"pgpUserID",NULL);
+ make_one_attr(&modlist,"pgpKeyCreateTime",NULL);
+ make_one_attr(&modlist,"pgpSignerID",NULL);
+ make_one_attr(&modlist,"pgpRevoked",NULL);
+ make_one_attr(&modlist,"pgpSubKeyID",NULL);
+ make_one_attr(&modlist,"pgpKeySize",NULL);
+ make_one_attr(&modlist,"pgpKeyExpireTime",NULL);
+ make_one_attr(&modlist,"pgpCertID",NULL);
+
+ /* Assemble the INFO stuff into LDAP attributes */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ if(sscanf(line,"INFO%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
+ && strcmp(state,"BEGIN")==0)
+ {
+ begin=1;
+ break;
+ }
+
+ if(!begin)
+ {
+ /* i.e. eof before the INFO BEGIN was found. This isn't an
+ error. */
+ *r_eof=1;
+ ret=KEYSERVER_OK;
+ goto fail;
+ }
+
+ if(strlen(keyid)!=16)
+ {
+ *r_eof=1;
+ ret=KEYSERVER_KEY_INCOMPLETE;
+ goto fail;
+ }
+
+ dn=malloc(strlen("pgpCertID=")+16+1+strlen(basekeyspacedn)+1);
+ if(dn==NULL)
+ {
+ fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ sprintf(dn,"pgpCertID=%s,%s",keyid,basekeyspacedn);
+
+ key=malloc(1);
+ if(!key)
+ {
+ fprintf(console,"gpgkeys: unable to allocate memory for key\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ key[0]='\0';
+
+ /* Now parse each line until we see the END */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ if(sscanf(line,"INFO%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
+ && strcmp(state,"END")==0)
+ {
+ end=1;
+ break;
+ }
+ else
+ build_attrs(&addlist,line);
+
+ if(!end)
+ {
+ fprintf(console,"gpgkeys: no INFO %s END found\n",keyid);
+ *r_eof=1;
+ ret=KEYSERVER_KEY_INCOMPLETE;
+ goto fail;
+ }
+
+ begin=end=0;
+
+ /* Read and throw away stdin until we see the BEGIN */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
+ && strcmp(state,"BEGIN")==0)
+ {
+ begin=1;
+ break;
+ }
+
+ if(!begin)
+ {
+ /* i.e. eof before the KEY BEGIN was found. This isn't an
+ error. */
+ *r_eof=1;
+ ret=KEYSERVER_OK;
+ goto fail;
+ }
+
+ /* Now slurp up everything until we see the END */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
+ && strcmp(state,"END")==0)
+ {
+ end=1;
+ break;
+ }
+ else
+ {
+ char *tempkey;
+ keysize+=strlen(line);
+ tempkey=realloc(key,keysize);
+ if(tempkey==NULL)
+ {
+ fprintf(console,"gpgkeys: unable to reallocate for key\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+ else
+ key=tempkey;
+
+ strcat(key,line);
+ }
+
+ if(!end)
+ {
+ fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
+ *r_eof=1;
+ ret=KEYSERVER_KEY_INCOMPLETE;
+ goto fail;
+ }
+
+ make_one_attr(&addlist,"objectClass","pgpKeyInfo");
+ make_one_attr(&addlist,"pgpKey",key);
+
+ /* Now append addlist onto modlist */
+ if(!join_two_modlists(&modlist,addlist))
+ {
+ fprintf(console,"gpgkeys: unable to merge LDAP modification lists\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ /* Going on the assumption that modify operations are more frequent
+ than adds, we try a modify first. If it's not there, we just
+ turn around and send an add command for the same key. Otherwise,
+ the modify brings the server copy into compliance with our copy.
+ Note that unlike the LDAP keyserver (and really, any other
+ keyserver) this does NOT merge signatures, but replaces the whole
+ key. This should make some people very happy. */
+
+ err=ldap_modify_s(ldap,dn,modlist);
+ if(err==LDAP_NO_SUCH_OBJECT)
+ err=ldap_add_s(ldap,dn,addlist);
+
+ if(err!=LDAP_SUCCESS)
+ {
+ fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
+ keyid,ldap_err2string(err));
+ ret=ldap_err_to_gpg_err(err);
+ goto fail;
+ }
+
+ ret=KEYSERVER_OK;
+
+ fail:
+ if (modlist)
+ {
+ /* Unwind and free the whole modlist structure */
+ for(ml=modlist;*ml;ml++)
+ {
+ free_mod_values(*ml);
+ free(*ml);
+ }
+ free(modlist);
+ }
+ free(addlist);
+ free(dn);
+ free(key);
+
+ if(ret!=0 && begin)
+ fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
+
+ return ret;
+}
+
+static int
+send_key_keyserver(int *r_eof)
+{
+ int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR;
+ char *dn=NULL,line[MAX_LINE],*key[2]={NULL,NULL};
+ char keyid[17],state[6];
+ LDAPMod mod, *attrs[2];
+
+ memset(&mod,0,sizeof(mod));
+ mod.mod_op=LDAP_MOD_ADD;
+ mod.mod_type=pgpkeystr;
+ mod.mod_values=key;
+ attrs[0]=&mod;
+ attrs[1]=NULL;
+
+ dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1);
+ if(dn==NULL)
+ {
+ fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ strcpy(dn,"pgpCertid=virtual,");
+ strcat(dn,basekeyspacedn);
+
+ key[0]=malloc(1);
+ if(key[0]==NULL)
+ {
+ fprintf(console,"gpgkeys: unable to allocate memory for key\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ key[0][0]='\0';
+
+ /* Read and throw away stdin until we see the BEGIN */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2
+ && strcmp(state,"BEGIN")==0)
+ {
+ begin=1;
+ break;
+ }
+
+ if(!begin)
+ {
+ /* i.e. eof before the KEY BEGIN was found. This isn't an
+ error. */
+ *r_eof=1;
+ ret=KEYSERVER_OK;
+ goto fail;
+ }
+
+ /* Now slurp up everything until we see the END */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2
+ && strcmp(state,"END")==0)
+ {
+ end=1;
+ break;
+ }
+ else
+ {
+ keysize+=strlen(line);
+ key[0]=realloc(key[0],keysize);
+ if(key[0]==NULL)
+ {
+ fprintf(console,"gpgkeys: unable to reallocate for key\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ strcat(key[0],line);
+ }
+
+ if(!end)
+ {
+ fprintf(console,"gpgkeys: no KEY %s END found\n",keyid);
+ *r_eof=1;
+ ret=KEYSERVER_KEY_INCOMPLETE;
+ goto fail;
+ }
+
+ err=ldap_add_s(ldap,dn,attrs);
+ if(err!=LDAP_SUCCESS)
+ {
+ fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n",
+ keyid,ldap_err2string(err));
+ ret=ldap_err_to_gpg_err(err);
+ goto fail;
+ }
+
+ ret=KEYSERVER_OK;
+
+ fail:
+
+ free(key[0]);
+ free(dn);
+
+ if(ret!=0 && begin)
+ fprintf(output,"KEY %s FAILED %d\n",keyid,ret);
+
+ /* Not a fatal error */
+ if(ret==KEYSERVER_KEY_EXISTS)
+ ret=KEYSERVER_OK;
+
+ return ret;
+}
+
+static void
+build_info(const char *certid,LDAPMessage *each)
+{
+ char **vals;
+
+ fprintf(output,"INFO %s BEGIN\n",certid);
+
+ fprintf(output,"pub:%s:",certid);
+
+ vals=ldap_get_values(ldap,each,"pgpkeytype");
+ if(vals!=NULL)
+ {
+ if(strcmp(vals[0],"RSA")==0)
+ fprintf(output,"1");
+ else if(strcmp(vals[0],"DSS/DH")==0)
+ fprintf(output,"17");
+ ldap_value_free(vals);
+ }
+
+ fprintf(output,":");
+
+ vals=ldap_get_values(ldap,each,"pgpkeysize");
+ if(vals!=NULL)
+ {
+ if(atoi(vals[0])>0)
+ fprintf(output,"%d",atoi(vals[0]));
+ ldap_value_free(vals);
+ }
+
+ fprintf(output,":");
+
+ vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
+ if(vals!=NULL)
+ {
+ if(strlen(vals[0])==15)
+ fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
+ ldap_value_free(vals);
+ }
+
+ fprintf(output,":");
+
+ vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
+ if(vals!=NULL)
+ {
+ if(strlen(vals[0])==15)
+ fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0]));
+ ldap_value_free(vals);
+ }
+
+ fprintf(output,":");
+
+ vals=ldap_get_values(ldap,each,"pgprevoked");
+ if(vals!=NULL)
+ {
+ if(atoi(vals[0])==1)
+ fprintf(output,"r");
+ ldap_value_free(vals);
+ }
+
+ fprintf(output,"\n");
+
+ vals=ldap_get_values(ldap,each,"pgpuserid");
+ if(vals!=NULL)
+ {
+ int i;
+
+ for(i=0;vals[i];i++)
+ fprintf(output,"uid:%s\n",vals[i]);
+ ldap_value_free(vals);
+ }
+
+ fprintf(output,"INFO %s END\n",certid);
+}
+
+/* Note that key-not-found is not a fatal error */
+static int
+get_key(char *getkey)
+{
+ LDAPMessage *res,*each;
+ int ret=KEYSERVER_INTERNAL_ERROR,err,count;
+ struct keylist *dupelist=NULL;
+ char search[62];
+ /* This ordering is significant - specifically, "pgpcertid" needs to
+ be the second item in the list, since everything after it may be
+ discarded if the user isn't in verbose mode. */
+ char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
+ "pgpdisabled","pgpkeycreatetime","modifytimestamp",
+ "pgpkeysize","pgpkeytype",NULL};
+ attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
+ array initializers. */
+
+ /* Build the search string */
+
+ /* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3
+ or v4 short key id */
+
+ if(strncmp(getkey,"0x",2)==0)
+ getkey+=2;
+
+ if(strlen(getkey)==32)
+ {
+ fprintf(console,
+ "gpgkeys: LDAP keyservers do not support v3 fingerprints\n");
+ fprintf(output,"KEY 0x%s BEGIN\n",getkey);
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED);
+ return KEYSERVER_NOT_SUPPORTED;
+ }
+
+ if(strlen(getkey)>16)
+ {
+ char *offset=&getkey[strlen(getkey)-16];
+
+ /* fingerprint. Take the last 16 characters and treat it like a
+ long key id */
+
+ if(opt->flags.include_subkeys)
+ sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
+ offset,offset);
+ else
+ sprintf(search,"(pgpcertid=%.16s)",offset);
+ }
+ else if(strlen(getkey)>8)
+ {
+ /* long key id */
+
+ if(opt->flags.include_subkeys)
+ sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))",
+ getkey,getkey);
+ else
+ sprintf(search,"(pgpcertid=%.16s)",getkey);
+ }
+ else
+ {
+ /* short key id */
+
+ sprintf(search,"(pgpkeyid=%.8s)",getkey);
+ }
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
+
+ if(!opt->verbose)
+ attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
+
+ err=ldap_search_s(ldap,basekeyspacedn,
+ LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
+ if(err!=0)
+ {
+ int errtag=ldap_err_to_gpg_err(err);
+
+ fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
+ fprintf(output,"KEY 0x%s BEGIN\n",getkey);
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
+ return errtag;
+ }
+
+ count=ldap_count_entries(ldap,res);
+ if(count<1)
+ {
+ fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
+ fprintf(output,"KEY 0x%s BEGIN\n",getkey);
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
+ }
+ else
+ {
+ /* There may be more than one unique result for a given keyID,
+ so we should fetch them all (test this by fetching short key
+ id 0xDEADBEEF). */
+
+ each=ldap_first_entry(ldap,res);
+ while(each!=NULL)
+ {
+ char **vals,**certid;
+
+ /* Use the long keyid to remove duplicates. The LDAP server
+ returns the same keyid more than once if there are
+ multiple user IDs on the key. Note that this does NOT
+ mean that a keyid that exists multiple times on the
+ keyserver will not be fetched. It means that each KEY,
+ no matter how many user IDs share its keyid, will be
+ fetched only once. If a keyid that belongs to more than
+ one key is fetched, the server quite properly responds
+ with all matching keys. -ds */
+
+ certid=ldap_get_values(ldap,each,"pgpcertid");
+ if(certid!=NULL)
+ {
+ if(!key_in_keylist(certid[0],dupelist))
+ {
+ /* it's not a duplicate, so add it */
+
+ int rc=add_key_to_keylist(certid[0],&dupelist);
+ if(rc)
+ {
+ ret=rc;
+ goto fail;
+ }
+
+ build_info(certid[0],each);
+
+ fprintf(output,"KEY 0x%s BEGIN\n",getkey);
+
+ vals=ldap_get_values(ldap,each,pgpkeystr);
+ if(vals==NULL)
+ {
+ int errtag=ldap_to_gpg_err(ldap);
+
+ fprintf(console,"gpgkeys: unable to retrieve key %s "
+ "from keyserver\n",getkey);
+ fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag);
+ }
+ else
+ {
+ print_nocr(output,vals[0]);
+ fprintf(output,"\nKEY 0x%s END\n",getkey);
+
+ ldap_value_free(vals);
+ }
+ }
+
+ ldap_value_free(certid);
+ }
+
+ each=ldap_next_entry(ldap,each);
+ }
+ }
+
+ ret=KEYSERVER_OK;
+
+ fail:
+ ldap_msgfree(res);
+ free_keylist(dupelist);
+
+ return ret;
+}
+
+#define LDAP_ESCAPE_CHARS "*()\\"
+
+/* Append string to buffer in a LDAP-quoted way */
+static void
+ldap_quote(char *buffer,const char *string)
+{
+ /* Find the end of buffer */
+ buffer+=strlen(buffer);
+
+ for(;*string;string++)
+ {
+ if(strchr(LDAP_ESCAPE_CHARS,*string))
+ {
+ sprintf(buffer,"\\%02X",*string);
+ buffer+=3;
+ }
+ else
+ *buffer++=*string;
+ }
+
+ *buffer='\0';
+}
+
+/* Note that key-not-found is not a fatal error */
+static int
+get_name(char *getkey)
+{
+ LDAPMessage *res,*each;
+ int ret=KEYSERVER_INTERNAL_ERROR,err,count;
+ /* The maximum size of the search, including the optional stuff and
+ the trailing \0 */
+ char search[2+12+(MAX_LINE*3)+2+15+14+1+1+20];
+ /* This ordering is significant - specifically, "pgpcertid" needs to
+ be the second item in the list, since everything after it may be
+ discarded if the user isn't in verbose mode. */
+ char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked",
+ "pgpdisabled","pgpkeycreatetime","modifytimestamp",
+ "pgpkeysize","pgpkeytype",NULL};
+ attrs[0]=pgpkeystr; /* Some compilers don't like using variables as
+ array initializers. */
+
+ /* Build the search string */
+
+ search[0]='\0';
+
+ if(!opt->flags.include_disabled || !opt->flags.include_revoked)
+ strcat(search,"(&");
+
+ strcat(search,"(pgpUserID=*");
+ ldap_quote(search,getkey);
+ strcat(search,"*)");
+
+ if(!opt->flags.include_disabled)
+ strcat(search,"(pgpDisabled=0)");
+
+ if(!opt->flags.include_revoked)
+ strcat(search,"(pgpRevoked=0)");
+
+ if(!opt->flags.include_disabled || !opt->flags.include_revoked)
+ strcat(search,")");
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search);
+
+ if(!opt->verbose)
+ attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */
+
+ err=ldap_search_s(ldap,basekeyspacedn,
+ LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
+ if(err!=0)
+ {
+ int errtag=ldap_err_to_gpg_err(err);
+
+ fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
+ fprintf(output,"NAME %s BEGIN\n",getkey);
+ fprintf(output,"NAME %s FAILED %d\n",getkey,errtag);
+ return errtag;
+ }
+
+ count=ldap_count_entries(ldap,res);
+ if(count<1)
+ {
+ fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
+ fprintf(output,"NAME %s BEGIN\n",getkey);
+ fprintf(output,"NAME %s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
+ }
+ else
+ {
+ /* There may be more than one result, but we return them all. */
+
+ each=ldap_first_entry(ldap,res);
+ while(each!=NULL)
+ {
+ char **vals,**certid;
+
+ certid=ldap_get_values(ldap,each,"pgpcertid");
+ if(certid!=NULL)
+ {
+ build_info(certid[0],each);
+
+ fprintf(output,"NAME %s BEGIN\n",getkey);
+
+ vals=ldap_get_values(ldap,each,pgpkeystr);
+ if(vals==NULL)
+ {
+ int errtag=ldap_to_gpg_err(ldap);
+
+ fprintf(console,"gpgkeys: unable to retrieve key %s "
+ "from keyserver\n",getkey);
+ fprintf(output,"NAME %s FAILED %d\n",getkey,errtag);
+ }
+ else
+ {
+ print_nocr(output,vals[0]);
+ fprintf(output,"\nNAME %s END\n",getkey);
+
+ ldap_value_free(vals);
+ }
+
+ ldap_value_free(certid);
+ }
+
+ each=ldap_next_entry(ldap,each);
+ }
+ }
+
+ ret=KEYSERVER_OK;
+
+ ldap_msgfree(res);
+
+ return ret;
+}
+
+static void
+printquoted(FILE *stream,char *string,char delim)
+{
+ while(*string)
+ {
+ if(*string==delim || *string=='%')
+ fprintf(stream,"%%%02x",*string);
+ else
+ fputc(*string,stream);
+
+ string++;
+ }
+}
+
+/* Returns 0 on success and -1 on error. Note that key-not-found is
+ not an error! */
+static int
+search_key(const char *searchkey)
+{
+ char **vals,*search;
+ LDAPMessage *res,*each;
+ int err,count=0;
+ struct keylist *dupelist=NULL;
+ /* The maximum size of the search, including the optional stuff and
+ the trailing \0 */
+ char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled",
+ "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp",
+ "pgpkeysize","pgpkeytype",NULL};
+ enum ks_search_type search_type;
+
+ search=malloc(2+1+9+1+3+strlen(searchkey)+3+1+15+14+1+1+20);
+ if(!search)
+ {
+ fprintf(console,"gpgkeys: out of memory when building search list\n");
+ fprintf(output,"SEARCH %s FAILED %d\n",searchkey,KEYSERVER_NO_MEMORY);
+ return KEYSERVER_NO_MEMORY;
+ }
+
+ fprintf(output,"SEARCH %s BEGIN\n",searchkey);
+
+ search_type=classify_ks_search(&searchkey);
+
+ if(opt->debug)
+ fprintf(console,"search type is %d, and key is \"%s\"\n",
+ search_type,searchkey);
+
+ /* Build the search string */
+
+ search[0]='\0';
+
+ if(!opt->flags.include_disabled || !opt->flags.include_revoked)
+ strcat(search,"(&");
+
+ strcat(search,"(");
+
+ switch(search_type)
+ {
+ case KS_SEARCH_KEYID_SHORT:
+ strcat(search,"pgpKeyID");
+ break;
+
+ case KS_SEARCH_KEYID_LONG:
+ strcat(search,"pgpCertID");
+ break;
+
+ default:
+ strcat(search,"pgpUserID");
+ break;
+ }
+
+ strcat(search,"=");
+
+ switch(search_type)
+ {
+ case KS_SEARCH_SUBSTR:
+ strcat(search,"*");
+ break;
+
+ case KS_SEARCH_MAIL:
+ strcat(search,"*<");
+ break;
+
+ case KS_SEARCH_MAILSUB:
+ strcat(search,"*<*");
+ break;
+
+ case KS_SEARCH_EXACT:
+ case KS_SEARCH_KEYID_LONG:
+ case KS_SEARCH_KEYID_SHORT:
+ break;
+ }
+
+ strcat(search,searchkey);
+
+ switch(search_type)
+ {
+ case KS_SEARCH_SUBSTR:
+ strcat(search,"*");
+ break;
+
+ case KS_SEARCH_MAIL:
+ strcat(search,">*");
+ break;
+
+ case KS_SEARCH_MAILSUB:
+ strcat(search,"*>*");
+ break;
+
+ case KS_SEARCH_EXACT:
+ case KS_SEARCH_KEYID_LONG:
+ case KS_SEARCH_KEYID_SHORT:
+ break;
+ }
+
+ strcat(search,")");
+
+ if(!opt->flags.include_disabled)
+ strcat(search,"(pgpDisabled=0)");
+
+ if(!opt->flags.include_revoked)
+ strcat(search,"(pgpRevoked=0)");
+
+ if(!opt->flags.include_disabled || !opt->flags.include_revoked)
+ strcat(search,")");
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: LDAP search for: %s\n",search);
+
+ err=ldap_search_s(ldap,basekeyspacedn,
+ LDAP_SCOPE_SUBTREE,search,attrs,0,&res);
+ free(search);
+ if(err!=LDAP_SUCCESS && err!=LDAP_SIZELIMIT_EXCEEDED)
+ {
+ int errtag=ldap_err_to_gpg_err(err);
+
+ fprintf(output,"SEARCH %s FAILED %d\n",searchkey,errtag);
+ fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err));
+ return errtag;
+ }
+
+ /* The LDAP server doesn't return a real count of unique keys, so we
+ can't use ldap_count_entries here. */
+ each=ldap_first_entry(ldap,res);
+ while(each!=NULL)
+ {
+ char **certid=ldap_get_values(ldap,each,"pgpcertid");
+
+ if(certid!=NULL)
+ {
+ if(!key_in_keylist(certid[0],dupelist))
+ {
+ int rc=add_key_to_keylist(certid[0],&dupelist);
+ if(rc!=0)
+ {
+ fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
+ free_keylist(dupelist);
+ return rc;
+ }
+
+ count++;
+ }
+ }
+
+ each=ldap_next_entry(ldap,each);
+ }
+
+ if(err==LDAP_SIZELIMIT_EXCEEDED)
+ {
+ if(count==1)
+ fprintf(console,"gpgkeys: search results exceeded server limit."
+ " First %d result shown.\n",count);
+ else
+ fprintf(console,"gpgkeys: search results exceeded server limit."
+ " First %d results shown.\n",count);
+ }
+
+ free_keylist(dupelist);
+ dupelist=NULL;
+
+ if(count<1)
+ fprintf(output,"info:1:0\n");
+ else
+ {
+ fprintf(output,"info:1:%d\n",count);
+
+ each=ldap_first_entry(ldap,res);
+ while(each!=NULL)
+ {
+ char **certid;
+
+ certid=ldap_get_values(ldap,each,"pgpcertid");
+ if(certid!=NULL)
+ {
+ LDAPMessage *uids;
+
+ /* Have we seen this certid before? */
+ if(!key_in_keylist(certid[0],dupelist))
+ {
+ int rc=add_key_to_keylist(certid[0],&dupelist);
+ if(rc)
+ {
+ fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc);
+ free_keylist(dupelist);
+ ldap_value_free(certid);
+ ldap_msgfree(res);
+ return rc;
+ }
+
+ fprintf(output,"pub:%s:",certid[0]);
+
+ vals=ldap_get_values(ldap,each,"pgpkeytype");
+ if(vals!=NULL)
+ {
+ /* The LDAP server doesn't exactly handle this
+ well. */
+ if(strcasecmp(vals[0],"RSA")==0)
+ fprintf(output,"1");
+ else if(strcasecmp(vals[0],"DSS/DH")==0)
+ fprintf(output,"17");
+ ldap_value_free(vals);
+ }
+
+ fputc(':',output);
+
+ vals=ldap_get_values(ldap,each,"pgpkeysize");
+ if(vals!=NULL)
+ {
+ /* Not sure why, but some keys are listed with a
+ key size of 0. Treat that like an
+ unknown. */
+ if(atoi(vals[0])>0)
+ fprintf(output,"%d",atoi(vals[0]));
+ ldap_value_free(vals);
+ }
+
+ fputc(':',output);
+
+ /* YYYYMMDDHHmmssZ */
+
+ vals=ldap_get_values(ldap,each,"pgpkeycreatetime");
+ if(vals!=NULL && strlen(vals[0])==15)
+ {
+ fprintf(output,"%u",
+ (unsigned int)ldap2epochtime(vals[0]));
+ ldap_value_free(vals);
+ }
+
+ fputc(':',output);
+
+ vals=ldap_get_values(ldap,each,"pgpkeyexpiretime");
+ if(vals!=NULL && strlen(vals[0])==15)
+ {
+ fprintf(output,"%u",
+ (unsigned int)ldap2epochtime(vals[0]));
+ ldap_value_free(vals);
+ }
+
+ fputc(':',output);
+
+ vals=ldap_get_values(ldap,each,"pgprevoked");
+ if(vals!=NULL)
+ {
+ if(atoi(vals[0])==1)
+ fprintf(output,"r");
+ ldap_value_free(vals);
+ }
+
+ vals=ldap_get_values(ldap,each,"pgpdisabled");
+ if(vals!=NULL)
+ {
+ if(atoi(vals[0])==1)
+ fprintf(output,"d");
+ ldap_value_free(vals);
+ }
+
+#if 0
+ /* This is not yet specified in the keyserver
+ protocol, but may be someday. */
+ fputc(':',output);
+
+ vals=ldap_get_values(ldap,each,"modifytimestamp");
+ if(vals!=NULL && strlen(vals[0])==15)
+ {
+ fprintf(output,"%u",
+ (unsigned int)ldap2epochtime(vals[0]));
+ ldap_value_free(vals);
+ }
+#endif
+
+ fprintf(output,"\n");
+
+ /* Now print all the uids that have this certid */
+ uids=ldap_first_entry(ldap,res);
+ while(uids!=NULL)
+ {
+ vals=ldap_get_values(ldap,uids,"pgpcertid");
+ if(vals!=NULL)
+ {
+ if(strcasecmp(certid[0],vals[0])==0)
+ {
+ char **uidvals;
+
+ fprintf(output,"uid:");
+
+ uidvals=ldap_get_values(ldap,uids,"pgpuserid");
+ if(uidvals!=NULL)
+ {
+ /* Need to escape any colons */
+ printquoted(output,uidvals[0],':');
+ ldap_value_free(uidvals);
+ }
+
+ fprintf(output,"\n");
+ }
+
+ ldap_value_free(vals);
+ }
+
+ uids=ldap_next_entry(ldap,uids);
+ }
+ }
+
+ ldap_value_free(certid);
+ }
+
+ each=ldap_next_entry(ldap,each);
+ }
+ }
+
+ ldap_msgfree(res);
+ free_keylist(dupelist);
+
+ fprintf(output,"SEARCH %s END\n",searchkey);
+
+ return KEYSERVER_OK;
+}
+
+static void
+fail_all(struct keylist *keylist,int err)
+{
+ if(!keylist)
+ return;
+
+ if(opt->action==KS_SEARCH)
+ {
+ fprintf(output,"SEARCH ");
+ while(keylist)
+ {
+ fprintf(output,"%s ",keylist->str);
+ keylist=keylist->next;
+ }
+ fprintf(output,"FAILED %d\n",err);
+ }
+ else
+ while(keylist)
+ {
+ fprintf(output,"KEY %s FAILED %d\n",keylist->str,err);
+ keylist=keylist->next;
+ }
+}
+
+static int
+find_basekeyspacedn(void)
+{
+ int err,i;
+ char *attr[]={"namingContexts",NULL,NULL,NULL};
+ LDAPMessage *res;
+ char **context;
+
+ /* Look for namingContexts */
+ err=ldap_search_s(ldap,"",LDAP_SCOPE_BASE,"(objectClass=*)",attr,0,&res);
+ if(err==LDAP_SUCCESS)
+ {
+ context=ldap_get_values(ldap,res,"namingContexts");
+ if(context)
+ {
+ attr[0]="pgpBaseKeySpaceDN";
+ attr[1]="pgpVersion";
+ attr[2]="pgpSoftware";
+
+ real_ldap=1;
+
+ /* We found some, so try each namingContext as the search base
+ and look for pgpBaseKeySpaceDN. Because we found this, we
+ know we're talking to a regular-ish LDAP server and not a
+ LDAP keyserver. */
+
+ for(i=0;context[i] && !basekeyspacedn;i++)
+ {
+ char **vals;
+ LDAPMessage *si_res;
+ char *object;
+
+ object=malloc(17+strlen(context[i])+1);
+ if(!object)
+ return -1;
+
+ strcpy(object,"cn=pgpServerInfo,");
+ strcat(object,context[i]);
+
+ err=ldap_search_s(ldap,object,LDAP_SCOPE_BASE,
+ "(objectClass=*)",attr,0,&si_res);
+ free(object);
+
+ if(err==LDAP_NO_SUCH_OBJECT)
+ continue;
+ else if(err!=LDAP_SUCCESS)
+ return err;
+
+ vals=ldap_get_values(ldap,si_res,"pgpBaseKeySpaceDN");
+ if(vals)
+ {
+ basekeyspacedn=strdup(vals[0]);
+ ldap_value_free(vals);
+ }
+
+ if(opt->verbose>1)
+ {
+ vals=ldap_get_values(ldap,si_res,"pgpSoftware");
+ if(vals)
+ {
+ fprintf(console,"Server: \t%s\n",vals[0]);
+ ldap_value_free(vals);
+ }
+
+ vals=ldap_get_values(ldap,si_res,"pgpVersion");
+ if(vals)
+ {
+ fprintf(console,"Version:\t%s\n",vals[0]);
+ ldap_value_free(vals);
+ }
+ }
+
+ ldap_msgfree(si_res);
+ }
+
+ ldap_value_free(context);
+ }
+
+ ldap_msgfree(res);
+ }
+ else
+ {
+ /* We don't have an answer yet, which means the server might be
+ a LDAP keyserver. */
+ char **vals;
+ LDAPMessage *si_res;
+
+ attr[0]="pgpBaseKeySpaceDN";
+ attr[1]="version";
+ attr[2]="software";
+
+ err=ldap_search_s(ldap,"cn=pgpServerInfo",LDAP_SCOPE_BASE,
+ "(objectClass=*)",attr,0,&si_res);
+ if(err!=LDAP_SUCCESS)
+ return err;
+
+ /* For the LDAP keyserver, this is always "OU=ACTIVE,O=PGP
+ KEYSPACE,C=US", but it might not be in the future. */
+
+ vals=ldap_get_values(ldap,si_res,"baseKeySpaceDN");
+ if(vals)
+ {
+ basekeyspacedn=strdup(vals[0]);
+ ldap_value_free(vals);
+ }
+
+ if(opt->verbose>1)
+ {
+ vals=ldap_get_values(ldap,si_res,"software");
+ if(vals)
+ {
+ fprintf(console,"Server: \t%s\n",vals[0]);
+ ldap_value_free(vals);
+ }
+ }
+
+ vals=ldap_get_values(ldap,si_res,"version");
+ if(vals)
+ {
+ if(opt->verbose>1)
+ fprintf(console,"Version:\t%s\n",vals[0]);
+
+ /* If the version is high enough, use the new pgpKeyV2
+ attribute. This design if iffy at best, but it matches how
+ PGP does it. I figure the NAI folks assumed that there would
+ never be a LDAP keyserver vendor with a different numbering
+ scheme. */
+ if(atoi(vals[0])>1)
+ pgpkeystr="pgpKeyV2";
+
+ ldap_value_free(vals);
+ }
+
+ ldap_msgfree(si_res);
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static void
+show_help (FILE *fp)
+{
+ fprintf (fp,"-h, --help\thelp\n");
+ fprintf (fp,"-V\t\tmachine readable version\n");
+ fprintf (fp,"--version\thuman readable version\n");
+ fprintf (fp,"-o\t\toutput to this file\n");
+}
+
+int
+main(int argc,char *argv[])
+{
+ int port=0,arg,err,ret=KEYSERVER_INTERNAL_ERROR;
+ char line[MAX_LINE],*binddn=NULL,*bindpw=NULL;
+ int failed=0,use_ssl=0,use_tls=0,bound=0;
+ struct keylist *keylist=NULL,*keyptr=NULL;
+
+ console=stderr;
+
+ /* Kludge to implement standard GNU options. */
+ if (argc > 1 && !strcmp (argv[1], "--version"))
+ {
+ fputs ("gpgkeys_ldap (GnuPG) " VERSION"\n", stdout);
+ return 0;
+ }
+ else if (argc > 1 && !strcmp (argv[1], "--help"))
+ {
+ show_help (stdout);
+ return 0;
+ }
+
+ while((arg=getopt(argc,argv,"hVo:"))!=-1)
+ switch(arg)
+ {
+ default:
+ case 'h':
+ show_help (console);
+ return KEYSERVER_OK;
+
+ case 'V':
+ fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION);
+ return KEYSERVER_OK;
+
+ case 'o':
+ output=fopen(optarg,"w");
+ if(output==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open output file `%s': %s\n",
+ optarg,strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ break;
+ }
+
+ if(argc>optind)
+ {
+ input=fopen(argv[optind],"r");
+ if(input==NULL)
+ {
+ fprintf(console,"gpgkeys: Cannot open input file `%s': %s\n",
+ argv[optind],strerror(errno));
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ }
+
+ if(input==NULL)
+ input=stdin;
+
+ if(output==NULL)
+ output=stdout;
+
+ opt=init_ks_options();
+ if(!opt)
+ return KEYSERVER_NO_MEMORY;
+
+ /* Get the command and info block */
+
+ while(fgets(line,MAX_LINE,input)!=NULL)
+ {
+ char optionstr[MAX_OPTION+1];
+
+ if(line[0]=='\n')
+ break;
+
+ err=parse_ks_options(line,opt);
+ if(err>0)
+ {
+ ret=err;
+ goto fail;
+ }
+ else if(err==0)
+ continue;
+
+ if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",optionstr)==1)
+ {
+ int no=0;
+ char *start=&optionstr[0];
+
+ optionstr[MAX_OPTION]='\0';
+
+ if(strncasecmp(optionstr,"no-",3)==0)
+ {
+ no=1;
+ start=&optionstr[3];
+ }
+
+ if(strncasecmp(start,"tls",3)==0)
+ {
+ if(no)
+ use_tls=0;
+ else if(start[3]=='=')
+ {
+ if(strcasecmp(&start[4],"no")==0)
+ use_tls=0;
+ else if(strcasecmp(&start[4],"try")==0)
+ use_tls=1;
+ else if(strcasecmp(&start[4],"warn")==0)
+ use_tls=2;
+ else if(strcasecmp(&start[4],"require")==0)
+ use_tls=3;
+ else
+ use_tls=1;
+ }
+ else if(start[3]=='\0')
+ use_tls=1;
+ }
+ else if(strncasecmp(start,"basedn",6)==0)
+ {
+ if(no)
+ {
+ free(basekeyspacedn);
+ basekeyspacedn=NULL;
+ }
+ else if(start[6]=='=')
+ {
+ free(basekeyspacedn);
+ basekeyspacedn=strdup(&start[7]);
+ if(!basekeyspacedn)
+ {
+ fprintf(console,"gpgkeys: out of memory while creating "
+ "base DN\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ real_ldap=1;
+ }
+ }
+ else if(strncasecmp(start,"binddn",6)==0)
+ {
+ if(no)
+ {
+ free(binddn);
+ binddn=NULL;
+ }
+ else if(start[6]=='=')
+ {
+ free(binddn);
+ binddn=strdup(&start[7]);
+ if(!binddn)
+ {
+ fprintf(console,"gpgkeys: out of memory while creating "
+ "bind DN\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ real_ldap=1;
+ }
+ }
+ else if(strncasecmp(start,"bindpw",6)==0)
+ {
+ if(no)
+ {
+ free(bindpw);
+ bindpw=NULL;
+ }
+ else if(start[6]=='=')
+ {
+ free(bindpw);
+ bindpw=strdup(&start[7]);
+ if(!bindpw)
+ {
+ fprintf(console,"gpgkeys: out of memory while creating "
+ "bind password\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ real_ldap=1;
+ }
+ }
+
+ continue;
+ }
+ }
+
+ if(!opt->scheme)
+ {
+ fprintf(console,"gpgkeys: no scheme supplied!\n");
+ ret=KEYSERVER_SCHEME_NOT_FOUND;
+ goto fail;
+ }
+
+ if(strcasecmp(opt->scheme,"ldaps")==0)
+ {
+ port=636;
+ use_ssl=1;
+ }
+
+ if(opt->port)
+ port=atoi(opt->port);
+
+ if(!opt->host)
+ {
+ fprintf(console,"gpgkeys: no keyserver host provided\n");
+ goto fail;
+ }
+
+ if(opt->timeout && register_timeout()==-1)
+ {
+ fprintf(console,"gpgkeys: unable to register timeout handler\n");
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+#if defined(LDAP_OPT_X_TLS_CACERTFILE) && defined(HAVE_LDAP_SET_OPTION)
+
+ if(opt->ca_cert_file)
+ {
+ err=ldap_set_option(NULL,LDAP_OPT_X_TLS_CACERTFILE,opt->ca_cert_file);
+ if(err!=LDAP_SUCCESS)
+ {
+ fprintf(console,"gpgkeys: unable to set ca-cert-file: %s\n",
+ ldap_err2string(err));
+ ret=KEYSERVER_INTERNAL_ERROR;
+ goto fail;
+ }
+ }
+#endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */
+
+ /* SSL trumps TLS */
+ if(use_ssl)
+ use_tls=0;
+
+ /* If it's a GET or a SEARCH, the next thing to come in is the
+ keyids. If it's a SEND, then there are no keyids. */
+
+ if(opt->action==KS_SEND)
+ while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n');
+ else if(opt->action==KS_GET
+ || opt->action==KS_GETNAME || opt->action==KS_SEARCH)
+ {
+ for(;;)
+ {
+ struct keylist *work;
+
+ if(fgets(line,MAX_LINE,input)==NULL)
+ break;
+ else
+ {
+ if(line[0]=='\n' || line[0]=='\0')
+ break;
+
+ work=malloc(sizeof(struct keylist));
+ if(work==NULL)
+ {
+ fprintf(console,"gpgkeys: out of memory while "
+ "building key list\n");
+ ret=KEYSERVER_NO_MEMORY;
+ goto fail;
+ }
+
+ strcpy(work->str,line);
+
+ /* Trim the trailing \n */
+ work->str[strlen(line)-1]='\0';
+
+ work->next=NULL;
+
+ /* Always attach at the end to keep the list in proper
+ order for searching */
+ if(keylist==NULL)
+ keylist=work;
+ else
+ keyptr->next=work;
+
+ keyptr=work;
+ }
+ }
+ }
+ else
+ {
+ fprintf(console,"gpgkeys: no keyserver command specified\n");
+ goto fail;
+ }
+
+ /* Send the response */
+
+ fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
+ fprintf(output,"PROGRAM %s\n\n",VERSION);
+
+ if(opt->verbose>1)
+ {
+ fprintf(console,"Host:\t\t%s\n",opt->host);
+ if(port)
+ fprintf(console,"Port:\t\t%d\n",port);
+ fprintf(console,"Command:\t%s\n",ks_action_to_string(opt->action));
+ }
+
+ if(opt->debug)
+ {
+#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(HAVE_LDAP_SET_OPTION)
+ err=ldap_set_option(NULL,LDAP_OPT_DEBUG_LEVEL,&opt->debug);
+ if(err!=LDAP_SUCCESS)
+ fprintf(console,"gpgkeys: unable to set debug mode: %s\n",
+ ldap_err2string(err));
+ else
+ fprintf(console,"gpgkeys: debug level %d\n",opt->debug);
+#else
+ fprintf(console,"gpgkeys: not built with debugging support\n");
+#endif
+ }
+
+ /* We have a timeout set for the setup stuff since it could time out
+ as well. */
+ set_timeout(opt->timeout);
+
+ /* Note that this tries all A records on a given host (or at least,
+ OpenLDAP does). */
+ ldap=ldap_init(opt->host,port);
+ if(ldap==NULL)
+ {
+ fprintf(console,"gpgkeys: internal LDAP init error: %s\n",
+ strerror(errno));
+ fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
+ goto fail;
+ }
+
+ if(use_ssl)
+ {
+#if defined(LDAP_OPT_X_TLS) && defined(HAVE_LDAP_SET_OPTION)
+ int ssl=LDAP_OPT_X_TLS_HARD;
+
+ err=ldap_set_option(ldap,LDAP_OPT_X_TLS,&ssl);
+ if(err!=LDAP_SUCCESS)
+ {
+ fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
+ ldap_err2string(err));
+ fail_all(keylist,ldap_err_to_gpg_err(err));
+ goto fail;
+ }
+
+ if(!opt->flags.check_cert)
+ ssl=LDAP_OPT_X_TLS_NEVER;
+
+ err=ldap_set_option(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,&ssl);
+ if(err!=LDAP_SUCCESS)
+ {
+ fprintf(console,
+ "gpgkeys: unable to set certificate validation: %s\n",
+ ldap_err2string(err));
+ fail_all(keylist,ldap_err_to_gpg_err(err));
+ goto fail;
+ }
+#else
+ fprintf(console,"gpgkeys: unable to make SSL connection: %s\n",
+ "not built with LDAPS support");
+ fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
+ goto fail;
+#endif
+ }
+
+ if(!basekeyspacedn)
+ if((err=find_basekeyspacedn()) || !basekeyspacedn)
+ {
+ fprintf(console,"gpgkeys: unable to retrieve LDAP base: %s\n",
+ err?ldap_err2string(err):"not found");
+ fail_all(keylist,ldap_err_to_gpg_err(err));
+ goto fail;
+ }
+
+ /* use_tls: 0=don't use, 1=try silently to use, 2=try loudly to use,
+ 3=force use. */
+ if(use_tls)
+ {
+ if(!real_ldap)
+ {
+ if(use_tls>=2)
+ fprintf(console,"gpgkeys: unable to start TLS: %s\n",
+ "not supported by the NAI LDAP keyserver");
+ if(use_tls==3)
+ {
+ fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
+ goto fail;
+ }
+ }
+ else
+ {
+#if defined(HAVE_LDAP_START_TLS_S) && defined(HAVE_LDAP_SET_OPTION)
+ int ver=LDAP_VERSION3;
+
+ err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
+
+#ifdef LDAP_OPT_X_TLS
+ if(err==LDAP_SUCCESS)
+ {
+ if(opt->flags.check_cert)
+ ver=LDAP_OPT_X_TLS_HARD;
+ else
+ ver=LDAP_OPT_X_TLS_NEVER;
+
+ err=ldap_set_option(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,&ver);
+ }
+#endif
+
+ if(err==LDAP_SUCCESS)
+ err=ldap_start_tls_s(ldap,NULL,NULL);
+
+ if(err!=LDAP_SUCCESS)
+ {
+ if(use_tls>=2 || opt->verbose>2)
+ fprintf(console,"gpgkeys: unable to start TLS: %s\n",
+ ldap_err2string(err));
+ /* Are we forcing it? */
+ if(use_tls==3)
+ {
+ fail_all(keylist,ldap_err_to_gpg_err(err));
+ goto fail;
+ }
+ }
+ else if(opt->verbose>1)
+ fprintf(console,"gpgkeys: TLS started successfully.\n");
+#else
+ if(use_tls>=2)
+ fprintf(console,"gpgkeys: unable to start TLS: %s\n",
+ "not built with TLS support");
+ if(use_tls==3)
+ {
+ fail_all(keylist,KEYSERVER_INTERNAL_ERROR);
+ goto fail;
+ }
+#endif
+ }
+ }
+
+ /* By default we don't bind as there is usually no need to. For
+ cases where the server needs some authentication, the user can
+ use binddn and bindpw for auth. */
+
+ if(binddn)
+ {
+#ifdef HAVE_LDAP_SET_OPTION
+ int ver=LDAP_VERSION3;
+
+ err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver);
+ if(err!=LDAP_SUCCESS)
+ {
+ fprintf(console,"gpgkeys: unable to go to LDAP 3: %s\n",
+ ldap_err2string(err));
+ fail_all(keylist,ldap_err_to_gpg_err(err));
+ goto fail;
+ }
+#endif
+
+ if(opt->verbose>2)
+ fprintf(console,"gpgkeys: LDAP bind to %s, pw %s\n",binddn,
+ bindpw?">not shown<":">none<");
+ err=ldap_simple_bind_s(ldap,binddn,bindpw);
+ if(err!=LDAP_SUCCESS)
+ {
+ fprintf(console,"gpgkeys: internal LDAP bind error: %s\n",
+ ldap_err2string(err));
+ fail_all(keylist,ldap_err_to_gpg_err(err));
+ goto fail;
+ }
+ else
+ bound=1;
+ }
+
+ if(opt->action==KS_GET)
+ {
+ keyptr=keylist;
+
+ while(keyptr!=NULL)
+ {
+ set_timeout(opt->timeout);
+
+ if(get_key(keyptr->str)!=KEYSERVER_OK)
+ failed++;
+
+ keyptr=keyptr->next;
+ }
+ }
+ else if(opt->action==KS_GETNAME)
+ {
+ keyptr=keylist;
+
+ while(keyptr!=NULL)
+ {
+ set_timeout(opt->timeout);
+
+ if(get_name(keyptr->str)!=KEYSERVER_OK)
+ failed++;
+
+ keyptr=keyptr->next;
+ }
+ }
+ else if(opt->action==KS_SEND)
+ {
+ int eof_seen = 0;
+
+ do
+ {
+ set_timeout(opt->timeout);
+
+ if(real_ldap)
+ {
+ if (send_key(&eof_seen) != KEYSERVER_OK)
+ failed++;
+ }
+ else
+ {
+ if (send_key_keyserver(&eof_seen) != KEYSERVER_OK)
+ failed++;
+ }
+ }
+ while (!eof_seen);
+ }
+ else if(opt->action==KS_SEARCH)
+ {
+ char *searchkey=NULL;
+ int len=0;
+
+ set_timeout(opt->timeout);
+
+ /* To search, we stick a * in between each key to search for.
+ This means that if the user enters words, they'll get
+ "enters*words". If the user "enters words", they'll get
+ "enters words" */
+
+ keyptr=keylist;
+ while(keyptr!=NULL)
+ {
+ len+=strlen(keyptr->str)+1;
+ keyptr=keyptr->next;
+ }
+
+ searchkey=malloc((len*3)+1);
+ if(searchkey==NULL)
+ {
+ ret=KEYSERVER_NO_MEMORY;
+ fail_all(keylist,KEYSERVER_NO_MEMORY);
+ goto fail;
+ }
+
+ searchkey[0]='\0';
+
+ keyptr=keylist;
+ while(keyptr!=NULL)
+ {
+ ldap_quote(searchkey,keyptr->str);
+ strcat(searchkey,"*");
+ keyptr=keyptr->next;
+ }
+
+ /* Nail that last "*" */
+ if(*searchkey)
+ searchkey[strlen(searchkey)-1]='\0';
+
+ if(search_key(searchkey)!=KEYSERVER_OK)
+ failed++;
+
+ free(searchkey);
+ }
+ else
+ assert (!"bad action");
+
+ if(!failed)
+ ret=KEYSERVER_OK;
+
+ fail:
+
+ while(keylist!=NULL)
+ {
+ struct keylist *current=keylist;
+ keylist=keylist->next;
+ free(current);
+ }
+
+ if(input!=stdin)
+ fclose(input);
+
+ if(output!=stdout)
+ fclose(output);
+
+ free_ks_options(opt);
+
+ if(ldap!=NULL && bound)
+ ldap_unbind_s(ldap);
+
+ free(basekeyspacedn);
+
+ return ret;
+}
diff --git a/keyserver/ksutil.c b/keyserver/ksutil.c
new file mode 100644
index 0000000..cc46b92
--- /dev/null
+++ b/keyserver/ksutil.c
@@ -0,0 +1,622 @@
+/* ksutil.c - general keyserver utility functions
+ * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ *
+ * In addition, as a special exception, the Free Software Foundation
+ * gives permission to link the code of the keyserver helper tools:
+ * gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
+ * project's "OpenSSL" library (or with modified versions of it that
+ * use the same license as the "OpenSSL" library), and distribute the
+ * linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If
+ * you modify this file, you may extend this exception to your version
+ * of the file, but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version.
+ */
+
+#include <config.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_W32_SYSTEM
+#include <windows.h>
+#endif
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#else
+#include "curl-shim.h"
+#endif
+#include "util.h"
+#include "keyserver.h"
+#include "ksutil.h"
+
+#ifdef HAVE_DOSISH_SYSTEM
+
+unsigned int set_timeout(unsigned int seconds) {return 0;}
+int register_timeout(void) {return 0;}
+
+#else
+
+static void
+catch_alarm(int foo)
+{
+ (void)foo;
+ _exit(KEYSERVER_TIMEOUT);
+}
+
+unsigned int
+set_timeout(unsigned int seconds)
+{
+ return alarm(seconds);
+}
+
+int
+register_timeout(void)
+{
+#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
+ struct sigaction act;
+
+ act.sa_handler=catch_alarm;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags=0;
+ return sigaction(SIGALRM,&act,NULL);
+#else
+ if(signal(SIGALRM,catch_alarm)==SIG_ERR)
+ return -1;
+ else
+ return 0;
+#endif
+}
+
+#endif /* !HAVE_DOSISH_SYSTEM */
+
+#ifdef HAVE_W32_SYSTEM
+void
+w32_init_sockets (void)
+{
+ static int initialized;
+ static WSADATA wsdata;
+
+ if (!initialized)
+ {
+ WSAStartup (0x0202, &wsdata);
+ initialized = 1;
+ }
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+struct ks_options *
+init_ks_options(void)
+{
+ struct ks_options *opt;
+
+ opt=calloc(1,sizeof(struct ks_options));
+
+ if(opt)
+ {
+ opt->action=KS_UNKNOWN;
+ opt->flags.include_revoked=1;
+ opt->flags.include_subkeys=1;
+ opt->flags.check_cert=1;
+ opt->timeout=DEFAULT_KEYSERVER_TIMEOUT;
+ opt->path=strdup("/");
+ if(!opt->path)
+ {
+ free(opt);
+ opt=NULL;
+ }
+ }
+
+ return opt;
+}
+
+void
+free_ks_options(struct ks_options *opt)
+{
+ if(opt)
+ {
+ free(opt->host);
+ free(opt->port);
+ free(opt->scheme);
+ free(opt->auth);
+ free(opt->path);
+ free(opt->opaque);
+ free(opt->ca_cert_file);
+ free(opt);
+ }
+}
+
+/* Returns 0 if we "ate" the line. Returns >0, a KEYSERVER_ error
+ code if that error applies. Returns -1 if we did not match the
+ line at all. */
+int
+parse_ks_options(char *line,struct ks_options *opt)
+{
+ int version;
+ char command[MAX_COMMAND+1];
+ char host[MAX_HOST+1];
+ char port[MAX_PORT+1];
+ char scheme[MAX_SCHEME+1];
+ char auth[MAX_AUTH+1];
+ char path[URLMAX_PATH+1];
+ char opaque[MAX_OPAQUE+1];
+ char option[MAX_OPTION+1];
+
+ if(line[0]=='#')
+ return 0;
+
+ if(sscanf(line,"COMMAND %" MKSTRING(MAX_COMMAND) "s\n",command)==1)
+ {
+ command[MAX_COMMAND]='\0';
+
+ if(strcasecmp(command,"get")==0)
+ opt->action=KS_GET;
+ else if(strcasecmp(command,"getname")==0)
+ opt->action=KS_GETNAME;
+ else if(strcasecmp(command,"send")==0)
+ opt->action=KS_SEND;
+ else if(strcasecmp(command,"search")==0)
+ opt->action=KS_SEARCH;
+
+ return 0;
+ }
+
+ if(sscanf(line,"HOST %" MKSTRING(MAX_HOST) "s\n",host)==1)
+ {
+ host[MAX_HOST]='\0';
+ free(opt->host);
+ opt->host=strdup(host);
+ if(!opt->host)
+ return KEYSERVER_NO_MEMORY;
+ return 0;
+ }
+
+ if(sscanf(line,"PORT %" MKSTRING(MAX_PORT) "s\n",port)==1)
+ {
+ port[MAX_PORT]='\0';
+ free(opt->port);
+ opt->port=strdup(port);
+ if(!opt->port)
+ return KEYSERVER_NO_MEMORY;
+ return 0;
+ }
+
+ if(sscanf(line,"SCHEME %" MKSTRING(MAX_SCHEME) "s\n",scheme)==1)
+ {
+ scheme[MAX_SCHEME]='\0';
+ free(opt->scheme);
+ opt->scheme=strdup(scheme);
+ if(!opt->scheme)
+ return KEYSERVER_NO_MEMORY;
+ return 0;
+ }
+
+ if(sscanf(line,"AUTH %" MKSTRING(MAX_AUTH) "s\n",auth)==1)
+ {
+ auth[MAX_AUTH]='\0';
+ free(opt->auth);
+ opt->auth=strdup(auth);
+ if(!opt->auth)
+ return KEYSERVER_NO_MEMORY;
+ return 0;
+ }
+
+ if(sscanf(line,"PATH %" MKSTRING(URLMAX_PATH) "s\n",path)==1)
+ {
+ path[URLMAX_PATH]='\0';
+ free(opt->path);
+ opt->path=strdup(path);
+ if(!opt->path)
+ return KEYSERVER_NO_MEMORY;
+ return 0;
+ }
+
+ if(sscanf(line,"OPAQUE %" MKSTRING(MAX_OPAQUE) "s\n",opaque)==1)
+ {
+ opaque[MAX_OPAQUE]='\0';
+ free(opt->opaque);
+ opt->opaque=strdup(opaque);
+ if(!opt->opaque)
+ return KEYSERVER_NO_MEMORY;
+ return 0;
+ }
+
+ if(sscanf(line,"VERSION %d\n",&version)==1)
+ {
+ if(version!=KEYSERVER_PROTO_VERSION)
+ return KEYSERVER_VERSION_ERROR;
+
+ return 0;
+ }
+
+ if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",option)==1)
+ {
+ int no=0;
+ char *start=&option[0];
+
+ option[MAX_OPTION]='\0';
+
+ if(strncasecmp(option,"no-",3)==0)
+ {
+ no=1;
+ start=&option[3];
+ }
+
+ if(strncasecmp(start,"verbose",7)==0)
+ {
+ if(no)
+ opt->verbose=0;
+ else if(start[7]=='=')
+ opt->verbose=atoi(&start[8]);
+ else
+ opt->verbose++;
+ }
+ else if(strcasecmp(start,"include-disabled")==0)
+ {
+ if(no)
+ opt->flags.include_disabled=0;
+ else
+ opt->flags.include_disabled=1;
+ }
+ else if(strcasecmp(start,"include-revoked")==0)
+ {
+ if(no)
+ opt->flags.include_revoked=0;
+ else
+ opt->flags.include_revoked=1;
+ }
+ else if(strcasecmp(start,"include-subkeys")==0)
+ {
+ if(no)
+ opt->flags.include_subkeys=0;
+ else
+ opt->flags.include_subkeys=1;
+ }
+ else if(strcasecmp(start,"check-cert")==0)
+ {
+ if(no)
+ opt->flags.check_cert=0;
+ else
+ opt->flags.check_cert=1;
+ }
+ else if(strncasecmp(start,"debug",5)==0)
+ {
+ if(no)
+ opt->debug=0;
+ else if(start[5]=='=')
+ opt->debug=atoi(&start[6]);
+ else if(start[5]=='\0')
+ opt->debug=1;
+ }
+ else if(strncasecmp(start,"timeout",7)==0)
+ {
+ if(no)
+ opt->timeout=0;
+ else if(start[7]=='=')
+ opt->timeout=atoi(&start[8]);
+ else if(start[7]=='\0')
+ opt->timeout=DEFAULT_KEYSERVER_TIMEOUT;
+ }
+ else if(strncasecmp(start,"ca-cert-file",12)==0)
+ {
+ if(no)
+ {
+ free(opt->ca_cert_file);
+ opt->ca_cert_file=NULL;
+ }
+ else if(start[12]=='=')
+ {
+ free(opt->ca_cert_file);
+ opt->ca_cert_file = make_filename_try (start+13, NULL);
+ if(!opt->ca_cert_file)
+ return KEYSERVER_NO_MEMORY;
+ }
+ }
+ }
+
+ return -1;
+}
+
+const char *
+ks_action_to_string(enum ks_action action)
+{
+ switch(action)
+ {
+ case KS_UNKNOWN: return "UNKNOWN";
+ case KS_GET: return "GET";
+ case KS_GETNAME: return "GETNAME";
+ case KS_SEND: return "SEND";
+ case KS_SEARCH: return "SEARCH";
+ }
+
+ return "?";
+}
+
+/* Canonicalize CRLF to just LF by stripping CRs. This actually makes
+ sense, since on Unix-like machines LF is correct, and on win32-like
+ machines, our output buffer is opened in textmode and will
+ re-canonicalize line endings back to CRLF. Since we only need to
+ handle armored keys, we don't have to worry about odd cases like
+ CRCRCR and the like. */
+
+void
+print_nocr(FILE *stream,const char *str)
+{
+ while(*str)
+ {
+ if(*str!='\r')
+ fputc(*str,stream);
+ str++;
+ }
+}
+
+enum ks_search_type
+classify_ks_search(const char **search)
+{
+ switch(**search)
+ {
+ case '*':
+ (*search)++;
+ return KS_SEARCH_SUBSTR;
+ case '=':
+ (*search)++;
+ return KS_SEARCH_EXACT;
+ case '<':
+ (*search)++;
+ return KS_SEARCH_MAIL;
+ case '@':
+ (*search)++;
+ return KS_SEARCH_MAILSUB;
+ case '0':
+ if((*search)[1]=='x')
+ {
+ if(strlen(*search)==10
+ && strspn(*search,"abcdefABCDEF1234567890x")==10)
+ {
+ (*search)+=2;
+ return KS_SEARCH_KEYID_SHORT;
+ }
+ else if(strlen(*search)==18
+ && strspn(*search,"abcdefABCDEF1234567890x")==18)
+ {
+ (*search)+=2;
+ return KS_SEARCH_KEYID_LONG;
+ }
+ }
+ /* fall through */
+ default:
+ return KS_SEARCH_SUBSTR;
+ }
+}
+
+int
+curl_err_to_gpg_err(CURLcode error)
+{
+ switch(error)
+ {
+ case CURLE_OK: return KEYSERVER_OK;
+ case CURLE_UNSUPPORTED_PROTOCOL: return KEYSERVER_SCHEME_NOT_FOUND;
+ case CURLE_COULDNT_CONNECT: return KEYSERVER_UNREACHABLE;
+ case CURLE_FTP_COULDNT_RETR_FILE: return KEYSERVER_KEY_NOT_FOUND;
+ default: return KEYSERVER_INTERNAL_ERROR;
+ }
+}
+
+#define B64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+
+static void
+curl_armor_writer(const unsigned char *buf,size_t size,void *cw_ctx)
+{
+ struct curl_writer_ctx *ctx=cw_ctx;
+ size_t idx=0;
+
+ while(idx<size)
+ {
+ for(;ctx->armor_remaining<3 && idx<size;ctx->armor_remaining++,idx++)
+ ctx->armor_ctx[ctx->armor_remaining]=buf[idx];
+
+ if(ctx->armor_remaining==3)
+ {
+ /* Top 6 bytes of ctx->armor_ctx[0] */
+ fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
+ /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of
+ ctx->armor_ctx[1] */
+ fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30)
+ |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream);
+ /* Bottom 4 bytes of ctx->armor_ctx[1] and top 2 bytes of
+ ctx->armor_ctx[2] */
+ fputc(B64[(((ctx->armor_ctx[1]<<2)&0x3C)
+ |((ctx->armor_ctx[2]>>6)&0x03))&0x3F],ctx->stream);
+ /* Bottom 6 bytes of ctx->armor_ctx[2] */
+ fputc(B64[(ctx->armor_ctx[2]&0x3F)],ctx->stream);
+
+ ctx->linelen+=4;
+ if(ctx->linelen>=70)
+ {
+ fputc('\n',ctx->stream);
+ ctx->linelen=0;
+ }
+
+ ctx->armor_remaining=0;
+ }
+ }
+
+}
+
+size_t
+curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx)
+{
+ struct curl_writer_ctx *ctx=cw_ctx;
+ const char *buf=ptr;
+ size_t i;
+
+ if(!ctx->flags.initialized)
+ {
+ if(size*nmemb==0)
+ return 0;
+
+ /* The object we're fetching is in binary form */
+ if(*buf&0x80)
+ {
+ ctx->flags.armor=1;
+ fprintf(ctx->stream,BEGIN"\n\n");
+ }
+ else
+ ctx->marker=BEGIN;
+
+ ctx->flags.initialized=1;
+ }
+
+ if(ctx->flags.armor)
+ curl_armor_writer(ptr,size*nmemb,cw_ctx);
+ else
+ {
+ /* scan the incoming data for our marker */
+ for(i=0;!ctx->flags.done && i<(size*nmemb);i++)
+ {
+ if(buf[i]==ctx->marker[ctx->markeridx])
+ {
+ ctx->markeridx++;
+ if(ctx->marker[ctx->markeridx]=='\0')
+ {
+ if(ctx->flags.begun)
+ ctx->flags.done=1;
+ else
+ {
+ /* We've found the BEGIN marker, so now we're
+ looking for the END marker. */
+ ctx->flags.begun=1;
+ ctx->marker=END;
+ ctx->markeridx=0;
+ fprintf(ctx->stream,BEGIN);
+ continue;
+ }
+ }
+ }
+ else
+ ctx->markeridx=0;
+
+ if(ctx->flags.begun)
+ {
+ /* Canonicalize CRLF to just LF by stripping CRs. This
+ actually makes sense, since on Unix-like machines LF
+ is correct, and on win32-like machines, our output
+ buffer is opened in textmode and will re-canonicalize
+ line endings back to CRLF. Since this code is just
+ for handling armored keys, we don't have to worry
+ about odd cases like CRCRCR and the like. */
+
+ if(buf[i]!='\r')
+ fputc(buf[i],ctx->stream);
+ }
+ }
+ }
+
+ return size*nmemb;
+}
+
+void
+curl_writer_finalize(struct curl_writer_ctx *ctx)
+{
+ if(ctx->flags.armor)
+ {
+ if(ctx->armor_remaining==2)
+ {
+ /* Top 6 bytes of ctx->armorctx[0] */
+ fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
+ /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of
+ ctx->armor_ctx[1] */
+ fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30)
+ |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream);
+ /* Bottom 4 bytes of ctx->armor_ctx[1] */
+ fputc(B64[((ctx->armor_ctx[1]<<2)&0x3C)],ctx->stream);
+ /* Pad */
+ fputc('=',ctx->stream);
+ }
+ else if(ctx->armor_remaining==1)
+ {
+ /* Top 6 bytes of ctx->armor_ctx[0] */
+ fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
+ /* Bottom 2 bytes of ctx->armor_ctx[0] */
+ fputc(B64[((ctx->armor_ctx[0]<<4)&0x30)],ctx->stream);
+ /* Pad */
+ fputc('=',ctx->stream);
+ /* Pad */
+ fputc('=',ctx->stream);
+ }
+
+ fprintf(ctx->stream,"\n"END);
+ ctx->flags.done=1;
+ }
+}
+
+
+int
+ks_hextobyte (const char *s)
+{
+ int c;
+
+ if ( *s >= '0' && *s <= '9' )
+ c = 16 * (*s - '0');
+ else if ( *s >= 'A' && *s <= 'F' )
+ c = 16 * (10 + *s - 'A');
+ else if ( *s >= 'a' && *s <= 'f' )
+ c = 16 * (10 + *s - 'a');
+ else
+ return -1;
+ s++;
+ if ( *s >= '0' && *s <= '9' )
+ c += *s - '0';
+ else if ( *s >= 'A' && *s <= 'F' )
+ c += 10 + *s - 'A';
+ else if ( *s >= 'a' && *s <= 'f' )
+ c += 10 + *s - 'a';
+ else
+ return -1;
+ return c;
+}
+
+
+/* Non localized version of toupper. */
+int
+ks_toupper (int c)
+{
+ if (c >= 'a' && c <= 'z')
+ c &= ~0x20;
+ return c;
+}
+
+
+/* Non localized version of strcasecmp. */
+int
+ks_strcasecmp (const char *a, const char *b)
+{
+ if (a == b)
+ return 0;
+
+ for (; *a && *b; a++, b++)
+ {
+ if (*a != *b && ks_toupper (*a) != ks_toupper (*b))
+ break;
+ }
+ return *a == *b? 0 : (ks_toupper (*a) - ks_toupper (*b));
+}
diff --git a/keyserver/ksutil.h b/keyserver/ksutil.h
new file mode 100644
index 0000000..9f51359
--- /dev/null
+++ b/keyserver/ksutil.h
@@ -0,0 +1,149 @@
+/* ksutil.h
+ * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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/>.
+ *
+ * In addition, as a special exception, the Free Software Foundation
+ * gives permission to link the code of the keyserver helper tools:
+ * gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
+ * project's "OpenSSL" library (or with modified versions of it that
+ * use the same license as the "OpenSSL" library), and distribute the
+ * linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If
+ * you modify this file, you may extend this exception to your version
+ * of the file, but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version.
+ */
+
+#ifndef _KSUTIL_H_
+#define _KSUTIL_H_
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#else
+#include "curl-shim.h"
+#endif
+
+/* MAX_LINE must be at least 1 larger than the largest item we expect
+ to receive, including the name tag ("COMMAND", "PORT", etc) and
+ space between. In practice, that means it should be
+ strlen("OPAQUE")+1+sizeof_opaque+1 */
+#define MAX_LINE (6+1+1024+1)
+
+#define MAX_COMMAND 7
+#define MAX_OPTION 256
+#define MAX_SCHEME 20
+#define MAX_OPAQUE 1024
+#define MAX_AUTH 128
+#define MAX_HOST 80
+#define MAX_PORT 10
+#define URLMAX_PATH 1024
+#define MAX_PROXY 128
+#define MAX_URL (MAX_SCHEME+1+3+MAX_AUTH+1+1+MAX_HOST+1+1 \
+ +MAX_PORT+1+1+URLMAX_PATH+1+50)
+
+#define STRINGIFY(x) #x
+#define MKSTRING(x) STRINGIFY(x)
+
+#define BEGIN "-----BEGIN PGP PUBLIC KEY BLOCK-----"
+#define END "-----END PGP PUBLIC KEY BLOCK-----"
+
+#ifdef __riscos__
+#define HTTP_PROXY_ENV "GnuPG$HttpProxy"
+#else
+#define HTTP_PROXY_ENV "http_proxy"
+#endif
+
+struct keylist
+{
+ char str[MAX_LINE];
+ struct keylist *next;
+};
+
+/* 2 minutes seems reasonable */
+#define DEFAULT_KEYSERVER_TIMEOUT 120
+
+unsigned int set_timeout(unsigned int seconds);
+int register_timeout(void);
+
+#ifdef HAVE_W32_SYSTEM
+void w32_init_sockets (void);
+#endif
+
+
+enum ks_action {KS_UNKNOWN=0,KS_GET,KS_GETNAME,KS_SEND,KS_SEARCH};
+
+enum ks_search_type {KS_SEARCH_SUBSTR,KS_SEARCH_EXACT,
+ KS_SEARCH_MAIL,KS_SEARCH_MAILSUB,
+ KS_SEARCH_KEYID_LONG,KS_SEARCH_KEYID_SHORT};
+
+struct ks_options
+{
+ enum ks_action action;
+ char *host;
+ char *port;
+ char *scheme;
+ char *auth;
+ char *path;
+ char *opaque;
+ struct
+ {
+ unsigned int include_disabled:1;
+ unsigned int include_revoked:1;
+ unsigned int include_subkeys:1;
+ unsigned int check_cert:1;
+ } flags;
+ unsigned int verbose;
+ unsigned int debug;
+ unsigned int timeout;
+ char *ca_cert_file;
+};
+
+struct ks_options *init_ks_options(void);
+void free_ks_options(struct ks_options *opt);
+int parse_ks_options(char *line,struct ks_options *opt);
+const char *ks_action_to_string(enum ks_action action);
+void print_nocr(FILE *stream,const char *str);
+enum ks_search_type classify_ks_search(const char **search);
+
+int curl_err_to_gpg_err(CURLcode error);
+
+struct curl_writer_ctx
+{
+ struct
+ {
+ unsigned int initialized:1;
+ unsigned int begun:1;
+ unsigned int done:1;
+ unsigned int armor:1;
+ } flags;
+
+ int armor_remaining;
+ unsigned char armor_ctx[3];
+ int markeridx,linelen;
+ const char *marker;
+ FILE *stream;
+};
+
+size_t curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx);
+void curl_writer_finalize(struct curl_writer_ctx *ctx);
+
+int ks_hextobyte (const char *s);
+int ks_toupper (int c);
+int ks_strcasecmp (const char *a, const char *b);
+
+
+#endif /* !_KSUTIL_H_ */
diff --git a/keyserver/no-libgcrypt.c b/keyserver/no-libgcrypt.c
new file mode 100644
index 0000000..2cce156
--- /dev/null
+++ b/keyserver/no-libgcrypt.c
@@ -0,0 +1,107 @@
+/* no-libgcrypt.c - Replacement functions for libgcrypt.
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "../common/util.h"
+#include "i18n.h"
+
+
+/* Replace libgcrypt's malloc functions which are used by
+ ../jnlib/libjnlib.a . ../common/util.h defines macros to map them
+ to xmalloc etc. */
+static void
+out_of_memory (void)
+{
+ fprintf (stderr, "error allocating enough memory: %s\n", strerror (errno));
+ exit (2);
+}
+
+
+void *
+gcry_malloc (size_t n)
+{
+ return malloc (n);
+}
+
+void *
+gcry_xmalloc (size_t n)
+{
+ void *p = malloc (n);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+char *
+gcry_strdup (const char *string)
+{
+ char *p = malloc (strlen (string)+1);
+ if (p)
+ strcpy (p, string);
+ return p;
+}
+
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ return realloc (a, n);
+}
+
+void *
+gcry_xrealloc (void *a, size_t n)
+{
+ void *p = realloc (a, n);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ return calloc (n, m);
+}
+
+void *
+gcry_xcalloc (size_t n, size_t m)
+{
+ void *p = calloc (n, m);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+
+char *
+gcry_xstrdup (const char *string)
+{
+ void *p = malloc (strlen (string)+1);
+ if (!p)
+ out_of_memory ();
+ strcpy( p, string );
+ return p;
+}
+
+void
+gcry_free (void *a)
+{
+ if (a)
+ free (a);
+}