diff options
author | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:46:38 +0900 |
---|---|---|
committer | Kibum Kim <kb0929.kim@samsung.com> | 2012-01-07 00:46:38 +0900 |
commit | f5660c6460a863b19f9ef745575780e37cc192a9 (patch) | |
tree | 0b478679da32d706de7b0de546d2e4daf03b160c /keyserver | |
parent | 06b9124a4f9d38acc78e6af686bc49a06f6354f8 (diff) | |
download | gnupg-f5660c6460a863b19f9ef745575780e37cc192a9.tar.gz gnupg-f5660c6460a863b19f9ef745575780e37cc192a9.tar.bz2 gnupg-f5660c6460a863b19f9ef745575780e37cc192a9.zip |
Diffstat (limited to 'keyserver')
-rw-r--r-- | keyserver/ChangeLog | 1142 | ||||
-rw-r--r-- | keyserver/Makefile.am | 54 | ||||
-rw-r--r-- | keyserver/Makefile.in | 824 | ||||
-rw-r--r-- | keyserver/curl-shim.c | 322 | ||||
-rw-r--r-- | keyserver/curl-shim.h | 92 | ||||
-rw-r--r-- | keyserver/gpgkeys_curl.c | 380 | ||||
-rw-r--r-- | keyserver/gpgkeys_finger.c | 534 | ||||
-rw-r--r-- | keyserver/gpgkeys_hkp.c | 854 | ||||
-rw-r--r-- | keyserver/gpgkeys_ldap.c | 2368 | ||||
-rwxr-xr-x | keyserver/gpgkeys_mailto.in | 225 | ||||
-rwxr-xr-x | keyserver/gpgkeys_test.in | 99 | ||||
-rw-r--r-- | keyserver/ksutil.c | 564 | ||||
-rw-r--r-- | keyserver/ksutil.h | 141 |
13 files changed, 7599 insertions, 0 deletions
diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog new file mode 100644 index 0000000..b720aee --- /dev/null +++ b/keyserver/ChangeLog @@ -0,0 +1,1142 @@ +2006-12-03 David Shaw <dshaw@jabberwocky.com> + + * ksutil.c (classify_ks_search): Try and recognize a key ID even + without the 0x prefix. This isn't exact (it's possible that a + user ID string happens to be 8 or 16 digits of hex), but it's + extremely unlikely. Plus GPG itself makes the same assumption. + + * gpgkeys_hkp.c (search_key): HKP keyservers like the 0x to be + present when searching by keyID. + +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-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-09-28 David Shaw <dshaw@jabberwocky.com> + + * Makefile.am: Link gpgkeys_ldap to libcompat.a. + + * gpgkeys_ldap.c, ksutil.h, ksutil.c: Remove hextobyte instead of + ks_hextobyte as it is provided by libcompat now. + + * gpgkeys_ldap.c (build_attrs), ksutil.c (ks_toupper, + ks_strcasecmp), ksutil.h: Remove the need for strcasecmp as the + field tags are always lowercase. + +2006-09-26 Werner Koch <wk@g10code.com> + + * gpgkeys_finger.c (get_key): Cast away signed/unsigned char ptr + mismatches. + + * ksutil.c (ks_hextobyte, ks_toupper, ks_strcasecmp): New. Use + them instead of there ascii_foo counterparts. + * gpgkeys_ldap.c (main): Replaced BUG by assert. + + * gpgkeys_curl.c, gpgkeys_hkp.c, gpgkeys_ldap.c, 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. + +2006-07-26 David Shaw <dshaw@jabberwocky.com> + + * Makefile.am: Fix missing include path for gpgkeys_finger (needs + the libcurl path, even though it doesn't use libcurl because of + ksutil.c:curl_err_to_gpg_err(). Noted by Gilbert Fernandes. + +2006-07-20 David Shaw <dshaw@jabberwocky.com> + + * curl-shim.c (curl_easy_perform): Minor cleanup of proxy code. + +2006-07-16 David Shaw <dshaw@jabberwocky.com> + + * gpgkeys_hkp.c (send_key), gpgkeys_ldap.c (send_key, + send_key_keyserver): Improved version of previous fix. Force + match on spaces in string. + +2006-07-14 David Shaw <dshaw@jabberwocky.com> + + * 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-07-12 David Shaw <dshaw@jabberwocky.com> + + * gpgkeys_ldap.c (printquoted), curl-shim.c (curl_escape): Fix bad + encoding of characters > 127. Noted by Nalin Dahyabhai. + +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. """) 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 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..3379910 --- /dev/null +++ b/keyserver/Makefile.am @@ -0,0 +1,54 @@ +# Copyright (C) 2001, 2002, 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +## Process this file with automake to produce Makefile.in + +INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl +EXTRA_PROGRAMS = gpgkeys_ldap gpgkeys_hkp gpgkeys_finger gpgkeys_curl +EXTRA_SCRIPTS = gpgkeys_mailto + +gpglibexecdir = $(libexecdir)/@PACKAGE@ + +gpglibexec_PROGRAMS = @GPGKEYS_LDAP@ @GPGKEYS_HKP@ @GPGKEYS_FINGER@ @GPGKEYS_CURL@ +gpglibexec_SCRIPTS = @GPGKEYS_MAILTO@ +noinst_SCRIPTS = gpgkeys_test + +gpgkeys_ldap_SOURCES = gpgkeys_ldap.c ksutil.c ksutil.h +gpgkeys_hkp_SOURCES = gpgkeys_hkp.c ksutil.c ksutil.h +gpgkeys_finger_SOURCES = gpgkeys_finger.c ksutil.c ksutil.h +gpgkeys_curl_SOURCES = gpgkeys_curl.c ksutil.c ksutil.h + +other_libs = $(LIBICONV) $(LIBINTL) $(CAPLIBS) + +gpgkeys_ldap_CPPFLAGS = @LDAP_CPPFLAGS@ +gpgkeys_ldap_LDADD = ../util/libcompat.a @LDAPLIBS@ @NETLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ + +gpgkeys_finger_LDADD = ../util/libutil.a @NETLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ + +if FAKE_CURL +gpgkeys_curl_SOURCES += curl-shim.c curl-shim.h +gpgkeys_curl_LDADD = ../util/libutil.a @NETLIBS@ @DNSLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ +gpgkeys_hkp_SOURCES += curl-shim.c curl-shim.h +gpgkeys_hkp_LDADD = ../util/libutil.a @NETLIBS@ @DNSLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ +else +gpgkeys_curl_CPPFLAGS = @LIBCURL_CPPFLAGS@ +gpgkeys_curl_LDADD = @LIBCURL@ @GETOPT@ +gpgkeys_hkp_CPPFLAGS = @LIBCURL_CPPFLAGS@ +gpgkeys_hkp_LDADD = @LIBCURL@ @GETOPT@ +gpgkeys_finger_CPPFLAGS = @LIBCURL_CPPFLAGS@ +endif diff --git a/keyserver/Makefile.in b/keyserver/Makefile.in new file mode 100644 index 0000000..c262238 --- /dev/null +++ b/keyserver/Makefile.in @@ -0,0 +1,824 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 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@ + +# Copyright (C) 2001, 2002, 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +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 = gpgkeys_ldap$(EXEEXT) gpgkeys_hkp$(EXEEXT) \ + gpgkeys_finger$(EXEEXT) gpgkeys_curl$(EXEEXT) +gpglibexec_PROGRAMS = @GPGKEYS_LDAP@ @GPGKEYS_HKP@ @GPGKEYS_FINGER@ \ + @GPGKEYS_CURL@ $(am__empty) +@FAKE_CURL_TRUE@am__append_1 = curl-shim.c curl-shim.h +@FAKE_CURL_TRUE@am__append_2 = curl-shim.c curl-shim.h +subdir = keyserver +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/gpgkeys_mailto.in $(srcdir)/gpgkeys_test.in \ + ChangeLog +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intmax.m4 \ + $(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \ + $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/isc-posix.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/libcurl.m4 \ + $(top_srcdir)/m4/libusb.m4 $(top_srcdir)/m4/longdouble.m4 \ + $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/printf-posix.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/signed.m4 \ + $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/stdint_h.m4 \ + $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/m4/uintmax_t.m4 \ + $(top_srcdir)/m4/ulonglong.m4 $(top_srcdir)/m4/wchar_t.m4 \ + $(top_srcdir)/m4/wint_t.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 = gpgkeys_mailto gpgkeys_test +am__installdirs = "$(DESTDIR)$(gpglibexecdir)" \ + "$(DESTDIR)$(gpglibexecdir)" +gpglibexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(gpglibexec_PROGRAMS) +am__gpgkeys_curl_SOURCES_DIST = gpgkeys_curl.c ksutil.c ksutil.h \ + curl-shim.c curl-shim.h +@FAKE_CURL_TRUE@am__objects_1 = gpgkeys_curl-curl-shim.$(OBJEXT) +am_gpgkeys_curl_OBJECTS = gpgkeys_curl-gpgkeys_curl.$(OBJEXT) \ + gpgkeys_curl-ksutil.$(OBJEXT) $(am__objects_1) +gpgkeys_curl_OBJECTS = $(am_gpgkeys_curl_OBJECTS) +am__DEPENDENCIES_1 = +am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +@FAKE_CURL_TRUE@gpgkeys_curl_DEPENDENCIES = ../util/libutil.a \ +@FAKE_CURL_TRUE@ $(am__DEPENDENCIES_2) +am_gpgkeys_finger_OBJECTS = gpgkeys_finger-gpgkeys_finger.$(OBJEXT) \ + gpgkeys_finger-ksutil.$(OBJEXT) +gpgkeys_finger_OBJECTS = $(am_gpgkeys_finger_OBJECTS) +gpgkeys_finger_DEPENDENCIES = ../util/libutil.a $(am__DEPENDENCIES_2) +am__gpgkeys_hkp_SOURCES_DIST = gpgkeys_hkp.c ksutil.c ksutil.h \ + curl-shim.c curl-shim.h +@FAKE_CURL_TRUE@am__objects_2 = gpgkeys_hkp-curl-shim.$(OBJEXT) +am_gpgkeys_hkp_OBJECTS = gpgkeys_hkp-gpgkeys_hkp.$(OBJEXT) \ + gpgkeys_hkp-ksutil.$(OBJEXT) $(am__objects_2) +gpgkeys_hkp_OBJECTS = $(am_gpgkeys_hkp_OBJECTS) +@FAKE_CURL_TRUE@gpgkeys_hkp_DEPENDENCIES = ../util/libutil.a \ +@FAKE_CURL_TRUE@ $(am__DEPENDENCIES_2) +am_gpgkeys_ldap_OBJECTS = gpgkeys_ldap-gpgkeys_ldap.$(OBJEXT) \ + gpgkeys_ldap-ksutil.$(OBJEXT) +gpgkeys_ldap_OBJECTS = $(am_gpgkeys_ldap_OBJECTS) +gpgkeys_ldap_DEPENDENCIES = ../util/libcompat.a $(am__DEPENDENCIES_2) +gpglibexecSCRIPT_INSTALL = $(INSTALL_SCRIPT) +SCRIPTS = $(gpglibexec_SCRIPTS) $(noinst_SCRIPTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(gpgkeys_curl_SOURCES) $(gpgkeys_finger_SOURCES) \ + $(gpgkeys_hkp_SOURCES) $(gpgkeys_ldap_SOURCES) +DIST_SOURCES = $(am__gpgkeys_curl_SOURCES_DIST) \ + $(gpgkeys_finger_SOURCES) $(am__gpgkeys_hkp_SOURCES_DIST) \ + $(gpgkeys_ldap_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +CAPLIBS = @CAPLIBS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCAS = @CCAS@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CROSS_COMPILING_FALSE = @CROSS_COMPILING_FALSE@ +CROSS_COMPILING_TRUE = @CROSS_COMPILING_TRUE@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIBS = @DLLIBS@ +DNSLIBS = @DNSLIBS@ +DOCBOOK_TO_MAN = @DOCBOOK_TO_MAN@ +DOCBOOK_TO_TEXI = @DOCBOOK_TO_TEXI@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_AGENT_SUPPORT_FALSE = @ENABLE_AGENT_SUPPORT_FALSE@ +ENABLE_AGENT_SUPPORT_TRUE = @ENABLE_AGENT_SUPPORT_TRUE@ +ENABLE_BZIP2_SUPPORT_FALSE = @ENABLE_BZIP2_SUPPORT_FALSE@ +ENABLE_BZIP2_SUPPORT_TRUE = @ENABLE_BZIP2_SUPPORT_TRUE@ +ENABLE_CARD_SUPPORT_FALSE = @ENABLE_CARD_SUPPORT_FALSE@ +ENABLE_CARD_SUPPORT_TRUE = @ENABLE_CARD_SUPPORT_TRUE@ +ENABLE_LOCAL_ZLIB_FALSE = @ENABLE_LOCAL_ZLIB_FALSE@ +ENABLE_LOCAL_ZLIB_TRUE = @ENABLE_LOCAL_ZLIB_TRUE@ +EXEEXT = @EXEEXT@ +FAKE_CURL_FALSE = @FAKE_CURL_FALSE@ +FAKE_CURL_TRUE = @FAKE_CURL_TRUE@ +FAQPROG = @FAQPROG@ +GENCAT = @GENCAT@ +GETOPT = @GETOPT@ +GLIBC21 = @GLIBC21@ +GMSGFMT = @GMSGFMT@ +GPGKEYS_CURL = @GPGKEYS_CURL@ +GPGKEYS_FINGER = @GPGKEYS_FINGER@ +GPGKEYS_HKP = @GPGKEYS_HKP@ +GPGKEYS_LDAP = @GPGKEYS_LDAP@ +GPGKEYS_MAILTO = @GPGKEYS_MAILTO@ +GREP = @GREP@ +HAVE_ASPRINTF = @HAVE_ASPRINTF@ +HAVE_DOCBOOK_TO_MAN_FALSE = @HAVE_DOCBOOK_TO_MAN_FALSE@ +HAVE_DOCBOOK_TO_MAN_TRUE = @HAVE_DOCBOOK_TO_MAN_TRUE@ +HAVE_DOCBOOK_TO_TEXI_FALSE = @HAVE_DOCBOOK_TO_TEXI_FALSE@ +HAVE_DOCBOOK_TO_TEXI_TRUE = @HAVE_DOCBOOK_TO_TEXI_TRUE@ +HAVE_DOSISH_SYSTEM_FALSE = @HAVE_DOSISH_SYSTEM_FALSE@ +HAVE_DOSISH_SYSTEM_TRUE = @HAVE_DOSISH_SYSTEM_TRUE@ +HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@ +HAVE_SNPRINTF = @HAVE_SNPRINTF@ +HAVE_USTAR_FALSE = @HAVE_USTAR_FALSE@ +HAVE_USTAR_TRUE = @HAVE_USTAR_TRUE@ +HAVE_W32_SYSTEM_FALSE = @HAVE_W32_SYSTEM_FALSE@ +HAVE_W32_SYSTEM_TRUE = @HAVE_W32_SYSTEM_TRUE@ +HAVE_WPRINTF = @HAVE_WPRINTF@ +IDEA_O = @IDEA_O@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLBISON = @INTLBISON@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ +LDAPLIBS = @LDAPLIBS@ +LDAP_CPPFLAGS = @LDAP_CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBUSB = @LIBUSB@ +LIBUSB_CPPFLAGS = @LIBUSB_CPPFLAGS@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MPI_EXTRA_ASM_OBJS = @MPI_EXTRA_ASM_OBJS@ +MPI_OPT_FLAGS = @MPI_OPT_FLAGS@ +MPI_SFLAGS = @MPI_SFLAGS@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +NETLIBS = @NETLIBS@ +NM = @NM@ +NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TAR = @TAR@ +USE_DNS_SRV_FALSE = @USE_DNS_SRV_FALSE@ +USE_DNS_SRV_TRUE = @USE_DNS_SRV_TRUE@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_INTERNAL_REGEX_FALSE = @USE_INTERNAL_REGEX_FALSE@ +USE_INTERNAL_REGEX_TRUE = @USE_INTERNAL_REGEX_TRUE@ +USE_NLS = @USE_NLS@ +USE_RNDEGD_FALSE = @USE_RNDEGD_FALSE@ +USE_RNDEGD_TRUE = @USE_RNDEGD_TRUE@ +USE_RNDLINUX_FALSE = @USE_RNDLINUX_FALSE@ +USE_RNDLINUX_TRUE = @USE_RNDLINUX_TRUE@ +USE_RNDUNIX_FALSE = @USE_RNDUNIX_FALSE@ +USE_RNDUNIX_TRUE = @USE_RNDUNIX_TRUE@ +USE_RNDW32_FALSE = @USE_RNDW32_FALSE@ +USE_RNDW32_TRUE = @USE_RNDW32_TRUE@ +USE_SHA512_FALSE = @USE_SHA512_FALSE@ +USE_SHA512_TRUE = @USE_SHA512_TRUE@ +USE_SIMPLE_GETTEXT_FALSE = @USE_SIMPLE_GETTEXT_FALSE@ +USE_SIMPLE_GETTEXT_TRUE = @USE_SIMPLE_GETTEXT_TRUE@ +VERSION = @VERSION@ +W32LIBS = @W32LIBS@ +WORKING_FAQPROG_FALSE = @WORKING_FAQPROG_FALSE@ +WORKING_FAQPROG_TRUE = @WORKING_FAQPROG_TRUE@ +XGETTEXT = @XGETTEXT@ +ZLIBS = @ZLIBS@ +_libcurl_config = @_libcurl_config@ +_usb_config = @_usb_config@ +ac_ct_CC = @ac_ct_CC@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +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@ +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 = @localedir@ +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@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl +EXTRA_SCRIPTS = gpgkeys_mailto +gpglibexecdir = $(libexecdir)/@PACKAGE@ +gpglibexec_SCRIPTS = @GPGKEYS_MAILTO@ +noinst_SCRIPTS = gpgkeys_test +gpgkeys_ldap_SOURCES = gpgkeys_ldap.c ksutil.c ksutil.h +gpgkeys_hkp_SOURCES = gpgkeys_hkp.c ksutil.c ksutil.h $(am__append_2) +gpgkeys_finger_SOURCES = gpgkeys_finger.c ksutil.c ksutil.h +gpgkeys_curl_SOURCES = gpgkeys_curl.c ksutil.c ksutil.h \ + $(am__append_1) +other_libs = $(LIBICONV) $(LIBINTL) $(CAPLIBS) +gpgkeys_ldap_CPPFLAGS = @LDAP_CPPFLAGS@ +gpgkeys_ldap_LDADD = ../util/libcompat.a @LDAPLIBS@ @NETLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ +gpgkeys_finger_LDADD = ../util/libutil.a @NETLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ +@FAKE_CURL_FALSE@gpgkeys_curl_LDADD = @LIBCURL@ @GETOPT@ +@FAKE_CURL_TRUE@gpgkeys_curl_LDADD = ../util/libutil.a @NETLIBS@ @DNSLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ +@FAKE_CURL_FALSE@gpgkeys_hkp_LDADD = @LIBCURL@ @GETOPT@ +@FAKE_CURL_TRUE@gpgkeys_hkp_LDADD = ../util/libutil.a @NETLIBS@ @DNSLIBS@ $(other_libs) @GETOPT@ @W32LIBS@ +@FAKE_CURL_FALSE@gpgkeys_curl_CPPFLAGS = @LIBCURL_CPPFLAGS@ +@FAKE_CURL_FALSE@gpgkeys_hkp_CPPFLAGS = @LIBCURL_CPPFLAGS@ +@FAKE_CURL_FALSE@gpgkeys_finger_CPPFLAGS = @LIBCURL_CPPFLAGS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu keyserver/Makefile'; \ + 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 +gpgkeys_mailto: $(top_builddir)/config.status $(srcdir)/gpgkeys_mailto.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +gpgkeys_test: $(top_builddir)/config.status $(srcdir)/gpgkeys_test.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-gpglibexecPROGRAMS: $(gpglibexec_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(gpglibexecdir)" || $(mkdir_p) "$(DESTDIR)$(gpglibexecdir)" + @list='$(gpglibexec_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(gpglibexecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(gpglibexecdir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(gpglibexecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(gpglibexecdir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-gpglibexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(gpglibexec_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(gpglibexecdir)/$$f'"; \ + rm -f "$(DESTDIR)$(gpglibexecdir)/$$f"; \ + done + +clean-gpglibexecPROGRAMS: + -test -z "$(gpglibexec_PROGRAMS)" || rm -f $(gpglibexec_PROGRAMS) + +installcheck-gpglibexecPROGRAMS: $(gpglibexec_PROGRAMS) + bad=0; pid=$$$$; list="$(gpglibexec_PROGRAMS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | \ + sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + for opt in --help --version; do \ + if "$(DESTDIR)$(gpglibexecdir)/$$f" $$opt >c$${pid}_.out \ + 2>c$${pid}_.err </dev/null \ + && test -n "`cat c$${pid}_.out`" \ + && test -z "`cat c$${pid}_.err`"; then :; \ + else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad +gpgkeys_curl$(EXEEXT): $(gpgkeys_curl_OBJECTS) $(gpgkeys_curl_DEPENDENCIES) + @rm -f gpgkeys_curl$(EXEEXT) + $(LINK) $(gpgkeys_curl_LDFLAGS) $(gpgkeys_curl_OBJECTS) $(gpgkeys_curl_LDADD) $(LIBS) +gpgkeys_finger$(EXEEXT): $(gpgkeys_finger_OBJECTS) $(gpgkeys_finger_DEPENDENCIES) + @rm -f gpgkeys_finger$(EXEEXT) + $(LINK) $(gpgkeys_finger_LDFLAGS) $(gpgkeys_finger_OBJECTS) $(gpgkeys_finger_LDADD) $(LIBS) +gpgkeys_hkp$(EXEEXT): $(gpgkeys_hkp_OBJECTS) $(gpgkeys_hkp_DEPENDENCIES) + @rm -f gpgkeys_hkp$(EXEEXT) + $(LINK) $(gpgkeys_hkp_LDFLAGS) $(gpgkeys_hkp_OBJECTS) $(gpgkeys_hkp_LDADD) $(LIBS) +gpgkeys_ldap$(EXEEXT): $(gpgkeys_ldap_OBJECTS) $(gpgkeys_ldap_DEPENDENCIES) + @rm -f gpgkeys_ldap$(EXEEXT) + $(LINK) $(gpgkeys_ldap_LDFLAGS) $(gpgkeys_ldap_OBJECTS) $(gpgkeys_ldap_LDADD) $(LIBS) +install-gpglibexecSCRIPTS: $(gpglibexec_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(gpglibexecdir)" || $(mkdir_p) "$(DESTDIR)$(gpglibexecdir)" + @list='$(gpglibexec_SCRIPTS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f $$d$$p; then \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " $(gpglibexecSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(gpglibexecdir)/$$f'"; \ + $(gpglibexecSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(gpglibexecdir)/$$f"; \ + else :; fi; \ + done + +uninstall-gpglibexecSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(gpglibexec_SCRIPTS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " rm -f '$(DESTDIR)$(gpglibexecdir)/$$f'"; \ + rm -f "$(DESTDIR)$(gpglibexecdir)/$$f"; \ + done + +installcheck-gpglibexecSCRIPTS: $(gpglibexec_SCRIPTS) + bad=0; pid=$$$$; list="$(gpglibexec_SCRIPTS)"; for p in $$list; do \ + case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \ + *" $$p "* | *" $(srcdir)/$$p "*) continue;; \ + esac; \ + f=`echo "$$p" | sed 's,^.*/,,;$(transform)'`; \ + for opt in --help --version; do \ + if "$(DESTDIR)$(gpglibexecdir)/$$f" $$opt >c$${pid}_.out \ + 2>c$${pid}_.err </dev/null \ + && test -n "`cat c$${pid}_.out`" \ + && test -z "`cat c$${pid}_.err`"; then :; \ + else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \ + done; \ + done; rm -f c$${pid}_.???; exit $$bad + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_curl-curl-shim.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_curl-ksutil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_finger-ksutil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_hkp-curl-shim.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_hkp-ksutil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgkeys_ldap-ksutil.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@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@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@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) '$<'` + +gpgkeys_curl-gpgkeys_curl.o: gpgkeys_curl.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_curl-gpgkeys_curl.o -MD -MP -MF "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Tpo" -c -o gpgkeys_curl-gpgkeys_curl.o `test -f 'gpgkeys_curl.c' || echo '$(srcdir)/'`gpgkeys_curl.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Tpo" "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Po"; else rm -f "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_curl.c' object='gpgkeys_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) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_curl-gpgkeys_curl.o `test -f 'gpgkeys_curl.c' || echo '$(srcdir)/'`gpgkeys_curl.c + +gpgkeys_curl-gpgkeys_curl.obj: gpgkeys_curl.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_curl-gpgkeys_curl.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Tpo" -c -o gpgkeys_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@ then mv -f "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Tpo" "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Po"; else rm -f "$(DEPDIR)/gpgkeys_curl-gpgkeys_curl.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_curl.c' object='gpgkeys_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) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_curl-gpgkeys_curl.obj `if test -f 'gpgkeys_curl.c'; then $(CYGPATH_W) 'gpgkeys_curl.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_curl.c'; fi` + +gpgkeys_curl-ksutil.o: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_curl-ksutil.o -MD -MP -MF "$(DEPDIR)/gpgkeys_curl-ksutil.Tpo" -c -o gpgkeys_curl-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_curl-ksutil.Tpo" "$(DEPDIR)/gpgkeys_curl-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_curl-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_curl-ksutil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_curl-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c + +gpgkeys_curl-ksutil.obj: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_curl-ksutil.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_curl-ksutil.Tpo" -c -o gpgkeys_curl-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_curl-ksutil.Tpo" "$(DEPDIR)/gpgkeys_curl-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_curl-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_curl-ksutil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_curl-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi` + +gpgkeys_curl-curl-shim.o: curl-shim.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_curl-curl-shim.o -MD -MP -MF "$(DEPDIR)/gpgkeys_curl-curl-shim.Tpo" -c -o gpgkeys_curl-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_curl-curl-shim.Tpo" "$(DEPDIR)/gpgkeys_curl-curl-shim.Po"; else rm -f "$(DEPDIR)/gpgkeys_curl-curl-shim.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpgkeys_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) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_curl-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c + +gpgkeys_curl-curl-shim.obj: curl-shim.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_curl-curl-shim.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_curl-curl-shim.Tpo" -c -o gpgkeys_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@ then mv -f "$(DEPDIR)/gpgkeys_curl-curl-shim.Tpo" "$(DEPDIR)/gpgkeys_curl-curl-shim.Po"; else rm -f "$(DEPDIR)/gpgkeys_curl-curl-shim.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpgkeys_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) $(gpgkeys_curl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_curl-curl-shim.obj `if test -f 'curl-shim.c'; then $(CYGPATH_W) 'curl-shim.c'; else $(CYGPATH_W) '$(srcdir)/curl-shim.c'; fi` + +gpgkeys_finger-gpgkeys_finger.o: gpgkeys_finger.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_finger-gpgkeys_finger.o -MD -MP -MF "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Tpo" -c -o gpgkeys_finger-gpgkeys_finger.o `test -f 'gpgkeys_finger.c' || echo '$(srcdir)/'`gpgkeys_finger.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Tpo" "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Po"; else rm -f "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_finger.c' object='gpgkeys_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) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_finger-gpgkeys_finger.o `test -f 'gpgkeys_finger.c' || echo '$(srcdir)/'`gpgkeys_finger.c + +gpgkeys_finger-gpgkeys_finger.obj: gpgkeys_finger.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_finger-gpgkeys_finger.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Tpo" -c -o gpgkeys_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@ then mv -f "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Tpo" "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Po"; else rm -f "$(DEPDIR)/gpgkeys_finger-gpgkeys_finger.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_finger.c' object='gpgkeys_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) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_finger-gpgkeys_finger.obj `if test -f 'gpgkeys_finger.c'; then $(CYGPATH_W) 'gpgkeys_finger.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_finger.c'; fi` + +gpgkeys_finger-ksutil.o: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_finger-ksutil.o -MD -MP -MF "$(DEPDIR)/gpgkeys_finger-ksutil.Tpo" -c -o gpgkeys_finger-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_finger-ksutil.Tpo" "$(DEPDIR)/gpgkeys_finger-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_finger-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_finger-ksutil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_finger-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c + +gpgkeys_finger-ksutil.obj: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_finger-ksutil.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_finger-ksutil.Tpo" -c -o gpgkeys_finger-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_finger-ksutil.Tpo" "$(DEPDIR)/gpgkeys_finger-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_finger-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_finger-ksutil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_finger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_finger-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi` + +gpgkeys_hkp-gpgkeys_hkp.o: gpgkeys_hkp.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_hkp-gpgkeys_hkp.o -MD -MP -MF "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Tpo" -c -o gpgkeys_hkp-gpgkeys_hkp.o `test -f 'gpgkeys_hkp.c' || echo '$(srcdir)/'`gpgkeys_hkp.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Tpo" "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Po"; else rm -f "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_hkp.c' object='gpgkeys_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) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_hkp-gpgkeys_hkp.o `test -f 'gpgkeys_hkp.c' || echo '$(srcdir)/'`gpgkeys_hkp.c + +gpgkeys_hkp-gpgkeys_hkp.obj: gpgkeys_hkp.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_hkp-gpgkeys_hkp.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Tpo" -c -o gpgkeys_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@ then mv -f "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Tpo" "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Po"; else rm -f "$(DEPDIR)/gpgkeys_hkp-gpgkeys_hkp.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_hkp.c' object='gpgkeys_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) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_hkp-gpgkeys_hkp.obj `if test -f 'gpgkeys_hkp.c'; then $(CYGPATH_W) 'gpgkeys_hkp.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_hkp.c'; fi` + +gpgkeys_hkp-ksutil.o: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_hkp-ksutil.o -MD -MP -MF "$(DEPDIR)/gpgkeys_hkp-ksutil.Tpo" -c -o gpgkeys_hkp-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_hkp-ksutil.Tpo" "$(DEPDIR)/gpgkeys_hkp-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_hkp-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_hkp-ksutil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_hkp-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c + +gpgkeys_hkp-ksutil.obj: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_hkp-ksutil.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_hkp-ksutil.Tpo" -c -o gpgkeys_hkp-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_hkp-ksutil.Tpo" "$(DEPDIR)/gpgkeys_hkp-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_hkp-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_hkp-ksutil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_hkp-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi` + +gpgkeys_hkp-curl-shim.o: curl-shim.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_hkp-curl-shim.o -MD -MP -MF "$(DEPDIR)/gpgkeys_hkp-curl-shim.Tpo" -c -o gpgkeys_hkp-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_hkp-curl-shim.Tpo" "$(DEPDIR)/gpgkeys_hkp-curl-shim.Po"; else rm -f "$(DEPDIR)/gpgkeys_hkp-curl-shim.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpgkeys_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) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_hkp-curl-shim.o `test -f 'curl-shim.c' || echo '$(srcdir)/'`curl-shim.c + +gpgkeys_hkp-curl-shim.obj: curl-shim.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_hkp-curl-shim.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_hkp-curl-shim.Tpo" -c -o gpgkeys_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@ then mv -f "$(DEPDIR)/gpgkeys_hkp-curl-shim.Tpo" "$(DEPDIR)/gpgkeys_hkp-curl-shim.Po"; else rm -f "$(DEPDIR)/gpgkeys_hkp-curl-shim.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curl-shim.c' object='gpgkeys_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) $(gpgkeys_hkp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_hkp-curl-shim.obj `if test -f 'curl-shim.c'; then $(CYGPATH_W) 'curl-shim.c'; else $(CYGPATH_W) '$(srcdir)/curl-shim.c'; fi` + +gpgkeys_ldap-gpgkeys_ldap.o: gpgkeys_ldap.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_ldap-gpgkeys_ldap.o -MD -MP -MF "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Tpo" -c -o gpgkeys_ldap-gpgkeys_ldap.o `test -f 'gpgkeys_ldap.c' || echo '$(srcdir)/'`gpgkeys_ldap.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Tpo" "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Po"; else rm -f "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_ldap.c' object='gpgkeys_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) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_ldap-gpgkeys_ldap.o `test -f 'gpgkeys_ldap.c' || echo '$(srcdir)/'`gpgkeys_ldap.c + +gpgkeys_ldap-gpgkeys_ldap.obj: gpgkeys_ldap.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_ldap-gpgkeys_ldap.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Tpo" -c -o gpgkeys_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@ then mv -f "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Tpo" "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Po"; else rm -f "$(DEPDIR)/gpgkeys_ldap-gpgkeys_ldap.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpgkeys_ldap.c' object='gpgkeys_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) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_ldap-gpgkeys_ldap.obj `if test -f 'gpgkeys_ldap.c'; then $(CYGPATH_W) 'gpgkeys_ldap.c'; else $(CYGPATH_W) '$(srcdir)/gpgkeys_ldap.c'; fi` + +gpgkeys_ldap-ksutil.o: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_ldap-ksutil.o -MD -MP -MF "$(DEPDIR)/gpgkeys_ldap-ksutil.Tpo" -c -o gpgkeys_ldap-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_ldap-ksutil.Tpo" "$(DEPDIR)/gpgkeys_ldap-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_ldap-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_ldap-ksutil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_ldap-ksutil.o `test -f 'ksutil.c' || echo '$(srcdir)/'`ksutil.c + +gpgkeys_ldap-ksutil.obj: ksutil.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpgkeys_ldap-ksutil.obj -MD -MP -MF "$(DEPDIR)/gpgkeys_ldap-ksutil.Tpo" -c -o gpgkeys_ldap-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gpgkeys_ldap-ksutil.Tpo" "$(DEPDIR)/gpgkeys_ldap-ksutil.Po"; else rm -f "$(DEPDIR)/gpgkeys_ldap-ksutil.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ksutil.c' object='gpgkeys_ldap-ksutil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gpgkeys_ldap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpgkeys_ldap-ksutil.obj `if test -f 'ksutil.c'; then $(CYGPATH_W) 'ksutil.c'; else $(CYGPATH_W) '$(srcdir)/ksutil.c'; fi` +uninstall-info-am: + +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; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + 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; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + 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; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && 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)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$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)$(gpglibexecdir)" "$(DESTDIR)$(gpglibexecdir)"; 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) + +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-gpglibexecPROGRAMS 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 + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-gpglibexecPROGRAMS install-gpglibexecSCRIPTS + +install-info: install-info-am + +install-man: + +installcheck-am: installcheck-gpglibexecPROGRAMS \ + installcheck-gpglibexecSCRIPTS + +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-gpglibexecPROGRAMS uninstall-gpglibexecSCRIPTS \ + uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-gpglibexecPROGRAMS 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-exec install-exec-am \ + install-gpglibexecPROGRAMS install-gpglibexecSCRIPTS \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installcheck-gpglibexecPROGRAMS \ + installcheck-gpglibexecSCRIPTS installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-gpglibexecPROGRAMS \ + uninstall-gpglibexecSCRIPTS uninstall-info-am + +# 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..f4fdc0c --- /dev/null +++ b/keyserver/curl-shim.c @@ -0,0 +1,322 @@ +/* curl-shim.c - Implement a small subset of the curl API in terms of + * the iobuf HTTP API + * + * Copyright (C) 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include "http.h" +#include "util.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) +{ + return CURLE_OK; +} + +void +curl_global_cleanup(void) {} + +CURL * +curl_easy_init(void) +{ + CURL *handle; + + handle=calloc(1,sizeof(CURL)); + if(handle) + handle->errors=stderr; + + return handle; +} + +void +curl_easy_cleanup(CURL *curl) +{ + 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,unsigned int); + break; + case CURLOPT_POSTFIELDS: + curl->postfields=va_arg(ap,char *); + break; + case CURLOPT_FAILONERROR: + curl->flags.failonerror=va_arg(ap,unsigned int); + break; + case CURLOPT_VERBOSE: + curl->flags.verbose=va_arg(ap,unsigned int); + break; + case CURLOPT_STDERR: + curl->errors=va_arg(ap,FILE *); + 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"); + + if(curl->flags.post) + { + rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,curl->auth,0,proxy); + if(rc==0) + { + char content_len[50]; + unsigned int post_len=strlen(curl->postfields); + + iobuf_writestr(curl->hd.fp_write, + "Content-Type: application/x-www-form-urlencoded\r\n"); + sprintf(content_len,"Content-Length: %u\r\n",post_len); + + iobuf_writestr(curl->hd.fp_write,content_len); + + http_start_data(&curl->hd); + iobuf_write(curl->hd.fp_write,curl->postfields,post_len); + rc=http_wait_response(&curl->hd,&curl->status); + if(rc==0 && curl->flags.failonerror && curl->status>=300) + err=CURLE_HTTP_RETURNED_ERROR; + } + } + else + { + rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,curl->auth,0,proxy); + if(rc==0) + { + rc=http_wait_response(&curl->hd,&curl->status); + if(rc==0) + { + if(curl->flags.failonerror && curl->status>=300) + err=CURLE_HTTP_RETURNED_ERROR; + else + { + unsigned int maxlen=1024,buflen,len; + byte *line=NULL; + + while((len=iobuf_read_line(curl->hd.fp_read, + &line,&buflen,&maxlen))) + { + size_t ret; + + maxlen=1024; + + ret=(curl->writer)(line,len,1,curl->file); + if(ret!=len) + { + err=CURLE_WRITE_ERROR; + break; + } + } + + xfree(line); + http_close(&curl->hd); + } + } + else + http_close(&curl->hd); + } + } + + switch(rc) + { + case 0: + break; + + case G10ERR_INVALID_URI: + err=CURLE_UNSUPPORTED_PROTOCOL; + break; + + case G10ERR_NETWORK: + errstr=strerror(errno); + err=CURLE_COULDNT_CONNECT; + break; + + default: + errstr=g10_errstr(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",(unsigned char)str[idx]); + strcpy(&enc[enc_idx],numbuf); + enc_idx+=3; + } + } + + enc[enc_idx]='\0'; + + return enc; +} + +void +curl_free(char *ptr) +{ + free(ptr); +} diff --git a/keyserver/curl-shim.h b/keyserver/curl-shim.h new file mode 100644 index 0000000..91eac9d --- /dev/null +++ b/keyserver/curl-shim.h @@ -0,0 +1,92 @@ +/* curl-shim.h + * Copyright (C) 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef _CURL_SHIM_H_ +#define _CURL_SHIM_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 + } 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; + unsigned int status; + FILE *errors; + struct + { + unsigned int post:1; + unsigned int failonerror:1; + unsigned int verbose:1; + } flags; + struct http_context hd; +} CURL; + +#define CURL_ERROR_SIZE 256 +#define CURL_GLOBAL_DEFAULT 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); +void curl_free(char *ptr); +#define curl_version() "GnuPG curl-shim "VERSION + +#endif /* !_CURL_SHIM_H_ */ diff --git a/keyserver/gpgkeys_curl.c b/keyserver/gpgkeys_curl.c new file mode 100644 index 0000000..192f9ba --- /dev/null +++ b/keyserver/gpgkeys_curl.c @@ -0,0 +1,380 @@ +/* gpgkeys_curl.c - fetch a key via libcurl + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * 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\thelp\n"); + fprintf (fp,"-V\tversion\n"); + fprintf (fp,"-o\toutput to this file\n"); +} + +int +main(int argc,char *argv[]) +{ + int arg,ret=KEYSERVER_INTERNAL_ERROR; + char line[MAX_LINE]; + char *thekey=NULL; + long follow_redirects=5; + char *proxy=NULL; + + console=stderr; + + /* Kludge to implement standard GNU options. */ + if (argc > 1 && !strcmp (argv[1], "--version")) + { + fputs ("gpgkeys_curl (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,"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; + } + + if(follow_redirects) + { + curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1); + 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,1); + } + + curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,opt->flags.check_cert); + curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); + + 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); + + 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..c91022c --- /dev/null +++ b/keyserver/gpgkeys_finger.c @@ -0,0 +1,534 @@ +/* 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#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 _WIN32 +#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" + +#ifdef _WIN32 +#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; + +#ifdef _WIN32 +static void +deinit_sockets (void) +{ + WSACleanup(); +} + +static void +init_sockets (void) +{ + static int initialized; + static WSADATA wsdata; + + if (initialized) + return; + + if (WSAStartup (0x0101, &wsdata) ) + { + fprintf (console, "error initializing socket library: ec=%d\n", + (int)WSAGetLastError () ); + return; + } + if (wsdata.wVersion < 0x0001) + { + fprintf (console, "socket library version is %x.%x - but 1.1 needed\n", + LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion)); + WSACleanup(); + return; + } + atexit (deinit_sockets); + initialized = 1; +} +#endif /*_WIN32*/ + + +/* 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 _WIN32 + struct hostent *hp; + struct sockaddr_in addr; + unsigned long l; + + 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 _WIN32 + 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 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\thelp\n"); + fprintf (fp,"-V\tversion\n"); + fprintf (fp,"-o\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..e393b85 --- /dev/null +++ b/keyserver/gpgkeys_hkp.c @@ -0,0 +1,854 @@ +/* gpgkeys_hkp.c - talk to an HKP keyserver + * Copyright (C) 2001, 2002, 2003, 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * 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 char errorbuffer[CURL_ERROR_SIZE]; + +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); +} + +int +send_key(int *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. */ + *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); + *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=malloc(8+strlen(encoded_key)+1); + if(!key) + { + fprintf(console,"gpgkeys: out of memory\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + strcpy(key,"keytext="); + strcat(key,encoded_key); + + strcpy(request,"http://"); + strcat(request,opt->host); + strcat(request,":"); + if(opt->port) + strcat(request,opt->port); + else + strcat(request,"11371"); + 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,1); + curl_easy_setopt(curl,CURLOPT_POSTFIELDS,key); + curl_easy_setopt(curl,CURLOPT_FAILONERROR,1); + + 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: + free(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+60]; + char *offset; + struct curl_writer_ctx ctx; + + 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,"http://"); + strcat(request,opt->host); + strcat(request,":"); + if(opt->port) + strcat(request,opt->port); + else + strcat(request,"11371"); + strcat(request,opt->path); + /* request is MAX_URL+55 bytes long - MAX_URL covers the whole URL, + including any supplied path. The 60 overcovers this /pks/... etc + string plus the 8 bytes of key id */ + append_path(request,"/pks/lookup?op=get&options=mr&search=0x"); + + /* fingerprint or long key id. Take the last 8 characters and treat + it like a short key id */ + if(strlen(getkey)>8) + offset=&getkey[strlen(getkey)-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=malloc(MAX_URL+60+strlen(searchkey_encoded)); + if(!request) + { + fprintf(console,"gpgkeys: out of memory\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + fprintf(output,"NAME %s BEGIN\n",getkey); + + strcpy(request,"http://"); + strcat(request,opt->host); + strcat(request,":"); + if(opt->port) + strcat(request,opt->port); + else + strcat(request,"11371"); + strcat(request,opt->path); + append_path(request,"/pks/lookup?op=get&options=mr&search="); + strcat(request,searchkey_encoded); + + if(opt->action==KS_GETNAME) + strcat(request,"&exact=on"); + + 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); + free(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; + + 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; + } + + request=malloc(MAX_URL+60+strlen(searchkey_encoded)); + if(!request) + { + fprintf(console,"gpgkeys: out of memory\n"); + ret=KEYSERVER_NO_MEMORY; + goto fail; + } + + fprintf(output,"SEARCH %s BEGIN\n",searchkey); + + strcpy(request,"http://"); + strcat(request,opt->host); + strcat(request,":"); + if(opt->port) + strcat(request,opt->port); + else + strcat(request,"11371"); + strcat(request,opt->path); + append_path(request,"/pks/lookup?op=index&options=mr&search="); + + /* HKP keyservers like the 0x to be present when searching by + keyid */ + if(search_type==KS_SEARCH_KEYID_SHORT || search_type==KS_SEARCH_KEYID_LONG) + strcat(request,"0x"); + + strcat(request,searchkey_encoded); + + if(search_type!=KS_SEARCH_SUBSTR) + strcat(request,"&exact=on"); + + 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); + free(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; + } +} + +static void +show_help (FILE *fp) +{ + fprintf (fp,"-h\thelp\n"); + fprintf (fp,"-V\tversion\n"); + fprintf (fp,"-o\toutput to this file\n"); +} + +int +main(int argc,char *argv[]) +{ + int arg,ret=KEYSERVER_INTERNAL_ERROR; + char line[MAX_LINE]; + int failed=0; + struct keylist *keylist=NULL,*keyptr=NULL; + char *proxy=NULL; + + console=stderr; + + /* Kludge to implement standard GNU options. */ + if (argc > 1 && !strcmp (argv[1], "--version")) + { + fputs ("gpgkeys_hkp (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; + 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]); + } + } + } +#if 0 + else if(strcasecmp(start,"try-dns-srv")==0) + { + if(no) + http_flags&=~HTTP_FLAG_TRY_SRV; + else + http_flags|=HTTP_FLAG_TRY_SRV; + } +#endif + continue; + } + } + + 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; + } + + 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,1); + } + + if(proxy) + curl_easy_setopt(curl,CURLOPT_PROXY,proxy); + +#if 0 + /* By suggested convention, if the user gives a :port, then disable + SRV. */ + if(opt->port) + http_flags&=~HTTP_FLAG_TRY_SRV; +#endif + + /* 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 eof=0; + + do + { + set_timeout(opt->timeout); + + if(send_key(&eof)!=KEYSERVER_OK) + failed++; + } + while(!eof); + } + 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); + + if(curl) + curl_easy_cleanup(curl); + + free(proxy); + + return ret; +} diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c new file mode 100644 index 0000000..1cc27f4 --- /dev/null +++ b/keyserver/gpgkeys_ldap.c @@ -0,0 +1,2368 @@ +/* gpgkeys_ldap.c - talk to a LDAP keyserver + * Copyright (C) 2001, 2002, 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * 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 "compat.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 (strcmp("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 (strcmp("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 (strcmp("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]) + { + if((userid[i]=hextobyte(&tok[1]))==-1) + userid[i]='?'; + + 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(strcmp("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 *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. */ + *eof=1; + ret=KEYSERVER_OK; + goto fail; + } + + if(strlen(keyid)!=16) + { + *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); + *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. */ + *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); + *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: + /* Unwind and free the whole modlist structure */ + for(ml=modlist;*ml;ml++) + { + free_mod_values(*ml); + free(*ml); + } + + free(modlist); + free(addlist); + free(dn); + + if(ret!=0 && begin) + fprintf(output,"KEY %s FAILED %d\n",keyid,ret); + + return ret; +} + +static int +send_key_keyserver(int *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. */ + *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); + *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",(unsigned char)*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; + 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 search[2+1+9+1+3+(MAX_LINE*3)+3+1+15+14+1+1+20]; + char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled", + "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp", + "pgpkeysize","pgpkeytype",NULL}; + enum ks_search_type search_type; + + 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; + } + + ldap_quote(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); + 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\thelp\n"); + fprintf (fp,"-V\tversion\n"); + fprintf (fp,"-o\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(ldap,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=0; + + do + { + set_timeout(opt->timeout); + + if(real_ldap) + { + if(send_key(&eof)!=KEYSERVER_OK) + failed++; + } + else + { + if(send_key_keyserver(&eof)!=KEYSERVER_OK) + failed++; + } + } + while(!eof); + } + 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+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 "*" */ + if(*searchkey) + searchkey[strlen(searchkey)-1]='\0'; + + if(search_key(searchkey)!=KEYSERVER_OK) + failed++; + + free(searchkey); + } + else + assert (!"invalid 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/gpgkeys_mailto.in b/keyserver/gpgkeys_mailto.in new file mode 100755 index 0000000..e37f5c0 --- /dev/null +++ b/keyserver/gpgkeys_mailto.in @@ -0,0 +1,225 @@ +#!@PERL@ -w + +# gpgkeys_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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +use Getopt::Std; +$Getopt::Std::STANDARD_HELP_VERSION=1; +$sendmail="@SENDMAIL@ -t"; + +### + +sub VERSION_MESSAGE () +{ + print STDOUT "gpgkeys_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"; +} + +($login,$name)=(getpwuid($<))[0,6]; + +$from="$name <$login>"; + +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--; + } + } +} + +$program="(unknown)" if(!defined($program)); + +if(!defined($address)) +{ + print STDERR "gpgkeys: no address provided\n"; + exit(1); +} + +# decode $address + +($address,$args)=split(/\?/,$address); + +if(defined($args)) +{ + @pairs = split(/&/, $args); + foreach $pair (@pairs) + { + ($hdr, $val) = split(/=/, $pair); + $hdr =~ tr/+/ /; + $hdr =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; + $val =~ tr/+/ /; + $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; +# we only handle "from" right now + if($hdr=~/^from$/i) + { + $from=$val; + last; + } + } +} + +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/gpgkeys_test.in b/keyserver/gpgkeys_test.in new file mode 100755 index 0000000..97748cd --- /dev/null +++ b/keyserver/gpgkeys_test.in @@ -0,0 +1,99 @@ +#!@PERL@ + +# gpgkeys_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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +use Getopt::Std; +$Getopt::Std::STANDARD_HELP_VERSION=1; + +$|=1; + +sub VERSION_MESSAGE () +{ + print STDOUT "gpgkeys_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/ksutil.c b/keyserver/ksutil.c new file mode 100644 index 0000000..23dbc8f --- /dev/null +++ b/keyserver/ksutil.c @@ -0,0 +1,564 @@ +/* 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * 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_LIBCURL +#include <curl/curl.h> +#else +#include "curl-shim.h" +#endif +#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 */ + +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=strdup(&start[13]); + 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++; + } +} + +#define HEX "abcdefABCDEF1234567890" + +/* Return what sort of item is being searched for. *search is + permuted to remove any special indicators of a search type. */ +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,HEX"x")==10) + { + (*search)+=2; + return KS_SEARCH_KEYID_SHORT; + } + else if(strlen(*search)==18 && strspn(*search,HEX"x")==18) + { + (*search)+=2; + return KS_SEARCH_KEYID_LONG; + } + } + /* fall through */ + default: + /* Try and recognize a key ID. This isn't exact (it's possible + that a user ID string happens to be 8 or 16 digits of hex), + but it's extremely unlikely. Plus the main GPG program does + this also, and consistency is good. */ + + if(strlen(*search)==8 && strspn(*search,HEX)==8) + return KS_SEARCH_KEYID_SHORT; + else if(strlen(*search)==16 && strspn(*search,HEX)==16) + return KS_SEARCH_KEYID_LONG; + + /* Last resort */ + 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; + } +} diff --git a/keyserver/ksutil.h b/keyserver/ksutil.h new file mode 100644 index 0000000..3affc06 --- /dev/null +++ b/keyserver/ksutil.h @@ -0,0 +1,141 @@ +/* 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * 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); + +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); + +#endif /* !_KSUTIL_H_ */ |