diff --git a/dirmngr/ChangeLog-2011 b/dirmngr/ChangeLog-2011 index 84cf55288..a793a33fc 100644 --- a/dirmngr/ChangeLog-2011 +++ b/dirmngr/ChangeLog-2011 @@ -1583,8 +1583,813 @@ Please note that earlier entries are found in the top level ChangeLog. - [Update after merge with GnuPG: see ./ChangeLog.1] + [Update after merge with GnuPG: These old ChangeLog entries are + found below up to ==END OLDEST CHANGELOG==] +==BEGIN OLDEST CHANGELOG== + +2004-10-04 Werner Koch + + * src/dirmngr.c: Changed an help entry description. + +2004-09-30 Werner Koch + + * src/dirmngr.c (i18n_init): Always use LC_ALL. + +2004-09-28 Werner Koch + + Released 0.5.6. + + * config.guess, config.sub: Updated. + +2004-06-21 Werner Koch + + * src/crlfetch.c (crl_fetch): Bad hack to use the right attribute. + +2004-05-13 Werner Koch + + Released 0.5.5. + + * src/ldap.c (start_cert_fetch_ldap, start_cert_fetch_ldap): More + detailed error messages. + + * src/crlcache.c (update_dir): Handle i-records properly. + +2004-04-29 Werner Koch + + Released 0.5.4. + + * src/crlcache.h (crl_cache_result_t): Add CRL_CACHE_CANTUSE. + * src/server.c (cmd_isvalid): Handle it here. + * src/crlcache.c (crl_cache_isvalid): Issue this code if the CRL + cant be used. + (open_dir): Parse new fields 8,9 and 10 as well as the invalid flag. + (write_dir_line_crl): Write new fields. + (get_crl_number, get_auth_key_id): New. + (crl_cache_insert): Fill new fields. Mark the entry invalid if + the CRL is too old after an update or an unknown critical + extension was seen. + (list_one_crl_entry): Print the new fields. + +2004-04-28 Werner Koch + + * configure.ac: Requires libksba 0.9.6. + + * src/dirmngr.c: New option --ocsp-signer. + * src/dirmngr.h (opt): Renamed member OCSP_REPONDERS to + OCSP_RESPONDER and made ist a simple string. Add OCSP_SIGNER. + * src/ocsp.c (ocsp_isvalid): Changed it accordingly. + (ocsp_isvalid): Pass the ocsp_signer to check_signature. + (check_signature): New arg SIGNER_FPR. Use it to retrieve the + certificate. Factored out common code to .. + (check_signature_core): .. New. + +2004-04-27 Werner Koch + + * src/server.c (start_command_handler): Keep track of the first + connection. + (dirmngr_tick): New. + * src/ldap.c (attr_fetch_fun_reader): Call it from time to time. + +2004-04-23 Werner Koch + + * src/dirmngr.c (main): Removed the add-servers option from the + gpgconf list. It is not really useful. + +2004-04-02 Thomas Schwinge + + * autogen.sh: Added ACLOCAL_FLAGS. + +2004-04-13 Werner Koch + + * src/crlcache.c (update_dir): Do not double close FPOUT. + +2004-04-09 Werner Koch + + * src/cdblib.c (cdb_make_start): Wipeout the entire buffer to + shutup valgrind. + (ewrite): Fixed writing bad data on EINTR. + + * src/ldap.c (get_attr_from_result_ldap): Fixed bad copy and + terminate of a string. + + * src/crlfetch.c (crl_fetch): Fixed freeing of VALUE on error. + +2004-04-07 Werner Koch + + * src/dirmngr.h (server_control_s): Add member force_crl_refresh. + * src/server.c (option_handler): New. + (start_command_handler): Register option handler + * src/crlcache.c (crl_cache_isvalid): Add arg FORCE_REFRESH. + (crl_cache_insert): Record last refresh in memory. + + * src/server.c (inquire_cert_and_load_crl): Renamed from + inquire_cert. + +2004-04-06 Werner Koch + + Released 0.5.3 + + * doc/dirmngr.texi: Updated. + * doc/texinfo.tex: Updated. + +2004-04-05 Werner Koch + + * src/ocsp.c (ocsp_isvalid): Check THIS_UPDATE. + + * src/misc.c (add_isotime): New. + (date2jd, jd2date, days_per_month, days_per_year): New. Taken from + my ancient (1988) code used in Wedit (time2.c). + +2004-04-02 Werner Koch + + * autogen.sh: Check gettext version. + * configure.ac: Add AM_GNU_GETTEXT. + +2004-04-02 gettextize + + * Makefile.am (SUBDIRS): Add intl. + (EXTRA_DIST): Add config.rpath. + * configure.ac (AC_CONFIG_FILES): Add intl/Makefile, + +2004-04-02 Werner Koch + + Add i18n at most places. + + * src/dirmngr.c (i18n_init): New. + (main): Call it. + * src/dirmngr.h: Add i18n stuff. + +2004-04-01 Werner Koch + + * src/misc.c (get_fingerprint_hexstring): New. + + * src/server.c (dirmngr_status): New. + +2004-03-26 Werner Koch + + * configure.ac: Add AC_SYS_LARGEFILE. + + * doc/dirmngr.texi: Changed the license to the GPL as per message + by Mathhias Kalle Dalheimer of Klaralvdalens-Datakonsult dated + Jan 7, 2004. + * doc/fdl.texi: Removed. + +2004-03-25 Werner Koch + + * src/dirmngr.c (main): New command --fetch-crl. + +2004-03-23 Werner Koch + + * src/dirmngr.c: New option --allow-ocsp. + * src/server.c (cmd_isvalid): Make use of allow_ocsp. + +2004-03-17 Werner Koch + + * src/dirmngr.c (main) : Fixed default value quoting. + +2004-03-16 Werner Koch + + * src/dirmngr.c (main): Add ocsp-responder to the gpgconf list. + Add option --debug-level. + (set_debug): New. + +2004-03-15 Werner Koch + + * src/misc.c (canon_sexp_to_grcy): New. + +2004-03-12 Werner Koch + + * src/crlfetch.c (crl_fetch): Hack to substitute http for https. + +2004-03-10 Werner Koch + + * src/dirmngr.c (parse_ldapserver_file): Don't skip the entire + file on errors. + +2004-03-09 Werner Koch + + * src/dirmngr.c (my_ksba_hash_buffer): New. + (main): Initialize the internal libksba hashing. + + * src/server.c (get_issuer_cert_local): Renamed to ... + (get_cert_local): ... this. Changed all callers. Allow NULL for + ISSUER to return the current target cert. + (get_issuing_cert_local): New. + (do_get_cert_local): Moved common code to here. + +2004-03-06 Werner Koch + + Released 0.5.2. + + * configure.ac: Fixed last change to check the API version of + libgcrypt. + +2004-03-05 Werner Koch + + * configure.ac: Also check the SONAME of libgcrypt. + +2004-03-03 Werner Koch + + * src/dirmngr.c: New option --ocsp-responder. + * src/dirmngr.h (opt): Add member OCSP_RESPONDERS. + +2004-02-26 Steffen Hansen + + * src/server.c (start_command_handler): Corrected typo and made + dirmngr output it's version in the greeting message. + +2004-02-24 Marcus Brinkmann + + * src/dirmngr.c (DEFAULT_ADD_SERVERS): Removed. If this were + true, there'd be no way to disable it. + (main): Dump options in new gpgconf format. + +2004-02-11 Werner Koch + + * autogen.sh (check_version): Removed bashism and simplified. + +2004-02-06 Moritz Schulte + + * src/crlfetch.c (crl_fetch_default): Do not dereference VALUE, + when checking for non-zero. + +2004-02-01 Marcus Brinkmann + + * src/dirmngr.c (DEFAULT_ADD_SERVERS, DEFAULT_MAX_REPLIES) + (DEFAULT_LDAP_TIMEOUT): New macros. + (main): Use them. + (enum cmd_and_opt_values): New command aGPGConfList. + (main): Add handler here. + +2004-01-17 Werner Koch + + * configure.ac: Added AC_CHECK_FUNCS tests again, because the + other test occurrences belong to the jnlib tests block. + +2004-01-15 Moritz Schulte + + * configure.ac: Fixed funopen replacement mechanism; removed + unnecessary AC_CHECK_FUNCS calls. + +2004-01-14 Werner Koch + + * src/crlcache.c (list_one_crl_entry): Don't use putchar. + + * src/server.c (cmd_listcrls): New. + +2003-12-23 Werner Koch + + Released 0.5.1. + +2003-12-17 Werner Koch + + * configure.ac (CFLAGS): Add -Wformat-noliteral in gcc + + maintainer mode. + (NEED_LIBASSUAN_VERSION): Bump up to 0.6.2. + +2003-12-16 Werner Koch + + * configure.ac: Update the tests for jnlib. + * src/dirmngr.c (main): Ignore SIGPIPE in server mode. + +2003-12-12 Werner Koch + + * src/crlcache.c (hash_dbfile): Also hash version info of the + cache file format. + + * src/Makefile.am (dirmngr_SOURCES): Add http.h. + + * configure.ac: Removed checking for DB2. Add checking for mmap. + * src/cdb.h, src/cdblib.h: New. Add a few comments from the + original man page and fixed typos. + * src/cdblib.c (cdb_findinit, cdb_findnext): Modified to allow + walking over all entries. + * src/crlcache.h: Removed DB2/4 cruft. + (release_one_cache_entry, lock_db_file, crl_parse_insert) + (crl_cache_insert, crl_cache_isvalid, list_one_crl_entry): Use the + new CDB interface. + + * src/dirmngr.c: Beautified the help messages. + (wrong_args): New. + (main): new option --force. Revamped the command handling code. + Allow to pass multiple CRLS as well as stdin to --local-crl. + * src/crlcache.c (crl_cache_insert): Make --force work. + +2003-12-11 Werner Koch + + * src/crlfetch.c (crl_fetch): Enhanced to allow fetching binary + data using HTTP. + * src/http.c, src/http.h: Replaced by the code from gnupg 1.3 and + modified acording to our needs. + (read_line): New. Based on the code from GnuPG's iobuf_read_line. + * configure.ac: Check for getaddrinfo. + + * src/dirmngr.c (parse_ldapserver_file): Close the stream. + (main): Free ldapfile. + + * src/ocsp.c, src/ocsp.h: New. Albeit not functionality. + + * src/server.c (inquire_cert): Catch EOF when reading dist points. + + * src/crlcache.c (hash_dbfile, check_dbfile): New. + (lock_db_file, crl_cache_insert): Use them here to detect + corrupted CRL files. + (open_dir): Read the new dbfile hash field. + + * src/crlfetch.c (crl_fetch, crl_fetch_default): Changed to retrun + a stream. + (fun_reader, fun_closer, setup_funopen): New. + * src/server.c (inquire_cert): Changed to use the new stream interface + of crlfetch.c. + +2003-12-10 Werner Koch + + * src/funopen.c: New. + * configure.ac (funopen): Add test. + * src/Makefile.am (dirmngr_LDADD): Add LIBOBJS. + + * src/crlcache.c (next_line_from_file): Remove the limit on the + line length. + (crl_cache_new): Removed. + (open_dbcontent): New. + (crl_cache_init): Use it here. + (crl_cache_flush): The DB content fie is now in the cache + directory, so we can simplify it. + (make_db_file_name, lock_db_file, unlock_db_file): New. + (release_cache): Close the cached DB files. + (crl_cache_isvalid): Make use of the new lock_db_file. + (crl_cache_insert): Changed to take a stream as argument. + (crl_parse_insert): Rewritten to use a temporary DB and to avoid + using up large amounts of memory. + (db_entry_new): Removed. + (release_cache,release_one_cache_entry): Splitted up. + (find_entry): Take care of the new deleted flag. + (crl_cache_load): Simplified becuase we can now pass a FP to the + insert code. + (save_contents): Removed. + (update_dir): New. + (open_dbcontent_file): Renamed to open_dir_file. + (check_dbcontent_version): Renamed to check_dir_version. + (open_dbcontent): Renamed to open_dir. + + * src/dirmngr.c: New option --faked-system-time. + * src/misc.c (faked_time_p, set_time, get_time): New. Taken from GnuPG. + (check_isotime): New. + (unpercent_string): New. + +2003-12-09 Werner Koch + + * src/crlcache.h (DBDIR,DBCONTENTFILE): Changed value. + + * autogen.sh: Reworked. + * README.CVS: New. + * configure.ac: Added min_automake_version. + +2003-12-03 Werner Koch + + * src/server.c (cmd_lookup): Send an END line after each + certificate. + +2003-11-28 Werner Koch + + * src/Makefile.am (dirmngr_LDADD): Remove DB_LIBS + because it never got defined and -ldb{2,4} is implictly set + by the AC_CHECK_LIB test in configure. + + * src/crlcache.c (mydbopen): DB4 needs an extra parameter; I + wonder who ever tested DB4 support. Add an error statement in + case no DB support is configured. + + * tests/Makefile.am: Don't use AM_CPPFLAGS but AM_CFLAGS, replaced + variables by configure templates. + * src/Makefile.am: Ditto. + +2003-11-19 Werner Koch + + * src/crlcache.c (list_one_crl_entry): Define X to nothing for non + DB4 systems. Thanks to Luca M. G. Centamore. + +2003-11-17 Werner Koch + + Released 0.5.0 + + * src/crlcache.c (crl_cache_new): Fixed eof detection. + + * src/server.c (cmd_loadcrl): Do the unescaping. + + * doc/dirmngr.texi: Added a history section for this modified + version. + +2003-11-14 Werner Koch + + * tests/asschk.c: New. Taken from GnuPG. + * tests/Makefile.am: Added asschk. + +2003-11-13 Werner Koch + + * src/ldap.c (fetch_next_cert_ldap): Get the pattern switching + right. + + * tests/test-dirmngr.c: Replaced a couple of deprecated types. + + * configure.ac (GPG_ERR_SOURCE_DEFAULT): Added. + (fopencookie, asprintf): Removed unneeded test. + (PRINTABLE_OS_NAME): Updated the test from gnupg. + (CFLAGS): Do full warnings only in maintainer mode. Add flag + --enable gcc-warnings to override it and to enable even more + warnings. + * acinclude.m4: Removed the libgcrypt test. + + * src/ldap.c (get_attr_from_result_ldap): Simplified the binary + hack and return a proper gpg error. + (attr_fetch_ldap_internal): Changed error handling. + (attr_fetch_ldap): Reworked. Return configuration error if no + servers are configured. + (url_fetch_ldap, add_server_to_servers) + (url_fetch_ldap_internal): Reworked. + (struct cert_fetch_context_s): New to get rid of a global state. + (start_cert_fetch_ldap): Allocate context and do a bind with a + timeout. Parse pattern. + (end_cert_fetch_ldap): Take context and don't return anything. + (find_next_pattern): Removed. + (parse_one_pattern): Redone. + (get_cert_ldap): Redone. + * src/server.c (cmd_lookup): Changed for changed fetch functions. + + * doc/dirmngr.texi: Reworked a bit to get rid of tex errors. + + * configure.ac: Enable makeinfo test. + + * src/crlcache.c (crl_cache_insert): Fixed for latest KSBA API + changes. + * tests/test-dirmngr.c (main): Ditto. Also added some more error + checking. + +2003-11-11 Werner Koch + + * src/cert.c (hashify_data, hexify_data, serial_hex) + (serial_to_buffer): Moved all to ... + * src/misc.c: .. here. + * src/Makefile.am (cert.c, cert.h): Removed. + * cert.c, cert.h: Removed. + + * m4/: New. + * configure.ac, Makefile.am: Include m4 directory support, updated + required library versions. + + * src/cert.c (make_cert): Removed. + + * src/ldap.c (fetch_next_cert_ldap): Return a gpg style error. + + * src/misc.h (copy_time): New. + * src/misc.c (get_isotime): New. + (iso_string2time, iso_time2string): Removed. + (unhexify): New. + + * src/crlcache.h (DBCONTENTSVERSION): Bumbed to 0.6. + * src/crlcache.c (finish_sig_check): New. Factored out from + crl_parse_insert and entirely redone. + (do_encode_md): Removed. + (print_time): Removed + (crl_cache_isvalid): Reworked. + +2003-11-10 Werner Koch + + * src/crlcache.c (make_db_val, parse_db_val): Removed. + + * src/cert.c (serial_to_buffer): New. + + * src/server.c (get_issuer_cert_local): Rewritten. + + * src/crlcache.c (crl_parse_insert): Rewritten. Takes now a CTRL + instead of the Assuan context. Changed caller accordingly. + (get_issuer_cert): Cleaned up. + + * src/crlfetch.c (crl_fetch): Changed VALUE to unsigned char* for + documentation reasons. Make sure that VALUE is released on error. + (crl_fetch_default, ca_cert_fetch): Ditto. + + * src/crlcache.c (release_cache): New. + (crl_cache_deinit): Use it here. + (crl_cache_flush): Redone. + (save_contents): Redone. + (crl_cache_list, list_one_crl_entry): Print error messages. + +2003-11-06 Werner Koch + + * src/crlcache.c (create_directory_if_needed, cleanup_cache_dir): + New. Factored out from crl_cache_new and mostly rewritten. + (crl_cache_new): Rewritten. + (next_line_from_file): New. + (find_entry): Cleaned up. + (crl_cache_deinit): Cleaned up. + + * src/dirmngr.c (dirmngr_init_default_ctrl): New stub. + * src/dirmngr.h (ctrl_t): New. + (DBG_ASSUAN,...): Added the usual debug test macros. + * src/server.c: Removed the GET_PTR cruft, replaced it by ctrl_t. + Removed the recursion flag. + (get_issuer_cert_local): Allow for arbitary large + certificates. 4096 is definitely too small. + (inquire_cert): Ditto. + (start_command_handler): Set a hello line and call the default + init function. + (cmd_isvalid): Rewritten. + (inquire_cert): Removed unused arg LINE. General cleanup. + (map_assuan_err,map_to_assuan_status): New. Taken from gnupg 1.9. + (cmd_lookup): Rewritten. + (cmd_loadcrl): Started to rewrite it. + +2003-10-29 Werner Koch + + * src/dirmngr.c (parse_ldapserver_file): Entirely rewritten. + (cleanup): New. + (main): Cleaned up. + +2003-10-28 Werner Koch + + * src/dirmngr.h: Renamed dirmngr_opt to opt. + + * src/dirmngr.c (parse_ldapserver_file, free_ldapservers_list): + Moved with this file. Cleaned up. Replaced too deep recursion in + the free function. + +2003-10-21 Werner Koch + + Changed all occurrences of assuan.h to use use the system provided + one. + * src/server.c (register_commands): Adjusted for Assuan API change. + +2003-08-14 Werner Koch + + * src/Makefile.am: s/LIBKSBA_/KSBA_/. Changed for external Assuan lib. + * tests/Makefile.am: Ditto. + + * configure.ac: Partly restructured, add standard checks for + required libraries, removed included libassuan. + * Makefile.am (SUBDIRS): Removed assuan becuase we now use the + libassuan package. + + * src/dirmngr.c (main): Properly initialize Libgcrypt and libksba. + +2003-08-13 Werner Koch + + * src/server.c (get_issuer_cert_local): Print error using + assuan_strerror. + + * src/crlcache.c (do_encode_md, start_sig_check): Adjust for + changed Libgcrypt API. + +2003-06-19 Steffen Hansen + + * configure.ac: Upped version to 0.4.7-cvs. + +2003-06-19 Steffen Hansen + + * configure.ac: Release 0.4.6. + +2003-06-17 Bernhard Reiter + + * src/ldap.c (url_fetch_ldap()): + try other default servers when an url with hostname failed + * AUTHORS: added Steffen and Werner + * THANKS: Thanked people in the ChangeLog and the Ägypten-Team + + +2003-06-16 Steffen Hansen + + * configure.ac, src/crlcache.h, src/crlcache.c: Added db4 support. + * src/Makefile.am, tests/Makefile.am: Removed automake warning. + * tests/test-dirmngr.c: Removed a warning. + +2003-05-12 Steffen Hansen + + * doc/Makefile.am: Added dirmngr.ops to DISTCLEANFILES. + * ChangeLog, doc/ChangeLog, src/ChangeLog: Merged dirmngr ChangeLogs + into one toplevel file. + * acinclude.m4, configure.ac: Renamed PFX to PATH for consistency. + +2003-05-12 Steffen Hansen + + * src/ldap.c: Fixed end-of-certificates-list indication. + +2003-05-08 Steffen Hansen + + * src/server.c: Fixed iteration over server list + +2003-02-23 Steffen Hansen + + * src/crlcache.h, src/crlcache.c, src/dirmngr.c: Implemented --flush command. + +2003-02-07 Marcus Brinkmann + + * configure.ac: Release 0.4.4. + +2003-02-05 Steffen Hansen + + * src/ldap.c: Try harder with and without ";binary" in the + attribute name when fetching certificates. + * src/ldap.c, src/server.c: Support multiple userCertificate attributes + per entry. + +2003-02-04 Steffen Hansen + + * src/ldap.c: Include the sn attribute in the search filter. + Better log messages. + +2002-11-20 Steffen Hansen + + * Doc updates (fixes #1373) + * Fix for #1419 (crash in free_ldapservers_list()) + * Fix for #1375. Dirmngr now asks back with an INQUIRE SENDCERT before + querying the LDAP servers for an issuer certificate to validate a CRL + +2002-11-12 Werner Koch + + * config.sub, config.guess: Updated from ftp.gnu.org/gnu/config + to version 2002-11-08. + +2002-11-12 Werner Koch + + * dirmngr.c (main) : Better pass NULL instead + of an unitialized Assuan context. Let's hope that the other + functions can cope with this. + +2002-10-25 Bernhard Reiter + + * src/ldap.c (get_attr_from_result_ldap()): + added value extraction retry for CRLs and Certs without ";binary" + * changed version number to reflect cvs status to "0.4.3-cvs" + +2002-08-21 Werner Koch + + * dirmngr.c (main): Changed default homedir to .gnupg. + +2002-08-07 Steffen Hansen + + * Added configure check to examine whether db2 cursor() uses 3 or + 4 parameters. + +2002-07-31 Werner Koch + + * doc/dirmngr.texi: Fixed the structure and added menu entries + for the other nodes. + +2002-07-30 Steffen Hansen + + * Added doc dir and first steps towards manual. + +2002-07-29 Steffen Hansen + + * Got rid of the default server for CRL lookup. We now use the + same list of servers that we use for cert. lookup. + +2002-07-29 Steffen Hansen + + * New option --add-servers to allow dirmngr to add LDAP servers + found in CRL distribution points to the list of servers it + searches. NOTE: The added servers are only active in the currently + running dirmngr -- the info isn't written to persistens storage. + +2002-07-26 Steffen Hansen + + * Default LDAP timeout is 100 seconds now. + + * Use DB2 instead of DB1. Check for libresolv, fixed bug when + libldap was found in the default search path. + +2002-07-22 Steffen Hansen + + * Implemented --load-crl option. Also available as + LOADCRL assuan command when in server mode. + +2002-07-22 Steffen Hansen + + * Implemented new option --ldaptimeout to specify the number of seconds to + wait for an LDAP request before timeout. + + * Added --list-crls option to print the contents of the CRL cache + * Added some items to the dbcontents file to make printout nicer + and updated it's version number + +2002-07-02 Werner Koch + + * crlcache.c (crl_parse_insert): Fixed log_debug format string. + +2002-07-02 Steffen Hansen + + * configure.ac: Use DB->get() return value correctly. + +2002-06-28 Werner Koch + + * crlcache.c (crl_parse_insert): Keep track of newly allocated + ENTRY so that we don't free existing errors after a bad signature. + + * dirmngr.h: Include prototype for start_command_handler. + + * crlfetch.c, crlcache.c, http.c, cert.c, ldap.c: Include + config.h. + + * crlcache.c (crl_parse_insert): Fixed format type specifiers for + time_t variables in log_debug. + + * error.h: Use log_debug instead of dirmngr_debug. Changed all + callers. + * Makefile.am (dirmngr_SOURCES): Removed error.c + + * dirmngr.c (main): Register gcrypt malloc functions with ksba so + that we don't run into problems by using the wrong free function. + The gcrypt malloc function have the additional benefit of a + providing allocation sanity checks when compiled with that + feature. + + * crlcache.c (get_issuer_cert): Use xfree instead of ksba_free. + + +2002-06-27 Steffen Hansen + + * ldap.c: Look for both userCertificate and caCertificate + +2002-06-26 Steffen Hansen + + * configure.ac: Upped version number to 0.3.1 + +2002-06-25 Werner Koch + + * server.c (cmd_lookup): Use assuan_write_status which ensures a + correct syntax. + +2002-06-20 Werner Koch + + * crlcache.c (crl_cache_isvalid): Started with some nicer logging. + However, this will need a lot more work. + (get_issuer_cert): Ditto. + + * dirmngr.c (main): Changed required libgcrypt version and don't + print the prefix when using a logfile. + +2002-06-20 Werner Koch + + * tests/Makefile.am (TESTS): Removed test-dirmngr because it + is not a proper test program. + (EXTRA_DIST): Removed the non-existent test certificate. + +2002-05-21 Werner Koch + + * server.c (start_command_handler): Enable assuan debugging. + +2002-05-08 Steffen Hansen + + * Replaced gdbm check with db1 check + +2002-05-08 Steffen Hansen + + * Replaced gdbm with db1, updated file format version + +2002-03-01 Steffen Hansen + + * Added gdbm configure check + +2002-01-23 Steffen Hansen + + * Return ASSUAN_CRL_Too_Old if the CRL is too old + + +2002-01-17 Steffen Hansen + + Added commandline options --ldapserver --ldapport + --ldapuser --ldappassword . + + Cleaned up CRL parsing, signature evaluation a bit, changed + datetime format in config file to ISO, added version string to + contents format and cache file clean up code in case of mismatch. + +2002-01-14 Steffen Hansen + + * Use dirmngr_opt.homedir for storing the db. Added Makefile.am to + tests, bugfixes. + + * First code. + Things that work: + Loading/saving database (paths hardcoded) + Fetching CRL from hardcoded server, parsing and inserting in database + Answer ISVALID xxx.yyy requests + + Things that are missing: + Some error-checking/handling + Proper autoconf handling of gdbm and OpenLDAP + Signature checking downloaded CRLs + Answer LOOKUP requests + ... + + How to test: + cd tests + ldapsearch -v -x -h www.trustcenter.de -b '' userCertificate -t + cp /tmp/ testcert.der + ./test-dirmngr + +==END OLDEST CHANGELOG== Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. diff --git a/keyserver/ChangeLog-2011 b/dirmngr/ChangeLog-2011-ks similarity index 99% rename from keyserver/ChangeLog-2011 rename to dirmngr/ChangeLog-2011-ks index 01cca41c3..b41955e7e 100644 --- a/keyserver/ChangeLog-2011 +++ b/dirmngr/ChangeLog-2011-ks @@ -1,3 +1,7 @@ +[ This is the ChangeLog from the former keyserver/ directory which + kept the old gpgkeys_* keyserver access helpers. We keep it here + to document the history of certain keyserver relates features. ] + 2011-12-01 Werner Koch NB: ChangeLog files are no longer manually maintained. Starting diff --git a/dirmngr/ChangeLog.1 b/dirmngr/ChangeLog.1 deleted file mode 100644 index f7b50c7a1..000000000 --- a/dirmngr/ChangeLog.1 +++ /dev/null @@ -1,806 +0,0 @@ -There are old Dirmngr ChangeLog entries. - -2004-10-04 Werner Koch - - * src/dirmngr.c: Changed an help entry description. - -2004-09-30 Werner Koch - - * src/dirmngr.c (i18n_init): Always use LC_ALL. - -2004-09-28 Werner Koch - - Released 0.5.6. - - * config.guess, config.sub: Updated. - -2004-06-21 Werner Koch - - * src/crlfetch.c (crl_fetch): Bad hack to use the right attribute. - -2004-05-13 Werner Koch - - Released 0.5.5. - - * src/ldap.c (start_cert_fetch_ldap, start_cert_fetch_ldap): More - detailed error messages. - - * src/crlcache.c (update_dir): Handle i-records properly. - -2004-04-29 Werner Koch - - Released 0.5.4. - - * src/crlcache.h (crl_cache_result_t): Add CRL_CACHE_CANTUSE. - * src/server.c (cmd_isvalid): Handle it here. - * src/crlcache.c (crl_cache_isvalid): Issue this code if the CRL - cant be used. - (open_dir): Parse new fields 8,9 and 10 as well as the invalid flag. - (write_dir_line_crl): Write new fields. - (get_crl_number, get_auth_key_id): New. - (crl_cache_insert): Fill new fields. Mark the entry invalid if - the CRL is too old after an update or an unknown critical - extension was seen. - (list_one_crl_entry): Print the new fields. - -2004-04-28 Werner Koch - - * configure.ac: Requires libksba 0.9.6. - - * src/dirmngr.c: New option --ocsp-signer. - * src/dirmngr.h (opt): Renamed member OCSP_REPONDERS to - OCSP_RESPONDER and made ist a simple string. Add OCSP_SIGNER. - * src/ocsp.c (ocsp_isvalid): Changed it accordingly. - (ocsp_isvalid): Pass the ocsp_signer to check_signature. - (check_signature): New arg SIGNER_FPR. Use it to retrieve the - certificate. Factored out common code to .. - (check_signature_core): .. New. - -2004-04-27 Werner Koch - - * src/server.c (start_command_handler): Keep track of the first - connection. - (dirmngr_tick): New. - * src/ldap.c (attr_fetch_fun_reader): Call it from time to time. - -2004-04-23 Werner Koch - - * src/dirmngr.c (main): Removed the add-servers option from the - gpgconf list. It is not really useful. - -2004-04-02 Thomas Schwinge - - * autogen.sh: Added ACLOCAL_FLAGS. - -2004-04-13 Werner Koch - - * src/crlcache.c (update_dir): Do not double close FPOUT. - -2004-04-09 Werner Koch - - * src/cdblib.c (cdb_make_start): Wipeout the entire buffer to - shutup valgrind. - (ewrite): Fixed writing bad data on EINTR. - - * src/ldap.c (get_attr_from_result_ldap): Fixed bad copy and - terminate of a string. - - * src/crlfetch.c (crl_fetch): Fixed freeing of VALUE on error. - -2004-04-07 Werner Koch - - * src/dirmngr.h (server_control_s): Add member force_crl_refresh. - * src/server.c (option_handler): New. - (start_command_handler): Register option handler - * src/crlcache.c (crl_cache_isvalid): Add arg FORCE_REFRESH. - (crl_cache_insert): Record last refresh in memory. - - * src/server.c (inquire_cert_and_load_crl): Renamed from - inquire_cert. - -2004-04-06 Werner Koch - - Released 0.5.3 - - * doc/dirmngr.texi: Updated. - * doc/texinfo.tex: Updated. - -2004-04-05 Werner Koch - - * src/ocsp.c (ocsp_isvalid): Check THIS_UPDATE. - - * src/misc.c (add_isotime): New. - (date2jd, jd2date, days_per_month, days_per_year): New. Taken from - my ancient (1988) code used in Wedit (time2.c). - -2004-04-02 Werner Koch - - * autogen.sh: Check gettext version. - * configure.ac: Add AM_GNU_GETTEXT. - -2004-04-02 gettextize - - * Makefile.am (SUBDIRS): Add intl. - (EXTRA_DIST): Add config.rpath. - * configure.ac (AC_CONFIG_FILES): Add intl/Makefile, - -2004-04-02 Werner Koch - - Add i18n at most places. - - * src/dirmngr.c (i18n_init): New. - (main): Call it. - * src/dirmngr.h: Add i18n stuff. - -2004-04-01 Werner Koch - - * src/misc.c (get_fingerprint_hexstring): New. - - * src/server.c (dirmngr_status): New. - -2004-03-26 Werner Koch - - * configure.ac: Add AC_SYS_LARGEFILE. - - * doc/dirmngr.texi: Changed the license to the GPL as per message - by Mathhias Kalle Dalheimer of Klaralvdalens-Datakonsult dated - Jan 7, 2004. - * doc/fdl.texi: Removed. - -2004-03-25 Werner Koch - - * src/dirmngr.c (main): New command --fetch-crl. - -2004-03-23 Werner Koch - - * src/dirmngr.c: New option --allow-ocsp. - * src/server.c (cmd_isvalid): Make use of allow_ocsp. - -2004-03-17 Werner Koch - - * src/dirmngr.c (main) : Fixed default value quoting. - -2004-03-16 Werner Koch - - * src/dirmngr.c (main): Add ocsp-responder to the gpgconf list. - Add option --debug-level. - (set_debug): New. - -2004-03-15 Werner Koch - - * src/misc.c (canon_sexp_to_grcy): New. - -2004-03-12 Werner Koch - - * src/crlfetch.c (crl_fetch): Hack to substitute http for https. - -2004-03-10 Werner Koch - - * src/dirmngr.c (parse_ldapserver_file): Don't skip the entire - file on errors. - -2004-03-09 Werner Koch - - * src/dirmngr.c (my_ksba_hash_buffer): New. - (main): Initialize the internal libksba hashing. - - * src/server.c (get_issuer_cert_local): Renamed to ... - (get_cert_local): ... this. Changed all callers. Allow NULL for - ISSUER to return the current target cert. - (get_issuing_cert_local): New. - (do_get_cert_local): Moved common code to here. - -2004-03-06 Werner Koch - - Released 0.5.2. - - * configure.ac: Fixed last change to check the API version of - libgcrypt. - -2004-03-05 Werner Koch - - * configure.ac: Also check the SONAME of libgcrypt. - -2004-03-03 Werner Koch - - * src/dirmngr.c: New option --ocsp-responder. - * src/dirmngr.h (opt): Add member OCSP_RESPONDERS. - -2004-02-26 Steffen Hansen - - * src/server.c (start_command_handler): Corrected typo and made - dirmngr output it's version in the greeting message. - -2004-02-24 Marcus Brinkmann - - * src/dirmngr.c (DEFAULT_ADD_SERVERS): Removed. If this were - true, there'd be no way to disable it. - (main): Dump options in new gpgconf format. - -2004-02-11 Werner Koch - - * autogen.sh (check_version): Removed bashism and simplified. - -2004-02-06 Moritz Schulte - - * src/crlfetch.c (crl_fetch_default): Do not dereference VALUE, - when checking for non-zero. - -2004-02-01 Marcus Brinkmann - - * src/dirmngr.c (DEFAULT_ADD_SERVERS, DEFAULT_MAX_REPLIES) - (DEFAULT_LDAP_TIMEOUT): New macros. - (main): Use them. - (enum cmd_and_opt_values): New command aGPGConfList. - (main): Add handler here. - -2004-01-17 Werner Koch - - * configure.ac: Added AC_CHECK_FUNCS tests again, because the - other test occurrences belong to the jnlib tests block. - -2004-01-15 Moritz Schulte - - * configure.ac: Fixed funopen replacement mechanism; removed - unnecessary AC_CHECK_FUNCS calls. - -2004-01-14 Werner Koch - - * src/crlcache.c (list_one_crl_entry): Don't use putchar. - - * src/server.c (cmd_listcrls): New. - -2003-12-23 Werner Koch - - Released 0.5.1. - -2003-12-17 Werner Koch - - * configure.ac (CFLAGS): Add -Wformat-noliteral in gcc + - maintainer mode. - (NEED_LIBASSUAN_VERSION): Bump up to 0.6.2. - -2003-12-16 Werner Koch - - * configure.ac: Update the tests for jnlib. - * src/dirmngr.c (main): Ignore SIGPIPE in server mode. - -2003-12-12 Werner Koch - - * src/crlcache.c (hash_dbfile): Also hash version info of the - cache file format. - - * src/Makefile.am (dirmngr_SOURCES): Add http.h. - - * configure.ac: Removed checking for DB2. Add checking for mmap. - * src/cdb.h, src/cdblib.h: New. Add a few comments from the - original man page and fixed typos. - * src/cdblib.c (cdb_findinit, cdb_findnext): Modified to allow - walking over all entries. - * src/crlcache.h: Removed DB2/4 cruft. - (release_one_cache_entry, lock_db_file, crl_parse_insert) - (crl_cache_insert, crl_cache_isvalid, list_one_crl_entry): Use the - new CDB interface. - - * src/dirmngr.c: Beautified the help messages. - (wrong_args): New. - (main): new option --force. Revamped the command handling code. - Allow to pass multiple CRLS as well as stdin to --local-crl. - * src/crlcache.c (crl_cache_insert): Make --force work. - -2003-12-11 Werner Koch - - * src/crlfetch.c (crl_fetch): Enhanced to allow fetching binary - data using HTTP. - * src/http.c, src/http.h: Replaced by the code from gnupg 1.3 and - modified acording to our needs. - (read_line): New. Based on the code from GnuPG's iobuf_read_line. - * configure.ac: Check for getaddrinfo. - - * src/dirmngr.c (parse_ldapserver_file): Close the stream. - (main): Free ldapfile. - - * src/ocsp.c, src/ocsp.h: New. Albeit not functionality. - - * src/server.c (inquire_cert): Catch EOF when reading dist points. - - * src/crlcache.c (hash_dbfile, check_dbfile): New. - (lock_db_file, crl_cache_insert): Use them here to detect - corrupted CRL files. - (open_dir): Read the new dbfile hash field. - - * src/crlfetch.c (crl_fetch, crl_fetch_default): Changed to retrun - a stream. - (fun_reader, fun_closer, setup_funopen): New. - * src/server.c (inquire_cert): Changed to use the new stream interface - of crlfetch.c. - -2003-12-10 Werner Koch - - * src/funopen.c: New. - * configure.ac (funopen): Add test. - * src/Makefile.am (dirmngr_LDADD): Add LIBOBJS. - - * src/crlcache.c (next_line_from_file): Remove the limit on the - line length. - (crl_cache_new): Removed. - (open_dbcontent): New. - (crl_cache_init): Use it here. - (crl_cache_flush): The DB content fie is now in the cache - directory, so we can simplify it. - (make_db_file_name, lock_db_file, unlock_db_file): New. - (release_cache): Close the cached DB files. - (crl_cache_isvalid): Make use of the new lock_db_file. - (crl_cache_insert): Changed to take a stream as argument. - (crl_parse_insert): Rewritten to use a temporary DB and to avoid - using up large amounts of memory. - (db_entry_new): Removed. - (release_cache,release_one_cache_entry): Splitted up. - (find_entry): Take care of the new deleted flag. - (crl_cache_load): Simplified becuase we can now pass a FP to the - insert code. - (save_contents): Removed. - (update_dir): New. - (open_dbcontent_file): Renamed to open_dir_file. - (check_dbcontent_version): Renamed to check_dir_version. - (open_dbcontent): Renamed to open_dir. - - * src/dirmngr.c: New option --faked-system-time. - * src/misc.c (faked_time_p, set_time, get_time): New. Taken from GnuPG. - (check_isotime): New. - (unpercent_string): New. - -2003-12-09 Werner Koch - - * src/crlcache.h (DBDIR,DBCONTENTFILE): Changed value. - - * autogen.sh: Reworked. - * README.CVS: New. - * configure.ac: Added min_automake_version. - -2003-12-03 Werner Koch - - * src/server.c (cmd_lookup): Send an END line after each - certificate. - -2003-11-28 Werner Koch - - * src/Makefile.am (dirmngr_LDADD): Remove DB_LIBS - because it never got defined and -ldb{2,4} is implictly set - by the AC_CHECK_LIB test in configure. - - * src/crlcache.c (mydbopen): DB4 needs an extra parameter; I - wonder who ever tested DB4 support. Add an error statement in - case no DB support is configured. - - * tests/Makefile.am: Don't use AM_CPPFLAGS but AM_CFLAGS, replaced - variables by configure templates. - * src/Makefile.am: Ditto. - -2003-11-19 Werner Koch - - * src/crlcache.c (list_one_crl_entry): Define X to nothing for non - DB4 systems. Thanks to Luca M. G. Centamore. - -2003-11-17 Werner Koch - - Released 0.5.0 - - * src/crlcache.c (crl_cache_new): Fixed eof detection. - - * src/server.c (cmd_loadcrl): Do the unescaping. - - * doc/dirmngr.texi: Added a history section for this modified - version. - -2003-11-14 Werner Koch - - * tests/asschk.c: New. Taken from GnuPG. - * tests/Makefile.am: Added asschk. - -2003-11-13 Werner Koch - - * src/ldap.c (fetch_next_cert_ldap): Get the pattern switching - right. - - * tests/test-dirmngr.c: Replaced a couple of deprecated types. - - * configure.ac (GPG_ERR_SOURCE_DEFAULT): Added. - (fopencookie, asprintf): Removed unneeded test. - (PRINTABLE_OS_NAME): Updated the test from gnupg. - (CFLAGS): Do full warnings only in maintainer mode. Add flag - --enable gcc-warnings to override it and to enable even more - warnings. - * acinclude.m4: Removed the libgcrypt test. - - * src/ldap.c (get_attr_from_result_ldap): Simplified the binary - hack and return a proper gpg error. - (attr_fetch_ldap_internal): Changed error handling. - (attr_fetch_ldap): Reworked. Return configuration error if no - servers are configured. - (url_fetch_ldap, add_server_to_servers) - (url_fetch_ldap_internal): Reworked. - (struct cert_fetch_context_s): New to get rid of a global state. - (start_cert_fetch_ldap): Allocate context and do a bind with a - timeout. Parse pattern. - (end_cert_fetch_ldap): Take context and don't return anything. - (find_next_pattern): Removed. - (parse_one_pattern): Redone. - (get_cert_ldap): Redone. - * src/server.c (cmd_lookup): Changed for changed fetch functions. - - * doc/dirmngr.texi: Reworked a bit to get rid of tex errors. - - * configure.ac: Enable makeinfo test. - - * src/crlcache.c (crl_cache_insert): Fixed for latest KSBA API - changes. - * tests/test-dirmngr.c (main): Ditto. Also added some more error - checking. - -2003-11-11 Werner Koch - - * src/cert.c (hashify_data, hexify_data, serial_hex) - (serial_to_buffer): Moved all to ... - * src/misc.c: .. here. - * src/Makefile.am (cert.c, cert.h): Removed. - * cert.c, cert.h: Removed. - - * m4/: New. - * configure.ac, Makefile.am: Include m4 directory support, updated - required library versions. - - * src/cert.c (make_cert): Removed. - - * src/ldap.c (fetch_next_cert_ldap): Return a gpg style error. - - * src/misc.h (copy_time): New. - * src/misc.c (get_isotime): New. - (iso_string2time, iso_time2string): Removed. - (unhexify): New. - - * src/crlcache.h (DBCONTENTSVERSION): Bumbed to 0.6. - * src/crlcache.c (finish_sig_check): New. Factored out from - crl_parse_insert and entirely redone. - (do_encode_md): Removed. - (print_time): Removed - (crl_cache_isvalid): Reworked. - -2003-11-10 Werner Koch - - * src/crlcache.c (make_db_val, parse_db_val): Removed. - - * src/cert.c (serial_to_buffer): New. - - * src/server.c (get_issuer_cert_local): Rewritten. - - * src/crlcache.c (crl_parse_insert): Rewritten. Takes now a CTRL - instead of the Assuan context. Changed caller accordingly. - (get_issuer_cert): Cleaned up. - - * src/crlfetch.c (crl_fetch): Changed VALUE to unsigned char* for - documentation reasons. Make sure that VALUE is released on error. - (crl_fetch_default, ca_cert_fetch): Ditto. - - * src/crlcache.c (release_cache): New. - (crl_cache_deinit): Use it here. - (crl_cache_flush): Redone. - (save_contents): Redone. - (crl_cache_list, list_one_crl_entry): Print error messages. - -2003-11-06 Werner Koch - - * src/crlcache.c (create_directory_if_needed, cleanup_cache_dir): - New. Factored out from crl_cache_new and mostly rewritten. - (crl_cache_new): Rewritten. - (next_line_from_file): New. - (find_entry): Cleaned up. - (crl_cache_deinit): Cleaned up. - - * src/dirmngr.c (dirmngr_init_default_ctrl): New stub. - * src/dirmngr.h (ctrl_t): New. - (DBG_ASSUAN,...): Added the usual debug test macros. - * src/server.c: Removed the GET_PTR cruft, replaced it by ctrl_t. - Removed the recursion flag. - (get_issuer_cert_local): Allow for arbitary large - certificates. 4096 is definitely too small. - (inquire_cert): Ditto. - (start_command_handler): Set a hello line and call the default - init function. - (cmd_isvalid): Rewritten. - (inquire_cert): Removed unused arg LINE. General cleanup. - (map_assuan_err,map_to_assuan_status): New. Taken from gnupg 1.9. - (cmd_lookup): Rewritten. - (cmd_loadcrl): Started to rewrite it. - -2003-10-29 Werner Koch - - * src/dirmngr.c (parse_ldapserver_file): Entirely rewritten. - (cleanup): New. - (main): Cleaned up. - -2003-10-28 Werner Koch - - * src/dirmngr.h: Renamed dirmngr_opt to opt. - - * src/dirmngr.c (parse_ldapserver_file, free_ldapservers_list): - Moved with this file. Cleaned up. Replaced too deep recursion in - the free function. - -2003-10-21 Werner Koch - - Changed all occurrences of assuan.h to use use the system provided - one. - * src/server.c (register_commands): Adjusted for Assuan API change. - -2003-08-14 Werner Koch - - * src/Makefile.am: s/LIBKSBA_/KSBA_/. Changed for external Assuan lib. - * tests/Makefile.am: Ditto. - - * configure.ac: Partly restructured, add standard checks for - required libraries, removed included libassuan. - * Makefile.am (SUBDIRS): Removed assuan becuase we now use the - libassuan package. - - * src/dirmngr.c (main): Properly initialize Libgcrypt and libksba. - -2003-08-13 Werner Koch - - * src/server.c (get_issuer_cert_local): Print error using - assuan_strerror. - - * src/crlcache.c (do_encode_md, start_sig_check): Adjust for - changed Libgcrypt API. - -2003-06-19 Steffen Hansen - - * configure.ac: Upped version to 0.4.7-cvs. - -2003-06-19 Steffen Hansen - - * configure.ac: Release 0.4.6. - -2003-06-17 Bernhard Reiter - - * src/ldap.c (url_fetch_ldap()): - try other default servers when an url with hostname failed - * AUTHORS: added Steffen and Werner - * THANKS: Thanked people in the ChangeLog and the Ägypten-Team - - -2003-06-16 Steffen Hansen - - * configure.ac, src/crlcache.h, src/crlcache.c: Added db4 support. - * src/Makefile.am, tests/Makefile.am: Removed automake warning. - * tests/test-dirmngr.c: Removed a warning. - -2003-05-12 Steffen Hansen - - * doc/Makefile.am: Added dirmngr.ops to DISTCLEANFILES. - * ChangeLog, doc/ChangeLog, src/ChangeLog: Merged dirmngr ChangeLogs - into one toplevel file. - * acinclude.m4, configure.ac: Renamed PFX to PATH for consistency. - -2003-05-12 Steffen Hansen - - * src/ldap.c: Fixed end-of-certificates-list indication. - -2003-05-08 Steffen Hansen - - * src/server.c: Fixed iteration over server list - -2003-02-23 Steffen Hansen - - * src/crlcache.h, src/crlcache.c, src/dirmngr.c: Implemented --flush command. - -2003-02-07 Marcus Brinkmann - - * configure.ac: Release 0.4.4. - -2003-02-05 Steffen Hansen - - * src/ldap.c: Try harder with and without ";binary" in the - attribute name when fetching certificates. - * src/ldap.c, src/server.c: Support multiple userCertificate attributes - per entry. - -2003-02-04 Steffen Hansen - - * src/ldap.c: Include the sn attribute in the search filter. - Better log messages. - -2002-11-20 Steffen Hansen - - * Doc updates (fixes #1373) - * Fix for #1419 (crash in free_ldapservers_list()) - * Fix for #1375. Dirmngr now asks back with an INQUIRE SENDCERT before - querying the LDAP servers for an issuer certificate to validate a CRL - -2002-11-12 Werner Koch - - * config.sub, config.guess: Updated from ftp.gnu.org/gnu/config - to version 2002-11-08. - -2002-11-12 Werner Koch - - * dirmngr.c (main) : Better pass NULL instead - of an unitialized Assuan context. Let's hope that the other - functions can cope with this. - -2002-10-25 Bernhard Reiter - - * src/ldap.c (get_attr_from_result_ldap()): - added value extraction retry for CRLs and Certs without ";binary" - * changed version number to reflect cvs status to "0.4.3-cvs" - -2002-08-21 Werner Koch - - * dirmngr.c (main): Changed default homedir to .gnupg. - -2002-08-07 Steffen Hansen - - * Added configure check to examine whether db2 cursor() uses 3 or - 4 parameters. - -2002-07-31 Werner Koch - - * doc/dirmngr.texi: Fixed the structure and added menu entries - for the other nodes. - -2002-07-30 Steffen Hansen - - * Added doc dir and first steps towards manual. - -2002-07-29 Steffen Hansen - - * Got rid of the default server for CRL lookup. We now use the - same list of servers that we use for cert. lookup. - -2002-07-29 Steffen Hansen - - * New option --add-servers to allow dirmngr to add LDAP servers - found in CRL distribution points to the list of servers it - searches. NOTE: The added servers are only active in the currently - running dirmngr -- the info isn't written to persistens storage. - -2002-07-26 Steffen Hansen - - * Default LDAP timeout is 100 seconds now. - - * Use DB2 instead of DB1. Check for libresolv, fixed bug when - libldap was found in the default search path. - -2002-07-22 Steffen Hansen - - * Implemented --load-crl option. Also available as - LOADCRL assuan command when in server mode. - -2002-07-22 Steffen Hansen - - * Implemented new option --ldaptimeout to specify the number of seconds to - wait for an LDAP request before timeout. - - * Added --list-crls option to print the contents of the CRL cache - * Added some items to the dbcontents file to make printout nicer - and updated it's version number - -2002-07-02 Werner Koch - - * crlcache.c (crl_parse_insert): Fixed log_debug format string. - -2002-07-02 Steffen Hansen - - * configure.ac: Use DB->get() return value correctly. - -2002-06-28 Werner Koch - - * crlcache.c (crl_parse_insert): Keep track of newly allocated - ENTRY so that we don't free existing errors after a bad signature. - - * dirmngr.h: Include prototype for start_command_handler. - - * crlfetch.c, crlcache.c, http.c, cert.c, ldap.c: Include - config.h. - - * crlcache.c (crl_parse_insert): Fixed format type specifiers for - time_t variables in log_debug. - - * error.h: Use log_debug instead of dirmngr_debug. Changed all - callers. - * Makefile.am (dirmngr_SOURCES): Removed error.c - - * dirmngr.c (main): Register gcrypt malloc functions with ksba so - that we don't run into problems by using the wrong free function. - The gcrypt malloc function have the additional benefit of a - providing allocation sanity checks when compiled with that - feature. - - * crlcache.c (get_issuer_cert): Use xfree instead of ksba_free. - - -2002-06-27 Steffen Hansen - - * ldap.c: Look for both userCertificate and caCertificate - -2002-06-26 Steffen Hansen - - * configure.ac: Upped version number to 0.3.1 - -2002-06-25 Werner Koch - - * server.c (cmd_lookup): Use assuan_write_status which ensures a - correct syntax. - -2002-06-20 Werner Koch - - * crlcache.c (crl_cache_isvalid): Started with some nicer logging. - However, this will need a lot more work. - (get_issuer_cert): Ditto. - - * dirmngr.c (main): Changed required libgcrypt version and don't - print the prefix when using a logfile. - -2002-06-20 Werner Koch - - * tests/Makefile.am (TESTS): Removed test-dirmngr because it - is not a proper test program. - (EXTRA_DIST): Removed the non-existent test certificate. - -2002-05-21 Werner Koch - - * server.c (start_command_handler): Enable assuan debugging. - -2002-05-08 Steffen Hansen - - * Replaced gdbm check with db1 check - -2002-05-08 Steffen Hansen - - * Replaced gdbm with db1, updated file format version - -2002-03-01 Steffen Hansen - - * Added gdbm configure check - -2002-01-23 Steffen Hansen - - * Return ASSUAN_CRL_Too_Old if the CRL is too old - - -2002-01-17 Steffen Hansen - - Added commandline options --ldapserver --ldapport - --ldapuser --ldappassword . - - Cleaned up CRL parsing, signature evaluation a bit, changed - datetime format in config file to ISO, added version string to - contents format and cache file clean up code in case of mismatch. - -2002-01-14 Steffen Hansen - - * Use dirmngr_opt.homedir for storing the db. Added Makefile.am to - tests, bugfixes. - - * First code. - Things that work: - Loading/saving database (paths hardcoded) - Fetching CRL from hardcoded server, parsing and inserting in database - Answer ISVALID xxx.yyy requests - - Things that are missing: - Some error-checking/handling - Proper autoconf handling of gdbm and OpenLDAP - Signature checking downloaded CRLs - Answer LOOKUP requests - ... - - How to test: - cd tests - ldapsearch -v -x -h www.trustcenter.de -b '' userCertificate -t - cp /tmp/ testcert.der - ./test-dirmngr - -Local Variables: -buffer-read-only: t -End: diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index c5713a773..906fe37eb 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -19,7 +19,7 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = OAUTHORS ONEWS ChangeLog.1 ChangeLog-2011 +EXTRA_DIST = OAUTHORS ONEWS ChangeLog-2011 bin_PROGRAMS = dirmngr dirmngr-client diff --git a/keyserver/curl-shim.c b/keyserver/curl-shim.c deleted file mode 100644 index 696efe2c7..000000000 --- a/keyserver/curl-shim.c +++ /dev/null @@ -1,382 +0,0 @@ -/* curl-shim.c - Implement a small subset of the curl API in terms of - * the iobuf HTTP API - * - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "util.h" -#include "http.h" -#include "ksutil.h" -#include "curl-shim.h" - -static CURLcode -handle_error(CURL *curl,CURLcode err,const char *str) -{ - if(curl->errorbuffer) - { - /* Make sure you never exceed CURL_ERROR_SIZE, currently set to - 256 in curl-shim.h */ - switch(err) - { - case CURLE_OK: - strcpy(curl->errorbuffer,"okay"); - break; - - case CURLE_UNSUPPORTED_PROTOCOL: - strcpy(curl->errorbuffer,"unsupported protocol"); - break; - - case CURLE_COULDNT_CONNECT: - strcpy(curl->errorbuffer,"couldn't connect"); - break; - - case CURLE_WRITE_ERROR: - strcpy(curl->errorbuffer,"write error"); - break; - - case CURLE_HTTP_RETURNED_ERROR: - sprintf(curl->errorbuffer,"url returned error %u",curl->status); - break; - - default: - strcpy(curl->errorbuffer,"generic error"); - break; - } - - if(str && (strlen(curl->errorbuffer)+2+strlen(str)+1)<=CURL_ERROR_SIZE) - { - strcat(curl->errorbuffer,": "); - strcat(curl->errorbuffer,str); - } - } - - return err; -} - -CURLcode -curl_global_init(long flags) -{ - (void)flags; - return CURLE_OK; -} - -void -curl_global_cleanup(void) {} - -CURL * -curl_easy_init(void) -{ - CURL *handle; - -#ifdef HAVE_W32_SYSTEM - w32_init_sockets (); -#endif - - handle=calloc(1,sizeof(CURL)); - if(handle) - handle->errors=stderr; - - return handle; -} - -void -curl_easy_cleanup(CURL *curl) -{ - if (curl) - { - http_close (curl->hd, 0); - free(curl); - } -} - -CURLcode -curl_easy_setopt(CURL *curl,CURLoption option,...) -{ - va_list ap; - - va_start(ap,option); - - switch(option) - { - case CURLOPT_URL: - curl->url=va_arg(ap,char *); - break; - case CURLOPT_USERPWD: - curl->auth=va_arg(ap,char *); - break; - case CURLOPT_WRITEFUNCTION: - curl->writer=va_arg(ap,write_func); - break; - case CURLOPT_FILE: - curl->file=va_arg(ap,void *); - break; - case CURLOPT_ERRORBUFFER: - curl->errorbuffer=va_arg(ap,char *); - break; - case CURLOPT_PROXY: - curl->proxy=va_arg(ap,char *); - break; - case CURLOPT_POST: - curl->flags.post=va_arg(ap,long)?1:0; - break; - case CURLOPT_POSTFIELDS: - curl->postfields=va_arg(ap,char *); - break; - case CURLOPT_SRVTAG_GPG_HACK: - curl->srvtag=va_arg(ap,char *); - break; - case CURLOPT_FAILONERROR: - curl->flags.failonerror=va_arg(ap,long)?1:0; - break; - case CURLOPT_VERBOSE: - curl->flags.verbose=va_arg(ap,long)?1:0; - break; - case CURLOPT_STDERR: - curl->errors=va_arg(ap,FILE *); - break; - case CURLOPT_HTTPHEADER: - curl->headers=va_arg(ap,struct curl_slist *); - break; - default: - /* We ignore the huge majority of curl options */ - break; - } - - return handle_error(curl,CURLE_OK,NULL); -} - -CURLcode -curl_easy_perform(CURL *curl) -{ - int rc; - CURLcode err=CURLE_OK; - const char *errstr=NULL; - char *proxy=NULL; - - /* Emulate the libcurl proxy behavior. If the calling program set a - proxy, use it. If it didn't set a proxy or set it to NULL, check - for one in the environment. If the calling program explicitly - set a null-string proxy the http code doesn't use a proxy at - all. */ - - if(curl->proxy) - proxy=curl->proxy; - else - proxy=getenv(HTTP_PROXY_ENV); - - if(curl->flags.verbose) - { - fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null"); - fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url); - fprintf(curl->errors,"* HTTP auth is \"%s\"\n", - curl->auth?curl->auth:"null"); - fprintf(curl->errors,"* HTTP method is %s\n", - curl->flags.post?"POST":"GET"); - } - - if(curl->flags.post) - { - rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, NULL, curl->auth, - 0, proxy, NULL, curl->srvtag, - curl->headers?curl->headers->list:NULL); - if (!rc) - { - unsigned int post_len = strlen(curl->postfields); - - es_fprintf (http_get_write_ptr (curl->hd), - "Content-Type: application/x-www-form-urlencoded\r\n" - "Content-Length: %u\r\n", post_len); - http_start_data (curl->hd); - es_write (http_get_write_ptr (curl->hd), - curl->postfields, post_len, NULL); - - rc = http_wait_response (curl->hd); - curl->status = http_get_status_code (curl->hd); - if (!rc && curl->flags.failonerror && curl->status>=300) - err = CURLE_HTTP_RETURNED_ERROR; - http_close (curl->hd, 0); - curl->hd = NULL; - } - } - else - { - rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, NULL, curl->auth, - 0, proxy, NULL, curl->srvtag, - curl->headers?curl->headers->list:NULL); - if (!rc) - { - rc = http_wait_response (curl->hd); - curl->status = http_get_status_code (curl->hd); - if (!rc) - { - if (curl->flags.failonerror && curl->status>=300) - err = CURLE_HTTP_RETURNED_ERROR; - else - { - size_t maxlen = 1024; - size_t buflen; - unsigned int len; - char *line = NULL; - - while ((len = es_read_line (http_get_read_ptr (curl->hd), - &line, &buflen, &maxlen))) - { - size_t ret; - - maxlen=1024; - - ret=(curl->writer)(line,len,1,curl->file); - if(ret!=len) - { - err=CURLE_WRITE_ERROR; - break; - } - } - - es_free (line); - http_close(curl->hd, 0); - curl->hd = NULL; - } - } - else - { - http_close (curl->hd, 0); - curl->hd = NULL; - } - } - } - - switch(gpg_err_code (rc)) - { - case 0: - break; - - case GPG_ERR_INV_URI: - err=CURLE_UNSUPPORTED_PROTOCOL; - break; - - default: - errstr=gpg_strerror (rc); - err=CURLE_COULDNT_CONNECT; - break; - } - - return handle_error(curl,err,errstr); -} - -/* This is not the same exact set that is allowed according to - RFC-2396, but it is what the real curl uses. */ -#define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ - "0123456789" - -char * -curl_escape(char *str,int length) -{ - int len,max,idx,enc_idx=0; - char *enc; - - if(length) - len=length; - else - len=strlen(str); - - enc=malloc(len+1); - if(!enc) - return enc; - - max=len; - - for(idx=0;idxmax) - { - char *tmp; - - max+=100; - - tmp=realloc(enc,max+1); - if(!tmp) - { - free(enc); - return NULL; - } - - enc=tmp; - } - - if(strchr(VALID_URI_CHARS,str[idx])) - enc[enc_idx++]=str[idx]; - else - { - char numbuf[5]; - sprintf(numbuf,"%%%02X",str[idx]); - strcpy(&enc[enc_idx],numbuf); - enc_idx+=3; - } - } - - enc[enc_idx]='\0'; - - return enc; -} - -curl_version_info_data * -curl_version_info(int type) -{ - static curl_version_info_data data; - static const char *protocols[]={"http",NULL}; - - (void)type; - - data.protocols=protocols; - - return &data; -} - -struct curl_slist * -curl_slist_append(struct curl_slist *list,const char *string) -{ - if(!list) - { - list=calloc(1,sizeof(*list)); - if(!list) - return NULL; - } - - add_to_strlist(&list->list,string); - - return list; -} - -void -curl_slist_free_all(struct curl_slist *list) -{ - if(list) - { - free_strlist(list->list); - free(list); - } -} diff --git a/keyserver/curl-shim.h b/keyserver/curl-shim.h deleted file mode 100644 index 0a11e7cd9..000000000 --- a/keyserver/curl-shim.h +++ /dev/null @@ -1,111 +0,0 @@ -/* curl-shim.h - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _CURL_SHIM_H_ -#define _CURL_SHIM_H_ - -#include "util.h" -#include "http.h" - -typedef enum - { - CURLE_OK=0, - CURLE_UNSUPPORTED_PROTOCOL=1, - CURLE_COULDNT_CONNECT=7, - CURLE_FTP_COULDNT_RETR_FILE=19, - CURLE_HTTP_RETURNED_ERROR=22, - CURLE_WRITE_ERROR=23 - } CURLcode; - -typedef enum - { - CURLOPT_URL, - CURLOPT_USERPWD, - CURLOPT_WRITEFUNCTION, - CURLOPT_FILE, - CURLOPT_ERRORBUFFER, - CURLOPT_FOLLOWLOCATION, - CURLOPT_MAXREDIRS, - CURLOPT_STDERR, - CURLOPT_VERBOSE, - CURLOPT_SSL_VERIFYPEER, - CURLOPT_PROXY, - CURLOPT_CAINFO, - CURLOPT_POST, - CURLOPT_POSTFIELDS, - CURLOPT_FAILONERROR, - CURLOPT_HTTPHEADER, - CURLOPT_SRVTAG_GPG_HACK - } CURLoption; - -typedef size_t (*write_func)(char *buffer,size_t size, - size_t nitems,void *outstream); - -typedef struct -{ - char *url; - char *auth; - char *errorbuffer; - char *proxy; - write_func writer; - void *file; - char *postfields; - char *srvtag; - unsigned int status; - FILE *errors; - struct curl_slist *headers; - struct - { - unsigned int post:1; - unsigned int failonerror:1; - unsigned int verbose:1; - } flags; - http_t hd; -} CURL; - -typedef struct -{ - const char **protocols; -} curl_version_info_data; - -#define CURL_ERROR_SIZE 256 -#define CURL_GLOBAL_DEFAULT 0 -#define CURLVERSION_NOW 0 - -CURLcode curl_global_init(long flags); -void curl_global_cleanup(void); -CURL *curl_easy_init(void); -CURLcode curl_easy_setopt(CURL *curl,CURLoption option,...); -CURLcode curl_easy_perform(CURL *curl); -void curl_easy_cleanup(CURL *curl); -char *curl_escape(char *str,int len); -#define curl_free(x) free(x) -#define curl_version() GNUPG_NAME" curl-shim" -curl_version_info_data *curl_version_info(int type); - -struct curl_slist -{ - strlist_t list; -}; - -struct curl_slist *curl_slist_append(struct curl_slist *list, - const char *string); -void curl_slist_free_all(struct curl_slist *list); - -#endif /* !_CURL_SHIM_H_ */ diff --git a/keyserver/gpg2keys_mailto.in b/keyserver/gpg2keys_mailto.in deleted file mode 100755 index 959f0e7ca..000000000 --- a/keyserver/gpg2keys_mailto.in +++ /dev/null @@ -1,211 +0,0 @@ -#!@PERL@ -w - -# gpg2keys_mailto - talk to a email keyserver -# Copyright (C) 2001, 2002 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -use Getopt::Std; -$Getopt::Std::STANDARD_HELP_VERSION=1; -$sendmail="@SENDMAIL@ -t"; - -### - -sub VERSION_MESSAGE () -{ - print STDOUT "gpg2keys_mailto (GnuPG) @VERSION@\n"; -} - -sub HELP_MESSAGE () -{ - print STDOUT <$opt_o") || die "Can't open output file $opt_o\n"; -} - -if(@ARGV) -{ - open(STDIN,$ARGV[0]) || die "Can't open input file $ARGV[0]\n"; -} - -while() -{ - last if($_ eq "\n"); - - if(/^COMMAND (\S+)/) - { - $command=$1; - } - - if(/^OPAQUE (\S+)/) - { - $address=$1; - } - - if(/^PROGRAM (\S+)/) - { - $program=$1; - } - - if(/^OPTION (\S+)/) - { - if($1=~/^verbose$/i) - { - $verbose++; - } - elsif($1=~/^no-verbose$/i) - { - $verbose--; - } - elsif($1=~/^mail-from=(.+)$/i) - { - $from=$1; - } - elsif($1=~/^no-mail-from$/i) - { - undef $from; - } - - } -} - -if(!defined($from)) -{ - ($login,$name)=(getpwuid($<))[0,6]; - $from="$name <$login>"; -} - -$program="(unknown)" if(!defined($program)); - -if(!defined($address)) -{ - print STDERR "gpgkeys: no address provided\n"; - exit(1); -} - -while() -{ - 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() - { - if(/^KEY (\S+) BEGIN$/) - { - $key=$1; - last; - } - } - - while() - { - if(/^KEY \S+ END$/) - { - last; - } - - print MAIL; - } - - close(MAIL); - - if($verbose) - { - print STDERR "gpgkeys: key $key sent to $address\n"; - } - } -} - - -# Local Variables: -# mode:perl -# End: diff --git a/keyserver/gpg2keys_test.in b/keyserver/gpg2keys_test.in deleted file mode 100755 index 9f2c0b6f7..000000000 --- a/keyserver/gpg2keys_test.in +++ /dev/null @@ -1,97 +0,0 @@ -#!@PERL@ - -# gpg2keys_test - keyserver code tester -# Copyright (C) 2001 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -use Getopt::Std; -$Getopt::Std::STANDARD_HELP_VERSION=1; - -$|=1; - -sub VERSION_MESSAGE () -{ - print STDOUT "gpg2keys_test (GnuPG) @VERSION@\n"; -} - -sub HELP_MESSAGE () -{ - print STDOUT <$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() -{ - last if($_ eq "\n"); - print STDERR "--command-> $_"; - - if(/^COMMAND (\w+)/) - { - $command=$1; - } -} - -# Get the keylist block - -print STDERR "Keylist block:\n"; - -while() -{ - 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() - { - print STDERR "$_"; - } -} - -printf STDERR "gpgkeys_test finished\n"; - -# Local Variables: -# mode:perl -# End: diff --git a/keyserver/gpgkeys_curl.c b/keyserver/gpgkeys_curl.c deleted file mode 100644 index fc4c6f38f..000000000 --- a/keyserver/gpgkeys_curl.c +++ /dev/null @@ -1,419 +0,0 @@ -/* gpgkeys_curl.c - fetch a key via libcurl - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * 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 -#include -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#endif -#ifdef HAVE_LIBCURL -#include -#else -#include "curl-shim.h" -#endif -#include "keyserver.h" -#include "ksutil.h" - -extern char *optarg; -extern int optind; - -static FILE *input,*output,*console; -static CURL *curl; -static struct ks_options *opt; - -static int -get_key(char *getkey) -{ - CURLcode res; - char errorbuffer[CURL_ERROR_SIZE]; - char request[MAX_URL]; - struct curl_writer_ctx ctx; - - memset(&ctx,0,sizeof(ctx)); - - if(strncmp(getkey,"0x",2)==0) - getkey+=2; - - fprintf(output,"KEY 0x%s BEGIN\n",getkey); - - sprintf(request,"%s://%s%s%s%s",opt->scheme,opt->host, - opt->port?":":"",opt->port?opt->port:"",opt->path?opt->path:"/"); - - curl_easy_setopt(curl,CURLOPT_URL,request); - curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer); - ctx.stream=output; - curl_easy_setopt(curl,CURLOPT_FILE,&ctx); - curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer); - - res=curl_easy_perform(curl); - if(res!=CURLE_OK) - { - fprintf(console,"gpgkeys: %s fetch error %d: %s\n",opt->scheme, - res,errorbuffer); - fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res)); - } - else - { - curl_writer_finalize(&ctx); - if(!ctx.flags.done) - { - fprintf(console,"gpgkeys: no key data found for %s\n",request); - fprintf(output,"\nKEY 0x%s FAILED %d\n", - getkey,KEYSERVER_KEY_NOT_FOUND); - } - else - fprintf(output,"\nKEY 0x%s END\n",getkey); - } - - return curl_err_to_gpg_err(res); -} - -static void -show_help (FILE *fp) -{ - fprintf (fp,"-h, --help\thelp\n"); - fprintf (fp,"-V\t\tmachine readable version\n"); - fprintf (fp,"--version\thuman readable version\n"); - fprintf (fp,"-o\t\toutput to this file\n"); -} - -int -main(int argc,char *argv[]) -{ - int arg,ret=KEYSERVER_INTERNAL_ERROR,i; - char line[MAX_LINE]; - char *thekey=NULL; - long follow_redirects=5; - char *proxy=NULL; - curl_version_info_data *curldata; - struct curl_slist *headers=NULL; - - console=stderr; - - /* Kludge to implement standard GNU options. */ - if (argc > 1 && !strcmp (argv[1], "--version")) - { - printf ("gpgkeys_curl (%s) %s\n", GNUPG_NAME, VERSION); - printf ("Uses: %s\n", curl_version()); - return 0; - } - else if (argc > 1 && !strcmp (argv[1], "--help")) - { - show_help (stdout); - return 0; - } - - while((arg=getopt(argc,argv,"hVo:"))!=-1) - switch(arg) - { - default: - case 'h': - show_help (console); - return KEYSERVER_OK; - - case 'V': - fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION); - return KEYSERVER_OK; - - case 'o': - output=fopen(optarg,"wb"); - if(output==NULL) - { - fprintf(console,"gpgkeys: Cannot open output file '%s': %s\n", - optarg,strerror(errno)); - return KEYSERVER_INTERNAL_ERROR; - } - - break; - } - - if(argc>optind) - { - input=fopen(argv[optind],"r"); - if(input==NULL) - { - fprintf(console,"gpgkeys: Cannot open input file '%s': %s\n", - argv[optind],strerror(errno)); - return KEYSERVER_INTERNAL_ERROR; - } - } - - if(input==NULL) - input=stdin; - - if(output==NULL) - output=stdout; - - opt=init_ks_options(); - if(!opt) - return KEYSERVER_NO_MEMORY; - - /* Get the command and info block */ - - while(fgets(line,MAX_LINE,input)!=NULL) - { - int err; - char option[MAX_OPTION+1]; - - if(line[0]=='\n') - break; - - err=parse_ks_options(line,opt); - if(err>0) - { - ret=err; - goto fail; - } - else if(err==0) - continue; - - if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "s\n",option)==1) - { - int no=0; - char *start=&option[0]; - - option[MAX_OPTION]='\0'; - - if(strncasecmp(option,"no-",3)==0) - { - no=1; - start=&option[3]; - } - - if(strncasecmp(start,"http-proxy",10)==0) - { - /* Safe to not check the return code of strdup() here. - If it fails, we simply won't use a proxy. */ - if(no) - { - free(proxy); - proxy=strdup(""); - } - else if(start[10]=='=') - { - if(strlen(&start[11])scheme) - { - fprintf(console,"gpgkeys: no scheme supplied!\n"); - ret=KEYSERVER_SCHEME_NOT_FOUND; - goto fail; - } - - if(!opt->host) - { - fprintf(console,"gpgkeys: no keyserver host provided\n"); - goto fail; - } - - if(opt->timeout && register_timeout()==-1) - { - fprintf(console,"gpgkeys: unable to register timeout handler\n"); - return KEYSERVER_INTERNAL_ERROR; - } - - curl_global_init(CURL_GLOBAL_DEFAULT); - - curl=curl_easy_init(); - if(!curl) - { - fprintf(console,"gpgkeys: unable to initialize curl\n"); - ret=KEYSERVER_INTERNAL_ERROR; - goto fail; - } - - /* Make sure we have the protocol the user is asking for so we can - print a nicer error message. */ - curldata=curl_version_info(CURLVERSION_NOW); - for(i=0;curldata->protocols[i];i++) - if(strcasecmp(curldata->protocols[i],opt->scheme)==0) - break; - - if(curldata->protocols[i]==NULL) - { - fprintf(console,"gpgkeys: protocol '%s' not supported\n",opt->scheme); - ret=KEYSERVER_SCHEME_NOT_FOUND; - goto fail; - } - - if(follow_redirects) - { - curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L); - if(follow_redirects>0) - curl_easy_setopt(curl,CURLOPT_MAXREDIRS,follow_redirects); - } - - if(opt->auth) - curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth); - - if(opt->debug) - { - fprintf(console,"gpgkeys: curl version = %s\n",curl_version()); - curl_easy_setopt(curl,CURLOPT_STDERR,console); - curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); - } - - curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); - curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); - - /* Avoid caches to get the most recent copy of the key. This is bug - #1061. In pre-curl versions of the code, we didn't do it. Then - we did do it (as a curl default) until curl changed the default. - Now we're doing it again, but in such a way that changing - defaults in the future won't impact us. We set both the Pragma - and Cache-Control versions of the header, so we're good with both - HTTP 1.0 and 1.1. */ - headers=curl_slist_append(headers,"Pragma: no-cache"); - if(headers) - headers=curl_slist_append(headers,"Cache-Control: no-cache"); - - if(!headers) - { - fprintf(console,"gpgkeys: out of memory when building HTTP headers\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers); - - if(proxy) - curl_easy_setopt(curl,CURLOPT_PROXY,proxy); - - /* If it's a GET or a SEARCH, the next thing to come in is the - keyids. If it's a SEND, then there are no keyids. */ - - if(opt->action==KS_GET) - { - /* Eat the rest of the file */ - for(;;) - { - if(fgets(line,MAX_LINE,input)==NULL) - break; - else - { - if(line[0]=='\n' || line[0]=='\0') - break; - - if(!thekey) - { - thekey=strdup(line); - if(!thekey) - { - fprintf(console,"gpgkeys: out of memory while " - "building key list\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - /* Trim the trailing \n */ - thekey[strlen(line)-1]='\0'; - } - } - } - } - else - { - fprintf(console, - "gpgkeys: this keyserver type only supports key retrieval\n"); - goto fail; - } - - if(!thekey) - { - fprintf(console,"gpgkeys: invalid keyserver instructions\n"); - goto fail; - } - - /* Send the response */ - - fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION); - fprintf(output,"PROGRAM %s\n\n",VERSION); - - if(opt->verbose) - { - fprintf(console,"Scheme:\t\t%s\n",opt->scheme); - fprintf(console,"Host:\t\t%s\n",opt->host); - if(opt->port) - fprintf(console,"Port:\t\t%s\n",opt->port); - if(opt->path) - fprintf(console,"Path:\t\t%s\n",opt->path); - fprintf(console,"Command:\tGET\n"); - } - - set_timeout(opt->timeout); - - ret=get_key(thekey); - - fail: - - free(thekey); - - if(input!=stdin) - fclose(input); - - if(output!=stdout) - fclose(output); - - free_ks_options(opt); - - curl_slist_free_all(headers); - - if(curl) - curl_easy_cleanup(curl); - - free(proxy); - - curl_global_cleanup(); - - return ret; -} diff --git a/keyserver/gpgkeys_finger.c b/keyserver/gpgkeys_finger.c deleted file mode 100644 index 673e95643..000000000 --- a/keyserver/gpgkeys_finger.c +++ /dev/null @@ -1,500 +0,0 @@ -/* gpgkeys_finger.c - fetch a key via finger - * Copyright (C) 2004, 2005 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#endif - -#ifdef HAVE_W32_SYSTEM -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#define INCLUDED_BY_MAIN_MODULE 1 -#include "util.h" -#include "keyserver.h" -#include "ksutil.h" -#include "iobuf.h" - -#ifdef HAVE_W32_SYSTEM -#define sock_close(a) closesocket(a) -#else -#define sock_close(a) close(a) -#endif - -extern char *optarg; -extern int optind; - -static FILE *input,*output,*console; -static struct ks_options *opt; - - -/* Connect to SERVER at PORT and return a file descriptor or -1 on - error. */ -static int -connect_server (const char *server, unsigned short port) -{ - int sock = -1; - -#ifdef HAVE_W32_SYSTEM - struct hostent *hp; - struct sockaddr_in addr; - unsigned long l; - - w32_init_sockets (); - - memset (&addr, 0, sizeof addr); - addr.sin_family = AF_INET; - addr.sin_port = htons (port); - - /* Win32 gethostbyname doesn't handle IP addresses internally, so we - try inet_addr first on that platform only. */ - if ((l = inet_addr (server)) != INADDR_NONE) - memcpy (&addr.sin_addr, &l, sizeof l); - else if ((hp = gethostbyname (server))) - { - if (hp->h_addrtype != AF_INET) - { - fprintf (console, "gpgkeys: unknown address family for '%s'\n", - server); - return -1; - } - if (hp->h_length != 4) - { - fprintf (console, "gpgkeys: illegal address length for '%s'\n", - server); - return -1; - } - memcpy (&addr.sin_addr, hp->h_addr, hp->h_length); - } - else - { - fprintf (console, "gpgkeys: host '%s' not found: ec=%d\n", - server, (int)WSAGetLastError ()); - return -1; - } - - sock = socket (AF_INET, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) - { - fprintf (console, "gpgkeys: error creating socket: ec=%d\n", - (int)WSAGetLastError ()); - return -1; - } - - if (connect (sock, (struct sockaddr *)&addr, sizeof addr)) - { - fprintf (console, "gpgkeys: error connecting '%s': ec=%d\n", - server, (int)WSAGetLastError ()); - sock_close (sock); - return -1; - } - -#else - - struct sockaddr_in addr; - struct hostent *host; - - addr.sin_family = AF_INET; - addr.sin_port = htons (port); - host = gethostbyname ((char*)server); - if (!host) - { - fprintf (console, "gpgkeys: host '%s' not found: %s\n", - server, strerror (errno)); - return -1; - } - - addr.sin_addr = *(struct in_addr*)host->h_addr; - - sock = socket (AF_INET, SOCK_STREAM, 0); - if (sock == -1) - { - fprintf (console, "gpgkeys: error creating socket: %s\n", - strerror (errno)); - return -1; - } - - if (connect (sock, (struct sockaddr *)&addr, sizeof addr) == -1) - { - fprintf (console, "gpgkeys: error connecting '%s': %s\n", - server, strerror (errno)); - close (sock); - return -1; - } -#endif - - return sock; -} - -static int -write_server (int sock, const char *data, size_t length) -{ - int nleft; - - nleft = length; - while (nleft > 0) - { - int nwritten; - -#ifdef HAVE_W32_SYSTEM - nwritten = send (sock, data, nleft, 0); - if ( nwritten == SOCKET_ERROR ) - { - fprintf (console, "gpgkeys: write failed: ec=%d\n", - (int)WSAGetLastError ()); - return -1; - } -#else - nwritten = write (sock, data, nleft); - if (nwritten == -1) - { - if (errno == EINTR) - continue; - if (errno == EAGAIN) - { - struct timeval tv; - - tv.tv_sec = 0; - tv.tv_usec = 50000; - select(0, NULL, NULL, NULL, &tv); - continue; - } - fprintf (console, "gpgkeys: write failed: %s\n", strerror(errno)); - return -1; - } -#endif - nleft -=nwritten; - data += nwritten; - } - - return 0; -} - - -/* Send the finger REQUEST to the server. Returns 0 and a file descriptor - in R_SOCK if the request was sucessful. */ -static int -send_request (const char *request, int *r_sock) -{ - char *server; - char *name; - int sock; - - *r_sock = -1; - name = strdup (request); - if (!name) - { - fprintf(console,"gpgkeys: out of memory\n"); - return KEYSERVER_NO_MEMORY; - } - - server = strchr (name, '@'); - if (!server) - { - fprintf (console, "gpgkeys: no name included in request\n"); - free (name); - return KEYSERVER_GENERAL_ERROR; - } - *server++ = 0; - - sock = connect_server (server, 79); - if (sock == -1) - { - free (name); - return KEYSERVER_UNREACHABLE; - } - - if (write_server (sock, name, strlen (name)) - || write_server (sock, "\r\n", 2)) - { - free (name); - sock_close (sock); - return KEYSERVER_GENERAL_ERROR; - } - free (name); - *r_sock = sock; - return 0; -} - - - -static int -get_key (char *getkey) -{ - int rc; - int sock; - iobuf_t fp_read; - unsigned int maxlen, buflen, gotit=0; - byte *line = NULL; - - if (strncmp (getkey,"0x",2)==0) - getkey+=2; - - /* Frankly we don't know what keys the server will return; we - indicated the requested key anyway. */ - fprintf(output,"KEY 0x%s BEGIN\n",getkey); - - rc=send_request(opt->opaque,&sock); - if(rc) - { - fprintf(output,"KEY 0x%s FAILED %d\n",getkey, rc); - sock_close (sock); - return KEYSERVER_OK; - } - - /* Hmmm, we use iobuf here only to cope with Windows socket - peculiarities (we can't used fdopen). */ - fp_read = iobuf_sockopen (sock , "r"); - if (!fp_read) - { - fprintf(output,"KEY 0x%s FAILED %d\n",getkey, KEYSERVER_INTERNAL_ERROR); - sock_close (sock); - return KEYSERVER_OK; - } - - while ( iobuf_read_line ( fp_read, &line, &buflen, &maxlen)) - { - maxlen=1024; - - if(gotit) - { - print_nocr(output, (const char*)line); - if (!strncmp((char*)line,END,strlen(END))) - break; - } - else if(!strncmp((char*)line,BEGIN,strlen(BEGIN))) - { - print_nocr(output, (const char*)line); - gotit=1; - } - } - - if(gotit) - fprintf (output,"KEY 0x%s END\n", getkey); - else - { - fprintf(console,"gpgkeys: no key data found for finger:%s\n", - opt->opaque); - fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND); - } - - xfree(line); - iobuf_close (fp_read); - - return KEYSERVER_OK; -} - - -static void -show_help (FILE *fp) -{ - fprintf (fp,"-h, --help\thelp\n"); - fprintf (fp,"-V\t\tmachine readable version\n"); - fprintf (fp,"--version\thuman readable version\n"); - fprintf (fp,"-o\t\toutput to this file\n"); -} - -int -main(int argc,char *argv[]) -{ - int arg,ret=KEYSERVER_INTERNAL_ERROR; - char line[MAX_LINE]; - char *thekey=NULL; - - console=stderr; - - /* Kludge to implement standard GNU options. */ - if (argc > 1 && !strcmp (argv[1], "--version")) - { - fputs ("gpgkeys_finger ("GNUPG_NAME") " 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 deleted file mode 100644 index 6ecc8bb5a..000000000 --- a/keyserver/gpgkeys_hkp.c +++ /dev/null @@ -1,976 +0,0 @@ -/* gpgkeys_hkp.c - talk to an HKP keyserver - * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - * 2009 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * 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 -#include -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#endif -#ifdef HAVE_LIBCURL -#include -#else -#include "curl-shim.h" -#endif -#include "util.h" -#ifdef USE_DNS_SRV -#include "srv.h" -#endif -#include "keyserver.h" -#include "ksutil.h" - -extern char *optarg; -extern int optind; - -static FILE *input,*output,*console; -static CURL *curl; -static struct ks_options *opt; -static char errorbuffer[CURL_ERROR_SIZE]; -static char *proto,*port; - -static size_t -curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream) -{ - static int checked=0,swallow=0; - - if(!checked) - { - /* If the document begins with a '<', assume it's a HTML - response, which we don't support. Discard the whole message - body. GPG can handle it, but this is an optimization to deal - with it on this side of the pipe. */ - const char *buf=ptr; - if(buf[0]=='<') - swallow=1; - - checked=1; - } - - if(swallow || fwrite(ptr,size,nmemb,stream)==nmemb) - return size*nmemb; - else - return 0; -} - -/* Append but avoid creating a double slash // in the path. */ -static char * -append_path(char *dest,const char *src) -{ - size_t n=strlen(dest); - - if(src[0]=='/' && n>0 && dest[n-1]=='/') - dest[n-1]='\0'; - - return strcat(dest,src); -} - -/* Return a pointer into STRING so that appending PATH to STRING will - not yield a duplicated slash. */ -static const char * -appendable_path (const char *string, const char *path) -{ - size_t n; - - if (path[0] == '/' && (n=strlen (string)) && string[n-1] == '/') - return path+1; - else - return path; -} - - -int -send_key(int *r_eof) -{ - CURLcode res; - char request[MAX_URL+15]; - int begin=0,end=0,ret=KEYSERVER_INTERNAL_ERROR; - char keyid[17],state[6]; - char line[MAX_LINE]; - char *key=NULL,*encoded_key=NULL; - size_t keylen=0,keymax=0; - - /* Read and throw away input until we see the BEGIN */ - - while(fgets(line,MAX_LINE,input)!=NULL) - if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2 - && strcmp(state,"BEGIN")==0) - { - begin=1; - break; - } - - if(!begin) - { - /* i.e. eof before the KEY BEGIN was found. This isn't an - error. */ - *r_eof=1; - ret=KEYSERVER_OK; - goto fail; - } - - /* Now slurp up everything until we see the END */ - - while(fgets(line,MAX_LINE,input)) - if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2 - && strcmp(state,"END")==0) - { - end=1; - break; - } - else - { - if(strlen(line)+keylen>keymax) - { - char *tmp; - - keymax+=200; - tmp=realloc(key,keymax+1); - if(!tmp) - { - free(key); - fprintf(console,"gpgkeys: out of memory\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - key=tmp; - } - - strcpy(&key[keylen],line); - keylen+=strlen(line); - } - - if(!end) - { - fprintf(console,"gpgkeys: no KEY %s END found\n",keyid); - *r_eof=1; - ret=KEYSERVER_KEY_INCOMPLETE; - goto fail; - } - - encoded_key=curl_escape(key,keylen); - if(!encoded_key) - { - fprintf(console,"gpgkeys: out of memory\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - free(key); - - key = strconcat ("keytext=", encoded_key, NULL); - if(!key) - { - fprintf(console,"gpgkeys: out of memory\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - strcpy(request,proto); - strcat(request,"://"); - strcat(request,opt->host); - strcat(request,":"); - strcat(request,port); - strcat(request,opt->path); - /* request is MAX_URL+15 bytes long - MAX_URL covers the whole URL, - including any supplied path. The 15 covers /pks/add. */ - append_path(request,"/pks/add"); - - if(opt->verbose>2) - fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request); - - curl_easy_setopt(curl,CURLOPT_URL,request); - curl_easy_setopt(curl,CURLOPT_POST,1L); - curl_easy_setopt(curl,CURLOPT_POSTFIELDS,key); - curl_easy_setopt(curl,CURLOPT_FAILONERROR,1L); - - res=curl_easy_perform(curl); - if(res!=0) - { - fprintf(console,"gpgkeys: HTTP post error %d: %s\n",res,errorbuffer); - ret=curl_err_to_gpg_err(res); - goto fail; - } - else - fprintf(output,"\nKEY %s SENT\n",keyid); - - ret=KEYSERVER_OK; - - fail: - xfree (key); - curl_free(encoded_key); - - if(ret!=0 && begin) - fprintf(output,"KEY %s FAILED %d\n",keyid,ret); - - return ret; -} - -static int -get_key(char *getkey) -{ - CURLcode res; - char request[MAX_URL+92]; - char *offset; - struct curl_writer_ctx ctx; - size_t keylen; - - memset(&ctx,0,sizeof(ctx)); - - /* Build the search string. HKP only uses the short key IDs. */ - - if(strncmp(getkey,"0x",2)==0) - getkey+=2; - - fprintf(output,"KEY 0x%s BEGIN\n",getkey); - - if(strlen(getkey)==32) - { - fprintf(console, - "gpgkeys: HKP keyservers do not support v3 fingerprints\n"); - fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED); - return KEYSERVER_NOT_SUPPORTED; - } - - strcpy(request,proto); - strcat(request,"://"); - strcat(request,opt->host); - strcat(request,":"); - strcat(request,port); - strcat(request,opt->path); - /* request is MAX_URL+55 bytes long - MAX_URL covers the whole URL, - including any supplied path. The 92 overcovers this /pks/... etc - string plus the 8, 16, or 40 bytes of key id/fingerprint */ - append_path(request,"/pks/lookup?op=get&options=mr&search=0x"); - - /* send only fingerprint, long key id, or short keyid. see: - https://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-3.1.1.1 */ - keylen = strlen(getkey); - if(keylen >= 40) - offset=&getkey[keylen-40]; - else if(keylen >= 16) - offset=&getkey[keylen-16]; - else if(keylen >= 8) - offset=&getkey[keylen-8]; - else - offset=getkey; - - strcat(request,offset); - - if(opt->verbose>2) - fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request); - - curl_easy_setopt(curl,CURLOPT_URL,request); - curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer); - ctx.stream=output; - curl_easy_setopt(curl,CURLOPT_FILE,&ctx); - - res=curl_easy_perform(curl); - if(res!=CURLE_OK) - { - fprintf(console,"gpgkeys: HTTP fetch error %d: %s\n",res,errorbuffer); - fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res)); - } - else - { - curl_writer_finalize(&ctx); - if(!ctx.flags.done) - { - fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); - fprintf(output,"\nKEY 0x%s FAILED %d\n", - getkey,KEYSERVER_KEY_NOT_FOUND); - } - else - fprintf(output,"\nKEY 0x%s END\n",getkey); - } - - return KEYSERVER_OK; -} - -static int -get_name(const char *getkey) -{ - CURLcode res; - char *request=NULL; - char *searchkey_encoded; - int ret=KEYSERVER_INTERNAL_ERROR; - struct curl_writer_ctx ctx; - - memset(&ctx,0,sizeof(ctx)); - - searchkey_encoded=curl_escape((char *)getkey,0); - if(!searchkey_encoded) - { - fprintf(console,"gpgkeys: out of memory\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - request = strconcat - (proto, - "://", - opt->host, - ":", - port, - opt->path, - appendable_path (opt->path,"/pks/lookup?op=get&options=mr&search="), - searchkey_encoded, - "&exact=on", - NULL); - if(!request) - { - fprintf(console,"gpgkeys: out of memory\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - fprintf(output,"NAME %s BEGIN\n",getkey); - - if(opt->verbose>2) - fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request); - - curl_easy_setopt(curl,CURLOPT_URL,request); - curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer); - ctx.stream=output; - curl_easy_setopt(curl,CURLOPT_FILE,&ctx); - - res=curl_easy_perform(curl); - if(res!=CURLE_OK) - { - fprintf(console,"gpgkeys: HTTP fetch error %d: %s\n",res,errorbuffer); - ret=curl_err_to_gpg_err(res); - } - else - { - curl_writer_finalize(&ctx); - if(!ctx.flags.done) - { - fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); - ret=KEYSERVER_KEY_NOT_FOUND; - } - else - { - fprintf(output,"\nNAME %s END\n",getkey); - ret=KEYSERVER_OK; - } - } - - fail: - curl_free(searchkey_encoded); - xfree (request); - - if(ret!=KEYSERVER_OK) - fprintf(output,"\nNAME %s FAILED %d\n",getkey,ret); - - return ret; -} - -static int -search_key(const char *searchkey) -{ - CURLcode res; - char *request=NULL; - char *searchkey_encoded; - int ret=KEYSERVER_INTERNAL_ERROR; - enum ks_search_type search_type; - const char *hexprefix; - - search_type=classify_ks_search(&searchkey); - - if(opt->debug) - fprintf(console,"gpgkeys: search type is %d, and key is \"%s\"\n", - search_type,searchkey); - - searchkey_encoded=curl_escape((char *)searchkey,0); - if(!searchkey_encoded) - { - fprintf(console,"gpgkeys: out of memory\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - /* HKP keyservers like the 0x to be present when searching by - keyid. */ - hexprefix = (search_type==KS_SEARCH_KEYID_SHORT - || search_type==KS_SEARCH_KEYID_LONG)? "0x":""; - - request = strconcat - (proto, - "://", - opt->host, - ":", - port, - opt->path, - appendable_path (opt->path, "/pks/lookup?op=index&options=mr&search="), - hexprefix, - searchkey_encoded, - NULL); - if(!request) - { - fprintf(console,"gpgkeys: out of memory\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - fprintf(output,"SEARCH %s BEGIN\n",searchkey); - - if(opt->verbose>2) - fprintf(console,"gpgkeys: HTTP URL is '%s'\n",request); - - curl_easy_setopt(curl,CURLOPT_URL,request); - curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_mrindex_writer); - curl_easy_setopt(curl,CURLOPT_FILE,output); - - res=curl_easy_perform(curl); - if(res!=0) - { - fprintf(console,"gpgkeys: HTTP search error %d: %s\n",res,errorbuffer); - ret=curl_err_to_gpg_err(res); - } - else - { - fprintf(output,"\nSEARCH %s END\n",searchkey); - ret=KEYSERVER_OK; - } - - fail: - curl_free(searchkey_encoded); - xfree (request); - - if(ret!=KEYSERVER_OK) - fprintf(output,"\nSEARCH %s FAILED %d\n",searchkey,ret); - - return ret; -} - -void -fail_all(struct keylist *keylist,int err) -{ - if(!keylist) - return; - - if(opt->action==KS_SEARCH) - { - fprintf(output,"SEARCH "); - while(keylist) - { - fprintf(output,"%s ",keylist->str); - keylist=keylist->next; - } - fprintf(output,"FAILED %d\n",err); - } - else - while(keylist) - { - fprintf(output,"KEY %s FAILED %d\n",keylist->str,err); - keylist=keylist->next; - } -} - -#ifdef HAVE_LIBCURL -/* If there is a SRV record, take the highest ranked possibility. - This is a hack, as we don't proceed downwards. */ -static void -srv_replace(const char *srvtag) -{ -#ifdef USE_DNS_SRV - struct srventry *srvlist=NULL; - int srvcount; - - if(!srvtag) - return; - - if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME) - { - char srvname[MAXDNAME]; - - strcpy(srvname,"_"); - strcat(srvname,srvtag); - strcat(srvname,"._tcp."); - strcat(srvname,opt->host); - srvcount=getsrv(srvname,&srvlist); - } - - if(srvlist) - { - char *newname,*newport; - - newname=strdup(srvlist->target); - newport=malloc(MAX_PORT); - if(newname && newport) - { - free(opt->host); - free(opt->port); - opt->host=newname; - snprintf(newport,MAX_PORT,"%u",srvlist->port); - opt->port=newport; - } - else - { - free(newname); - free(newport); - } - } -#endif -} -#endif - -static void -show_help (FILE *fp) -{ - fprintf (fp,"-h, --help\thelp\n"); - fprintf (fp,"-V\t\tmachine readable version\n"); - fprintf (fp,"--version\thuman readable version\n"); - fprintf (fp,"-o\t\toutput to this file\n"); -} - -int -main(int argc,char *argv[]) -{ - int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1; - char line[MAX_LINE]; - int failed=0; - struct keylist *keylist=NULL,*keyptr=NULL; - char *proxy=NULL; - struct curl_slist *headers=NULL; - - console=stderr; - - /* Kludge to implement standard GNU options. */ - if (argc > 1 && !strcmp (argv[1], "--version")) - { - printf ("gpgkeys_hkp (%s) %s\n", GNUPG_NAME, VERSION); - printf ("Uses: %s\n", curl_version()); - return 0; - } - else if (argc > 1 && !strcmp (argv[1], "--help")) - { - show_help (stdout); - return 0; - } - - while((arg=getopt(argc,argv,"hVo:"))!=-1) - switch(arg) - { - default: - case 'h': - show_help (console); - return KEYSERVER_OK; - - case 'V': - fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION); - return KEYSERVER_OK; - - case 'o': - output=fopen(optarg,"w"); - if(output==NULL) - { - fprintf(console,"gpgkeys: Cannot open output file '%s': %s\n", - optarg,strerror(errno)); - return KEYSERVER_INTERNAL_ERROR; - } - - break; - } - - if(argc>optind) - { - input=fopen(argv[optind],"r"); - if(input==NULL) - { - fprintf(console,"gpgkeys: Cannot open input file '%s': %s\n", - argv[optind],strerror(errno)); - return KEYSERVER_INTERNAL_ERROR; - } - } - - if(input==NULL) - input=stdin; - - if(output==NULL) - output=stdout; - - opt=init_ks_options(); - if(!opt) - return KEYSERVER_NO_MEMORY; - - /* Get the command and info block */ - - while(fgets(line,MAX_LINE,input)!=NULL) - { - int err; - char option[MAX_OPTION+1]; - - if(line[0]=='\n') - break; - - err=parse_ks_options(line,opt); - if(err>0) - { - ret=err; - goto fail; - } - else if(err==0) - continue; - - if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "s\n",option)==1) - { - int no=0; - char *start=&option[0]; - - option[MAX_OPTION]='\0'; - - if(strncasecmp(option,"no-",3)==0) - { - no=1; - start=&option[3]; - } - - if(strncasecmp(start,"http-proxy",10)==0) - { - if(no) - { - free(proxy); - proxy=strdup(""); - } - else if(start[10]=='=') - { - if(strlen(&start[11])scheme) - { - fprintf(console,"gpgkeys: no scheme supplied!\n"); - ret=KEYSERVER_SCHEME_NOT_FOUND; - goto fail; - } - - if(ascii_strcasecmp(opt->scheme,"hkps")==0) - { - proto="https"; - port="443"; - } - else - { - proto="http"; - port="11371"; - } - - if(!opt->host) - { - fprintf(console,"gpgkeys: no keyserver host provided\n"); - goto fail; - } - - if(opt->timeout && register_timeout()==-1) - { - fprintf(console,"gpgkeys: unable to register timeout handler\n"); - return KEYSERVER_INTERNAL_ERROR; - } - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl=curl_easy_init(); - if(!curl) - { - fprintf(console,"gpgkeys: unable to initialize curl\n"); - ret=KEYSERVER_INTERNAL_ERROR; - goto fail; - } - - /* If the user gives a :port, then disable SRV. The semantics of a - specified port and SRV do not play well together. */ - if(opt->port) - port=opt->port; - else if(try_srv) - { - char *srvtag; - - if(ks_strcasecmp(opt->scheme,"hkp")==0) - srvtag="pgpkey-http"; - else if(ks_strcasecmp(opt->scheme,"hkps")==0) - srvtag="pgpkey-https"; - else - srvtag=NULL; - -#ifdef HAVE_LIBCURL - /* We're using libcurl, so fake SRV support via our wrapper. - This isn't as good as true SRV support, as we do not try all - possible targets at one particular level and work our way - down the list, but it's better than nothing. */ - srv_replace(srvtag); -#else - /* We're using our internal curl shim, so we can use its (true) - SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real - libcurl option. It's specific to our shim. */ - curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,srvtag); -#endif - } - - curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer); - - if(opt->auth) - curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth); - - if(opt->debug) - { - fprintf(console,"gpgkeys: curl version = %s\n",curl_version()); - curl_easy_setopt(curl,CURLOPT_STDERR,console); - curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); - } - - curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); - curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); - - /* Avoid caches to get the most recent copy of the key. This is bug - #1061. In pre-curl versions of the code, we didn't do it. Then - we did do it (as a curl default) until curl changed the default. - Now we're doing it again, but in such a way that changing - defaults in the future won't impact us. We set both the Pragma - and Cache-Control versions of the header, so we're good with both - HTTP 1.0 and 1.1. */ - headers=curl_slist_append(headers,"Pragma: no-cache"); - if(headers) - headers=curl_slist_append(headers,"Cache-Control: no-cache"); - - if(!headers) - { - fprintf(console,"gpgkeys: out of memory when building HTTP headers\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers); - - if(proxy) - curl_easy_setopt(curl,CURLOPT_PROXY,proxy); - - /* If it's a GET or a SEARCH, the next thing to come in is the - keyids. If it's a SEND, then there are no keyids. */ - - if(opt->action==KS_SEND) - while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n'); - else if(opt->action==KS_GET - || opt->action==KS_GETNAME || opt->action==KS_SEARCH) - { - for(;;) - { - struct keylist *work; - - if(fgets(line,MAX_LINE,input)==NULL) - break; - else - { - if(line[0]=='\n' || line[0]=='\0') - break; - - work=malloc(sizeof(struct keylist)); - if(work==NULL) - { - fprintf(console,"gpgkeys: out of memory while " - "building key list\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - strcpy(work->str,line); - - /* Trim the trailing \n */ - work->str[strlen(line)-1]='\0'; - - work->next=NULL; - - /* Always attach at the end to keep the list in proper - order for searching */ - if(keylist==NULL) - keylist=work; - else - keyptr->next=work; - - keyptr=work; - } - } - } - else - { - fprintf(console,"gpgkeys: no keyserver command specified\n"); - goto fail; - } - - /* Send the response */ - - fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION); - fprintf(output,"PROGRAM %s\n\n",VERSION); - - if(opt->verbose>1) - { - fprintf(console,"Host:\t\t%s\n",opt->host); - if(opt->port) - fprintf(console,"Port:\t\t%s\n",opt->port); - if(strcmp(opt->path,"/")!=0) - fprintf(console,"Path:\t\t%s\n",opt->path); - fprintf(console,"Command:\t%s\n",ks_action_to_string(opt->action)); - } - - if(opt->action==KS_GET) - { - keyptr=keylist; - - while(keyptr!=NULL) - { - set_timeout(opt->timeout); - - if(get_key(keyptr->str)!=KEYSERVER_OK) - failed++; - - keyptr=keyptr->next; - } - } - else if(opt->action==KS_GETNAME) - { - keyptr=keylist; - - while(keyptr!=NULL) - { - set_timeout(opt->timeout); - - if(get_name(keyptr->str)!=KEYSERVER_OK) - failed++; - - keyptr=keyptr->next; - } - } - else if(opt->action==KS_SEND) - { - int myeof=0; - - do - { - set_timeout(opt->timeout); - - if(send_key(&myeof)!=KEYSERVER_OK) - failed++; - } - while(!myeof); - } - else if(opt->action==KS_SEARCH) - { - char *searchkey=NULL; - int len=0; - - set_timeout(opt->timeout); - - /* To search, we stick a space in between each key to search - for. */ - - keyptr=keylist; - while(keyptr!=NULL) - { - len+=strlen(keyptr->str)+1; - keyptr=keyptr->next; - } - - searchkey=malloc(len+1); - if(searchkey==NULL) - { - ret=KEYSERVER_NO_MEMORY; - fail_all(keylist,KEYSERVER_NO_MEMORY); - goto fail; - } - - searchkey[0]='\0'; - - keyptr=keylist; - while(keyptr!=NULL) - { - strcat(searchkey,keyptr->str); - strcat(searchkey," "); - keyptr=keyptr->next; - } - - /* Nail that last space */ - if(*searchkey) - searchkey[strlen(searchkey)-1]='\0'; - - if(search_key(searchkey)!=KEYSERVER_OK) - failed++; - - free(searchkey); - } - else - abort(); - - if(!failed) - ret=KEYSERVER_OK; - - fail: - while(keylist!=NULL) - { - struct keylist *current=keylist; - keylist=keylist->next; - free(current); - } - - if(input!=stdin) - fclose(input); - - if(output!=stdout) - fclose(output); - - free_ks_options(opt); - - curl_slist_free_all(headers); - - if(curl) - curl_easy_cleanup(curl); - - free(proxy); - - return ret; -} diff --git a/keyserver/gpgkeys_kdns.c b/keyserver/gpgkeys_kdns.c deleted file mode 100644 index 14651f993..000000000 --- a/keyserver/gpgkeys_kdns.c +++ /dev/null @@ -1,444 +0,0 @@ -/* gpgkeys_kdns.c - Fetch a key via the GnuPG specific KDNS scheme. - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -# include -#endif -#include -#ifdef HAVE_ADNS_H -# include -# ifndef HAVE_ADNS_FREE -# define adns_free free -# endif -#endif - -#define INCLUDED_BY_MAIN_MODULE 1 -#include "util.h" -#include "keyserver.h" -#include "ksutil.h" - -/* Our own name. */ -#define PGM "gpgkeys_kdns" - -/* getopt(3) requires declarion of some global variables. */ -extern char *optarg; -extern int optind; - -/* Convenience variables usually intialized withn std{in,out,err}. */ -static FILE *input, *output, *console; - -/* Standard keyserver module options. */ -static struct ks_options *opt; - -/* The flags we pass to adns_init: Do not allow any environment - variables and for now enable debugging. */ -#define MY_ADNS_INITFLAGS (adns_if_noenv) - - -/* ADNS has no support for CERT yes. */ -#define my_adns_r_cert 37 - -/* The root of the KDNS tree. */ -static const char *kdns_root; - -/* The replacement string for the at sign. */ -static const char *kdns_at_repl; - -/* Flag indicating that a TCP connection should be used. */ -static int kdns_usevc; - - - -/* Retrieve one key. ADDRESS should be an RFC-2822 addr-spec. */ -static int -get_key (adns_state adns_ctx, char *address) -{ - int ret = KEYSERVER_INTERNAL_ERROR; - const char *domain; - char *name = NULL; - adns_answer *answer = NULL; - const unsigned char *data; - int datalen; - struct b64state b64state; - char *p; - - domain = strrchr (address, '@'); - if (!domain || domain == address || !domain[1]) - { - fprintf (console, PGM": invalid mail address '%s'\n", address); - ret = KEYSERVER_GENERAL_ERROR; - goto leave; - } - name = xtrymalloc (strlen (address) + strlen (kdns_at_repl) - + 1 + strlen (kdns_root) + 1); - if (!name) - goto leave; - memcpy (name, address, domain - address); - p = stpcpy (name + (domain-address), "."); - if (*kdns_at_repl) - p = stpcpy (stpcpy (p, kdns_at_repl), "."); - p = stpcpy (p, domain+1); - if (*kdns_root) - strcpy (stpcpy (p, "."), kdns_root); - - fprintf (output,"NAME %s BEGIN\n", address); - if (opt->verbose > 2) - fprintf(console, PGM": looking up '%s'\n", name); - - if ( adns_synchronous (adns_ctx, name, (adns_r_unknown | my_adns_r_cert), - adns_qf_quoteok_query|(kdns_usevc?adns_qf_usevc:0), - &answer) ) - { - fprintf (console, PGM": DNS query failed: %s\n", strerror (errno)); - ret = KEYSERVER_KEY_NOT_FOUND; - goto leave; - } - if (answer->status != adns_s_ok) - { - fprintf (console, PGM": DNS query returned: %s (%s)\n", - adns_strerror (answer->status), - adns_errabbrev (answer->status)); - ret = KEYSERVER_KEY_NOT_FOUND; - goto leave; - } - datalen = answer->rrs.byteblock->len; - data = answer->rrs.byteblock->data; - - if ( opt->debug > 1 ) - { - int i; - - fprintf (console, "got %d bytes of data:", datalen); - for (i=0; i < datalen; i++) - { - if (!(i % 32)) - fprintf (console, "\n%08x ", i); - fprintf (console, "%02x", data[i]); - } - putc ('\n', console); - } - if ( datalen < 5 ) - { - fprintf (console, PGM": error: truncated CERT record\n"); - ret = KEYSERVER_KEY_NOT_FOUND; - goto leave; - } - - switch ( ((data[0]<<8)|data[1]) ) - { - case 3: /* CERT type is PGP. */ - /* (key tag and algorithm fields are ignored for this CERT type). */ - data += 5; - datalen -= 5; - if ( datalen < 11 ) - { - /* Gpg checks for a minium length of 11, thus we do the same. */ - fprintf (console, PGM": error: OpenPGP data to short\n"); - ret = KEYSERVER_KEY_NOT_FOUND; - goto leave; - } - if (b64enc_start (&b64state, output, "PGP PUBLIC KEY BLOCK") - || b64enc_write (&b64state, data, datalen) - || b64enc_finish (&b64state)) - goto leave; /* Oops, base64 encoder failed. */ - break; - - default: - fprintf (console, PGM": CERT type %d ignored\n", (data[0] <<8|data[1])); - ret = KEYSERVER_KEY_NOT_FOUND; - goto leave; - } - - ret = 0; /* All fine. */ - - leave: - if (ret) - fprintf (output, "\nNAME %s FAILED %d\n", address, ret); - else - fprintf (output, "\nNAME %s END\n", address); - adns_free (answer); - xfree (name); - return ret; -} - - -/* Print some help. */ -static void -show_help (FILE *fp) -{ - fputs (PGM" ("GNUPG_NAME") " VERSION"\n\n", fp); - fputs (" -h\thelp\n" - " -V\tversion\n" - " -o\toutput to this file\n" - "\n", fp); - fputs ("This keyserver helper accepts URLs of the form:\n" - " kdns://[NAMESERVER]/[ROOT][?at=STRING]\n" - "with\n" - " NAMESERVER used for queries (default: system standard)\n" - " ROOT a DNS name appended to the query (default: none)\n" - " STRING a string to replace the '@' (default: \".\")\n" - "If a long answer is expected add the parameter \"usevc=1\".\n" - "\n", fp); - fputs ("Example: A query for \"hacker@gnupg.org\" with\n" - " kdns://10.0.0.1/example.net?at=_key&usevc=1\n" - "setup as --auto-key-lookup does a CERT record query\n" - "with type PGP on the nameserver 10.0.0.1 for\n" - " hacker._key_.gnupg.org.example.net\n" - "\n", fp); -} - - -int -main (int argc, char *argv[]) -{ - int arg; - int ret = KEYSERVER_INTERNAL_ERROR; - char line[MAX_LINE]; - struct keylist *keylist = NULL; - struct keylist **keylist_tail = &keylist; - struct keylist *akey; - int failed = 0; - adns_state adns_ctx = NULL; - adns_initflags my_adns_initflags = MY_ADNS_INITFLAGS; - int tmprc; - - /* The defaults for the KDNS name mangling. */ - kdns_root = ""; - kdns_at_repl = ""; - - console = stderr; - - /* Kludge to implement standard GNU options. */ - if (argc > 1 && !strcmp (argv[1], "--version")) - { - fputs (PGM" ("GNUPG_NAME") " VERSION"\n", stdout); - return 0; - } - else if (argc > 1 && !strcmp (argv[1], "--help")) - { - show_help (stdout); - return 0; - } - - while ( (arg = getopt (argc, argv, "hVo:")) != -1 ) - { - switch(arg) - { - case 'V': - printf ("%d\n%s\n", KEYSERVER_PROTO_VERSION, VERSION); - return KEYSERVER_OK; - - case 'o': - output = fopen (optarg,"w"); - if (!output) - { - fprintf (console, PGM": cannot open output file '%s': %s\n", - optarg, strerror(errno) ); - return KEYSERVER_INTERNAL_ERROR; - } - break; - - case 'h': - default: - show_help (console); - return KEYSERVER_OK; - } - } - - if (argc > optind) - { - input = fopen (argv[optind], "r"); - if (!input) - { - fprintf (console, PGM": cannot open input file '%s': %s\n", - argv[optind], strerror(errno) ); - return KEYSERVER_INTERNAL_ERROR; - } - } - - if (!input) - input = stdin; - - if (!output) - output = stdout; - - opt = init_ks_options(); - if(!opt) - return KEYSERVER_NO_MEMORY; - - /* Get the command and info block */ - while ( fgets(line,MAX_LINE,input) ) - { - int err; - - if(line[0]=='\n') - break; - - err = parse_ks_options (line, opt); - if (err > 0) - { - ret = err; - goto leave; - } - else if (!err) - continue; - } - - if (opt->timeout && register_timeout() == -1 ) - { - fprintf (console, PGM": unable to register timeout handler\n"); - return KEYSERVER_INTERNAL_ERROR; - } - - if (opt->verbose) - { - fprintf (console, PGM": HOST=%s\n", opt->host? opt->host:"(none)"); - fprintf (console, PGM": PATH=%s\n", opt->path? opt->path:"(none)"); - } - if (opt->path && *opt->path == '/') - { - char *p, *pend; - - kdns_root = opt->path+1; - p = strchr (opt->path+1, '?'); - if (p) - { - *p++ = 0; - do - { - pend = strchr (p, '&'); - if (pend) - *pend++ = 0; - if (!strncmp (p, "at=", 3)) - kdns_at_repl = p+3; - else if (!strncmp (p, "usevc=", 6)) - kdns_usevc = !!atoi (p+6); - } - while ((p = pend)); - } - } - if (strchr (kdns_root, '/')) - { - fprintf (console, PGM": invalid character in KDNS root\n"); - return KEYSERVER_GENERAL_ERROR; - } - if (!strcmp (kdns_at_repl, ".")) - kdns_at_repl = ""; - - if (opt->verbose) - { - fprintf (console, PGM": kdns_root=%s\n", kdns_root); - fprintf (console, PGM": kdns_at=%s\n", kdns_at_repl); - fprintf (console, PGM": kdns_usevc=%d\n", kdns_usevc); - } - - if (opt->debug) - my_adns_initflags |= adns_if_debug; - if (opt->host) - { - char cfgtext[200]; - - snprintf (cfgtext, sizeof cfgtext, "nameserver %s\n", opt->host); - tmprc = adns_init_strcfg (&adns_ctx, my_adns_initflags, console,cfgtext); - } - else - tmprc = adns_init (&adns_ctx, my_adns_initflags, console); - if (tmprc) - { - fprintf (console, PGM": error initializing ADNS: %s\n", - strerror (errno)); - goto leave; - } - - if (opt->action == KS_GETNAME) - { - while ( fgets (line,MAX_LINE,input) ) - { - if (line[0]=='\n' || !line[0] ) - break; - line[strlen(line)-1] = 0; /* Trim the trailing LF. */ - - akey = xtrymalloc (sizeof *akey); - if (!akey) - { - fprintf (console, - PGM": out of memory while building key list\n"); - ret = KEYSERVER_NO_MEMORY; - goto leave; - } - assert (sizeof (akey->str) > strlen(line)); - strcpy (akey->str, line); - akey->next = NULL; - *keylist_tail = akey; - keylist_tail = &akey->next; - } - } - else - { - fprintf (console, - PGM": this keyserver type only supports " - "key retrieval by name\n"); - goto leave; - } - - /* Send the response */ - fprintf (output, "VERSION %d\n", KEYSERVER_PROTO_VERSION); - fprintf (output, "PROGRAM %s\n\n", VERSION); - - if (opt->verbose > 1) - { - if (opt->opaque) - fprintf (console, "User:\t\t%s\n", opt->opaque); - fprintf (console, "Command:\tGET\n"); - } - - for (akey = keylist; akey; akey = akey->next) - { - set_timeout (opt->timeout); - if ( get_key (adns_ctx, akey->str) ) - failed++; - } - if (!failed) - ret = KEYSERVER_OK; - - - leave: - if (adns_ctx) - adns_finish (adns_ctx); - while (keylist) - { - akey = keylist->next; - xfree (keylist); - keylist = akey; - } - if (input != stdin) - fclose (input); - if (output != stdout) - fclose (output); - kdns_root = ""; - kdns_at_repl = "."; - free_ks_options (opt); - return ret; -} diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c deleted file mode 100644 index f24a5719b..000000000 --- a/keyserver/gpgkeys_ldap.c +++ /dev/null @@ -1,2379 +0,0 @@ -/* gpgkeys_ldap.c - talk to a LDAP keyserver - * Copyright (C) 2001, 2002, 2004, 2005, 2006 - * 2007 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * 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 -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#endif -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#else -#ifdef NEED_LBER_H -#include -#endif -/* For OpenLDAP, to enable the API that we're using. */ -#define LDAP_DEPRECATED 1 -#include -#endif - -#include "util.h" -#include "keyserver.h" -#include "ksutil.h" - -#ifdef __riscos__ -#include "util.h" -#endif - -extern char *optarg; -extern int optind; - -static int real_ldap=0; -static char *basekeyspacedn=NULL; -static char *pgpkeystr="pgpKey"; -static FILE *input=NULL,*output=NULL,*console=NULL; -static LDAP *ldap=NULL; -static struct ks_options *opt; - -#ifndef HAVE_TIMEGM -time_t timegm(struct tm *tm); -#endif - -static int -ldap_err_to_gpg_err(int err) -{ - int ret; - - switch(err) - { - case LDAP_ALREADY_EXISTS: - ret=KEYSERVER_KEY_EXISTS; - break; - - case LDAP_SERVER_DOWN: - ret=KEYSERVER_UNREACHABLE; - break; - - default: - ret=KEYSERVER_GENERAL_ERROR; - break; - } - - return ret; -} - -static int -ldap_to_gpg_err(LDAP *ld) -{ -#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) - - int err; - - if(ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&err)==0) - return ldap_err_to_gpg_err(err); - else - return KEYSERVER_GENERAL_ERROR; - -#elif defined(HAVE_LDAP_LD_ERRNO) - - return ldap_err_to_gpg_err(ld->ld_errno); - -#else - - /* We should never get here since the LDAP library should always - have either ldap_get_option or ld_errno, but just in case... */ - return KEYSERVER_GENERAL_ERROR; - -#endif -} - -static int -key_in_keylist(const char *key,struct keylist *list) -{ - struct keylist *keyptr=list; - - while(keyptr!=NULL) - { - if(strcasecmp(key,keyptr->str)==0) - return 1; - - keyptr=keyptr->next; - } - - return 0; -} - -static int -add_key_to_keylist(const char *key,struct keylist **list) -{ - struct keylist *keyptr=malloc(sizeof(struct keylist)); - - if(keyptr==NULL) - { - fprintf(console,"gpgkeys: out of memory when deduping " - "key list\n"); - return KEYSERVER_NO_MEMORY; - } - - strncpy(keyptr->str,key,MAX_LINE); - keyptr->str[MAX_LINE-1]='\0'; - keyptr->next=*list; - *list=keyptr; - - return 0; -} - -static void -free_keylist(struct keylist *list) -{ - while(list!=NULL) - { - struct keylist *keyptr=list; - - list=keyptr->next; - free(keyptr); - } -} - -static time_t -ldap2epochtime(const char *timestr) -{ - struct tm pgptime; - time_t answer; - - memset(&pgptime,0,sizeof(pgptime)); - - /* YYYYMMDDHHmmssZ */ - - sscanf(timestr,"%4d%2d%2d%2d%2d%2d", - &pgptime.tm_year, - &pgptime.tm_mon, - &pgptime.tm_mday, - &pgptime.tm_hour, - &pgptime.tm_min, - &pgptime.tm_sec); - - pgptime.tm_year-=1900; - pgptime.tm_isdst=-1; - pgptime.tm_mon--; - - /* mktime() takes the timezone into account, so we use timegm() */ - - answer=timegm(&pgptime); - - return answer; -} - -/* Caller must free */ -static char * -epoch2ldaptime(time_t stamp) -{ - struct tm *ldaptime; - char buf[16]; - - ldaptime=gmtime(&stamp); - - ldaptime->tm_year+=1900; - ldaptime->tm_mon++; - - /* YYYYMMDDHHmmssZ */ - - sprintf(buf,"%04d%02d%02d%02d%02d%02dZ", - ldaptime->tm_year, - ldaptime->tm_mon, - ldaptime->tm_mday, - ldaptime->tm_hour, - ldaptime->tm_min, - ldaptime->tm_sec); - - return strdup(buf); -} - -/* Append two onto the end of one. Two is not freed, but its pointers - are now part of one. Make sure you don't free them both! */ -static int -join_two_modlists(LDAPMod ***one,LDAPMod **two) -{ - int i,one_count=0,two_count=0; - LDAPMod **grow; - - for(grow=*one;*grow;grow++) - one_count++; - - for(grow=two;*grow;grow++) - two_count++; - - grow=realloc(*one,sizeof(LDAPMod *)*(one_count+two_count+1)); - if(!grow) - return 0; - - for(i=0;imod_type,attr)==0) - { - char **ptr=(*m)->mod_values; - int numvalues=0; - - /* We have this attribute already, so when the REPLACE - happens, the server attributes will be replaced - anyway. */ - if(!value) - return 1; - - if(ptr) - for(ptr=(*m)->mod_values;*ptr;ptr++) - { - /* Duplicate value */ - if(strcmp(*ptr,value)==0) - return 1; - numvalues++; - } - - ptr=realloc((*m)->mod_values,sizeof(char *)*(numvalues+2)); - if(!ptr) - return 0; - - (*m)->mod_values=ptr; - ptr[numvalues]=strdup(value); - if(!ptr[numvalues]) - return 0; - - ptr[numvalues+1]=NULL; - break; - } - - nummods++; - } - - /* We didn't find the attr, so make one and add it to the end */ - if(!*m) - { - LDAPMod **grow; - - grow=realloc(*modlist,sizeof(LDAPMod *)*(nummods+2)); - if(!grow) - return 0; - - *modlist=grow; - grow[nummods]=malloc(sizeof(LDAPMod)); - if(!grow[nummods]) - return 0; - grow[nummods]->mod_op=LDAP_MOD_REPLACE; - grow[nummods]->mod_type=attr; - if(value) - { - grow[nummods]->mod_values=malloc(sizeof(char *)*2); - if(!grow[nummods]->mod_values) - { - grow[nummods]=NULL; - return 0; - } - - /* Is this the right thing? Can a UTF8-encoded user ID have - embedded nulls? */ - grow[nummods]->mod_values[0]=strdup(value); - if(!grow[nummods]->mod_values[0]) - { - free(grow[nummods]->mod_values); - grow[nummods]=NULL; - return 0; - } - - grow[nummods]->mod_values[1]=NULL; - } - else - grow[nummods]->mod_values=NULL; - - grow[nummods+1]=NULL; - } - - return 1; -} - -static void -build_attrs(LDAPMod ***modlist,char *line) -{ - char *record; - int i; - - /* Remove trailing whitespace */ - for(i=strlen(line);i>0;i--) - if(ascii_isspace(line[i-1])) - line[i-1]='\0'; - else - break; - - if((record=strsep(&line,":"))==NULL) - return; - - if(ks_strcasecmp("pub",record)==0) - { - char *tok; - int disabled=0,revoked=0; - - /* The long keyid */ - if((tok=strsep(&line,":"))==NULL) - return; - - if(strlen(tok)==16) - { - make_one_attr(modlist,"pgpCertID",tok); - make_one_attr(modlist,"pgpKeyID",&tok[8]); - } - else - return; - - /* The primary pubkey algo */ - if((tok=strsep(&line,":"))==NULL) - return; - - switch(atoi(tok)) - { - case 1: - make_one_attr(modlist,"pgpKeyType","RSA"); - break; - - case 17: - make_one_attr(modlist,"pgpKeyType","DSS/DH"); - break; - } - - /* Size of primary key */ - if((tok=strsep(&line,":"))==NULL) - return; - - if(atoi(tok)>0) - { - char padded[6]; - int val=atoi(tok); - - /* We zero pad this on the left to make PGP happy. */ - - if(val<99999 && val>0) - { - sprintf(padded,"%05u",atoi(tok)); - make_one_attr(modlist,"pgpKeySize",padded); - } - } - - /* pk timestamp */ - if((tok=strsep(&line,":"))==NULL) - return; - - if(atoi(tok)>0) - { - char *stamp=epoch2ldaptime(atoi(tok)); - if(stamp) - { - make_one_attr(modlist,"pgpKeyCreateTime",stamp); - free(stamp); - } - } - - /* pk expire */ - if((tok=strsep(&line,":"))==NULL) - return; - - if(atoi(tok)>0) - { - char *stamp=epoch2ldaptime(atoi(tok)); - if(stamp) - { - make_one_attr(modlist,"pgpKeyExpireTime",stamp); - free(stamp); - } - } - - /* flags */ - if((tok=strsep(&line,":"))==NULL) - return; - - while(*tok) - switch(*tok++) - { - case 'r': - case 'R': - revoked=1; - break; - - case 'd': - case 'D': - disabled=1; - break; - } - - /* - Note that we always create the pgpDisabled and pgpRevoked - attributes, regardless of whether the key is disabled/revoked - or not. This is because a very common search is like - "(&(pgpUserID=*isabella*)(pgpDisabled=0))" - */ - - make_one_attr(modlist,"pgpDisabled",disabled?"1":"0"); - make_one_attr(modlist,"pgpRevoked",revoked?"1":"0"); - } - else if(ks_strcasecmp("sub",record)==0) - { - char *tok; - - /* The long keyid */ - if((tok=strsep(&line,":"))==NULL) - return; - - if(strlen(tok)==16) - make_one_attr(modlist,"pgpSubKeyID",tok); - else - return; - - /* The subkey algo */ - if((tok=strsep(&line,":"))==NULL) - return; - - /* Size of subkey */ - if((tok=strsep(&line,":"))==NULL) - return; - - if(atoi(tok)>0) - { - char padded[6]; - int val=atoi(tok); - - /* We zero pad this on the left to make PGP happy. */ - - if(val<99999 && val>0) - { - sprintf(padded,"%05u",atoi(tok)); - make_one_attr(modlist,"pgpKeySize",padded); - } - } - - /* Ignore the rest of the items for subkeys since the LDAP - schema doesn't store them. */ - } - else if(ks_strcasecmp("uid",record)==0) - { - char *userid,*tok; - - /* The user ID string */ - if((tok=strsep(&line,":"))==NULL) - return; - - if(strlen(tok)==0) - return; - - userid=tok; - - /* By definition, de-%-encoding is always smaller than the - original string so we can decode in place. */ - - i=0; - - while(*tok) - if(tok[0]=='%' && tok[1] && tok[2]) - { - int c; - - userid[i] = (c=hextobyte(&tok[1])) == -1 ? '?' : c; - i++; - tok+=3; - } - else - userid[i++]=*tok++; - - userid[i]='\0'; - - /* We don't care about the other info provided in the uid: line - since the LDAP schema doesn't need it. */ - - make_one_attr(modlist,"pgpUserID",userid); - } - else if(ks_strcasecmp("sig",record)==0) - { - char *tok; - - if((tok=strsep(&line,":"))==NULL) - return; - - if(strlen(tok)==16) - make_one_attr(modlist,"pgpSignerID",tok); - } -} - -static void -free_mod_values(LDAPMod *mod) -{ - char **ptr; - - if(!mod->mod_values) - return; - - for(ptr=mod->mod_values;*ptr;ptr++) - free(*ptr); - - free(mod->mod_values); -} - -static int -send_key(int *r_eof) -{ - int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR; - char *dn=NULL,line[MAX_LINE],*key=NULL; - char keyid[17],state[6]; - LDAPMod **modlist,**addlist,**ml; - - modlist=malloc(sizeof(LDAPMod *)); - if(!modlist) - { - fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - *modlist=NULL; - - addlist=malloc(sizeof(LDAPMod *)); - if(!addlist) - { - fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - *addlist=NULL; - - /* Start by nulling out all attributes. We try and do a modify - operation first, so this ensures that we don't leave old - attributes lying around. */ - make_one_attr(&modlist,"pgpDisabled",NULL); - make_one_attr(&modlist,"pgpKeyID",NULL); - make_one_attr(&modlist,"pgpKeyType",NULL); - make_one_attr(&modlist,"pgpUserID",NULL); - make_one_attr(&modlist,"pgpKeyCreateTime",NULL); - make_one_attr(&modlist,"pgpSignerID",NULL); - make_one_attr(&modlist,"pgpRevoked",NULL); - make_one_attr(&modlist,"pgpSubKeyID",NULL); - make_one_attr(&modlist,"pgpKeySize",NULL); - make_one_attr(&modlist,"pgpKeyExpireTime",NULL); - make_one_attr(&modlist,"pgpCertID",NULL); - - /* Assemble the INFO stuff into LDAP attributes */ - - while(fgets(line,MAX_LINE,input)!=NULL) - if(sscanf(line,"INFO%*[ ]%16s%*[ ]%5s\n",keyid,state)==2 - && strcmp(state,"BEGIN")==0) - { - begin=1; - break; - } - - if(!begin) - { - /* i.e. eof before the INFO BEGIN was found. This isn't an - error. */ - *r_eof=1; - ret=KEYSERVER_OK; - goto fail; - } - - if(strlen(keyid)!=16) - { - *r_eof=1; - ret=KEYSERVER_KEY_INCOMPLETE; - goto fail; - } - - dn=malloc(strlen("pgpCertID=")+16+1+strlen(basekeyspacedn)+1); - if(dn==NULL) - { - fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - sprintf(dn,"pgpCertID=%s,%s",keyid,basekeyspacedn); - - key=malloc(1); - if(!key) - { - fprintf(console,"gpgkeys: unable to allocate memory for key\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - key[0]='\0'; - - /* Now parse each line until we see the END */ - - while(fgets(line,MAX_LINE,input)!=NULL) - if(sscanf(line,"INFO%*[ ]%16s%*[ ]%3s\n",keyid,state)==2 - && strcmp(state,"END")==0) - { - end=1; - break; - } - else - build_attrs(&addlist,line); - - if(!end) - { - fprintf(console,"gpgkeys: no INFO %s END found\n",keyid); - *r_eof=1; - ret=KEYSERVER_KEY_INCOMPLETE; - goto fail; - } - - begin=end=0; - - /* Read and throw away stdin until we see the BEGIN */ - - while(fgets(line,MAX_LINE,input)!=NULL) - if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2 - && strcmp(state,"BEGIN")==0) - { - begin=1; - break; - } - - if(!begin) - { - /* i.e. eof before the KEY BEGIN was found. This isn't an - error. */ - *r_eof=1; - ret=KEYSERVER_OK; - goto fail; - } - - /* Now slurp up everything until we see the END */ - - while(fgets(line,MAX_LINE,input)!=NULL) - if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2 - && strcmp(state,"END")==0) - { - end=1; - break; - } - else - { - char *tempkey; - keysize+=strlen(line); - tempkey=realloc(key,keysize); - if(tempkey==NULL) - { - fprintf(console,"gpgkeys: unable to reallocate for key\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - else - key=tempkey; - - strcat(key,line); - } - - if(!end) - { - fprintf(console,"gpgkeys: no KEY %s END found\n",keyid); - *r_eof=1; - ret=KEYSERVER_KEY_INCOMPLETE; - goto fail; - } - - make_one_attr(&addlist,"objectClass","pgpKeyInfo"); - make_one_attr(&addlist,"pgpKey",key); - - /* Now append addlist onto modlist */ - if(!join_two_modlists(&modlist,addlist)) - { - fprintf(console,"gpgkeys: unable to merge LDAP modification lists\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - /* Going on the assumption that modify operations are more frequent - than adds, we try a modify first. If it's not there, we just - turn around and send an add command for the same key. Otherwise, - the modify brings the server copy into compliance with our copy. - Note that unlike the LDAP keyserver (and really, any other - keyserver) this does NOT merge signatures, but replaces the whole - key. This should make some people very happy. */ - - err=ldap_modify_s(ldap,dn,modlist); - if(err==LDAP_NO_SUCH_OBJECT) - err=ldap_add_s(ldap,dn,addlist); - - if(err!=LDAP_SUCCESS) - { - fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n", - keyid,ldap_err2string(err)); - ret=ldap_err_to_gpg_err(err); - goto fail; - } - - ret=KEYSERVER_OK; - - fail: - if (modlist) - { - /* Unwind and free the whole modlist structure */ - for(ml=modlist;*ml;ml++) - { - free_mod_values(*ml); - free(*ml); - } - free(modlist); - } - free(addlist); - free(dn); - free(key); - - if(ret!=0 && begin) - fprintf(output,"KEY %s FAILED %d\n",keyid,ret); - - return ret; -} - -static int -send_key_keyserver(int *r_eof) -{ - int err,begin=0,end=0,keysize=1,ret=KEYSERVER_INTERNAL_ERROR; - char *dn=NULL,line[MAX_LINE],*key[2]={NULL,NULL}; - char keyid[17],state[6]; - LDAPMod mod, *attrs[2]; - - memset(&mod,0,sizeof(mod)); - mod.mod_op=LDAP_MOD_ADD; - mod.mod_type=pgpkeystr; - mod.mod_values=key; - attrs[0]=&mod; - attrs[1]=NULL; - - dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1); - if(dn==NULL) - { - fprintf(console,"gpgkeys: can't allocate memory for keyserver record\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - strcpy(dn,"pgpCertid=virtual,"); - strcat(dn,basekeyspacedn); - - key[0]=malloc(1); - if(key[0]==NULL) - { - fprintf(console,"gpgkeys: unable to allocate memory for key\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - key[0][0]='\0'; - - /* Read and throw away stdin until we see the BEGIN */ - - while(fgets(line,MAX_LINE,input)!=NULL) - if(sscanf(line,"KEY%*[ ]%16s%*[ ]%5s\n",keyid,state)==2 - && strcmp(state,"BEGIN")==0) - { - begin=1; - break; - } - - if(!begin) - { - /* i.e. eof before the KEY BEGIN was found. This isn't an - error. */ - *r_eof=1; - ret=KEYSERVER_OK; - goto fail; - } - - /* Now slurp up everything until we see the END */ - - while(fgets(line,MAX_LINE,input)!=NULL) - if(sscanf(line,"KEY%*[ ]%16s%*[ ]%3s\n",keyid,state)==2 - && strcmp(state,"END")==0) - { - end=1; - break; - } - else - { - keysize+=strlen(line); - key[0]=realloc(key[0],keysize); - if(key[0]==NULL) - { - fprintf(console,"gpgkeys: unable to reallocate for key\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - strcat(key[0],line); - } - - if(!end) - { - fprintf(console,"gpgkeys: no KEY %s END found\n",keyid); - *r_eof=1; - ret=KEYSERVER_KEY_INCOMPLETE; - goto fail; - } - - err=ldap_add_s(ldap,dn,attrs); - if(err!=LDAP_SUCCESS) - { - fprintf(console,"gpgkeys: error adding key %s to keyserver: %s\n", - keyid,ldap_err2string(err)); - ret=ldap_err_to_gpg_err(err); - goto fail; - } - - ret=KEYSERVER_OK; - - fail: - - free(key[0]); - free(dn); - - if(ret!=0 && begin) - fprintf(output,"KEY %s FAILED %d\n",keyid,ret); - - /* Not a fatal error */ - if(ret==KEYSERVER_KEY_EXISTS) - ret=KEYSERVER_OK; - - return ret; -} - -static void -build_info(const char *certid,LDAPMessage *each) -{ - char **vals; - - fprintf(output,"INFO %s BEGIN\n",certid); - - fprintf(output,"pub:%s:",certid); - - vals=ldap_get_values(ldap,each,"pgpkeytype"); - if(vals!=NULL) - { - if(strcmp(vals[0],"RSA")==0) - fprintf(output,"1"); - else if(strcmp(vals[0],"DSS/DH")==0) - fprintf(output,"17"); - ldap_value_free(vals); - } - - fprintf(output,":"); - - vals=ldap_get_values(ldap,each,"pgpkeysize"); - if(vals!=NULL) - { - if(atoi(vals[0])>0) - fprintf(output,"%d",atoi(vals[0])); - ldap_value_free(vals); - } - - fprintf(output,":"); - - vals=ldap_get_values(ldap,each,"pgpkeycreatetime"); - if(vals!=NULL) - { - if(strlen(vals[0])==15) - fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0])); - ldap_value_free(vals); - } - - fprintf(output,":"); - - vals=ldap_get_values(ldap,each,"pgpkeyexpiretime"); - if(vals!=NULL) - { - if(strlen(vals[0])==15) - fprintf(output,"%u",(unsigned int)ldap2epochtime(vals[0])); - ldap_value_free(vals); - } - - fprintf(output,":"); - - vals=ldap_get_values(ldap,each,"pgprevoked"); - if(vals!=NULL) - { - if(atoi(vals[0])==1) - fprintf(output,"r"); - ldap_value_free(vals); - } - - fprintf(output,"\n"); - - vals=ldap_get_values(ldap,each,"pgpuserid"); - if(vals!=NULL) - { - int i; - - for(i=0;vals[i];i++) - fprintf(output,"uid:%s\n",vals[i]); - ldap_value_free(vals); - } - - fprintf(output,"INFO %s END\n",certid); -} - -/* Note that key-not-found is not a fatal error */ -static int -get_key(char *getkey) -{ - LDAPMessage *res,*each; - int ret=KEYSERVER_INTERNAL_ERROR,err,count; - struct keylist *dupelist=NULL; - char search[62]; - /* This ordering is significant - specifically, "pgpcertid" needs to - be the second item in the list, since everything after it may be - discarded if the user isn't in verbose mode. */ - char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked", - "pgpdisabled","pgpkeycreatetime","modifytimestamp", - "pgpkeysize","pgpkeytype",NULL}; - attrs[0]=pgpkeystr; /* Some compilers don't like using variables as - array initializers. */ - - /* Build the search string */ - - /* GPG can send us a v4 fingerprint, a v3 or v4 long key id, or a v3 - or v4 short key id */ - - if(strncmp(getkey,"0x",2)==0) - getkey+=2; - - if(strlen(getkey)==32) - { - fprintf(console, - "gpgkeys: LDAP keyservers do not support v3 fingerprints\n"); - fprintf(output,"KEY 0x%s BEGIN\n",getkey); - fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_NOT_SUPPORTED); - return KEYSERVER_NOT_SUPPORTED; - } - - if(strlen(getkey)>16) - { - char *offset=&getkey[strlen(getkey)-16]; - - /* fingerprint. Take the last 16 characters and treat it like a - long key id */ - - if(opt->flags.include_subkeys) - sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))", - offset,offset); - else - sprintf(search,"(pgpcertid=%.16s)",offset); - } - else if(strlen(getkey)>8) - { - /* long key id */ - - if(opt->flags.include_subkeys) - sprintf(search,"(|(pgpcertid=%.16s)(pgpsubkeyid=%.16s))", - getkey,getkey); - else - sprintf(search,"(pgpcertid=%.16s)",getkey); - } - else - { - /* short key id */ - - sprintf(search,"(pgpkeyid=%.8s)",getkey); - } - - if(opt->verbose>2) - fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search); - - if(!opt->verbose) - attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */ - - err=ldap_search_s(ldap,basekeyspacedn, - LDAP_SCOPE_SUBTREE,search,attrs,0,&res); - if(err!=0) - { - int errtag=ldap_err_to_gpg_err(err); - - fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err)); - fprintf(output,"KEY 0x%s BEGIN\n",getkey); - fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag); - return errtag; - } - - count=ldap_count_entries(ldap,res); - if(count<1) - { - fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); - fprintf(output,"KEY 0x%s BEGIN\n",getkey); - fprintf(output,"KEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND); - } - else - { - /* There may be more than one unique result for a given keyID, - so we should fetch them all (test this by fetching short key - id 0xDEADBEEF). */ - - each=ldap_first_entry(ldap,res); - while(each!=NULL) - { - char **vals,**certid; - - /* Use the long keyid to remove duplicates. The LDAP server - returns the same keyid more than once if there are - multiple user IDs on the key. Note that this does NOT - mean that a keyid that exists multiple times on the - keyserver will not be fetched. It means that each KEY, - no matter how many user IDs share its keyid, will be - fetched only once. If a keyid that belongs to more than - one key is fetched, the server quite properly responds - with all matching keys. -ds */ - - certid=ldap_get_values(ldap,each,"pgpcertid"); - if(certid!=NULL) - { - if(!key_in_keylist(certid[0],dupelist)) - { - /* it's not a duplicate, so add it */ - - int rc=add_key_to_keylist(certid[0],&dupelist); - if(rc) - { - ret=rc; - goto fail; - } - - build_info(certid[0],each); - - fprintf(output,"KEY 0x%s BEGIN\n",getkey); - - vals=ldap_get_values(ldap,each,pgpkeystr); - if(vals==NULL) - { - int errtag=ldap_to_gpg_err(ldap); - - fprintf(console,"gpgkeys: unable to retrieve key %s " - "from keyserver\n",getkey); - fprintf(output,"KEY 0x%s FAILED %d\n",getkey,errtag); - } - else - { - print_nocr(output,vals[0]); - fprintf(output,"\nKEY 0x%s END\n",getkey); - - ldap_value_free(vals); - } - } - - ldap_value_free(certid); - } - - each=ldap_next_entry(ldap,each); - } - } - - ret=KEYSERVER_OK; - - fail: - ldap_msgfree(res); - free_keylist(dupelist); - - return ret; -} - -#define LDAP_ESCAPE_CHARS "*()\\" - -/* Append string to buffer in a LDAP-quoted way */ -static void -ldap_quote(char *buffer,const char *string) -{ - /* Find the end of buffer */ - buffer+=strlen(buffer); - - for(;*string;string++) - { - if(strchr(LDAP_ESCAPE_CHARS,*string)) - { - sprintf(buffer,"\\%02X",*string); - buffer+=3; - } - else - *buffer++=*string; - } - - *buffer='\0'; -} - -/* Note that key-not-found is not a fatal error */ -static int -get_name(char *getkey) -{ - LDAPMessage *res,*each; - int ret=KEYSERVER_INTERNAL_ERROR,err,count; - /* The maximum size of the search, including the optional stuff and - the trailing \0 */ - char search[2+12+(MAX_LINE*3)+2+15+14+1+1+20]; - /* This ordering is significant - specifically, "pgpcertid" needs to - be the second item in the list, since everything after it may be - discarded if the user isn't in verbose mode. */ - char *attrs[]={"replaceme","pgpcertid","pgpuserid","pgpkeyid","pgprevoked", - "pgpdisabled","pgpkeycreatetime","modifytimestamp", - "pgpkeysize","pgpkeytype",NULL}; - attrs[0]=pgpkeystr; /* Some compilers don't like using variables as - array initializers. */ - - /* Build the search string */ - - search[0]='\0'; - - if(!opt->flags.include_disabled || !opt->flags.include_revoked) - strcat(search,"(&"); - - strcat(search,"(pgpUserID=*"); - ldap_quote(search,getkey); - strcat(search,"*)"); - - if(!opt->flags.include_disabled) - strcat(search,"(pgpDisabled=0)"); - - if(!opt->flags.include_revoked) - strcat(search,"(pgpRevoked=0)"); - - if(!opt->flags.include_disabled || !opt->flags.include_revoked) - strcat(search,")"); - - if(opt->verbose>2) - fprintf(console,"gpgkeys: LDAP fetch for: %s\n",search); - - if(!opt->verbose) - attrs[2]=NULL; /* keep only pgpkey(v2) and pgpcertid */ - - err=ldap_search_s(ldap,basekeyspacedn, - LDAP_SCOPE_SUBTREE,search,attrs,0,&res); - if(err!=0) - { - int errtag=ldap_err_to_gpg_err(err); - - fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err)); - fprintf(output,"NAME %s BEGIN\n",getkey); - fprintf(output,"NAME %s FAILED %d\n",getkey,errtag); - return errtag; - } - - count=ldap_count_entries(ldap,res); - if(count<1) - { - fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); - fprintf(output,"NAME %s BEGIN\n",getkey); - fprintf(output,"NAME %s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND); - } - else - { - /* There may be more than one result, but we return them all. */ - - each=ldap_first_entry(ldap,res); - while(each!=NULL) - { - char **vals,**certid; - - certid=ldap_get_values(ldap,each,"pgpcertid"); - if(certid!=NULL) - { - build_info(certid[0],each); - - fprintf(output,"NAME %s BEGIN\n",getkey); - - vals=ldap_get_values(ldap,each,pgpkeystr); - if(vals==NULL) - { - int errtag=ldap_to_gpg_err(ldap); - - fprintf(console,"gpgkeys: unable to retrieve key %s " - "from keyserver\n",getkey); - fprintf(output,"NAME %s FAILED %d\n",getkey,errtag); - } - else - { - print_nocr(output,vals[0]); - fprintf(output,"\nNAME %s END\n",getkey); - - ldap_value_free(vals); - } - - ldap_value_free(certid); - } - - each=ldap_next_entry(ldap,each); - } - } - - ret=KEYSERVER_OK; - - ldap_msgfree(res); - - return ret; -} - -static void -printquoted(FILE *stream,char *string,char delim) -{ - while(*string) - { - if(*string==delim || *string=='%') - fprintf(stream,"%%%02x",*string); - else - fputc(*string,stream); - - string++; - } -} - -/* Returns 0 on success and -1 on error. Note that key-not-found is - not an error! */ -static int -search_key(const char *searchkey) -{ - char **vals,*search; - LDAPMessage *res,*each; - int err,count=0; - struct keylist *dupelist=NULL; - /* The maximum size of the search, including the optional stuff and - the trailing \0 */ - char *attrs[]={"pgpcertid","pgpuserid","pgprevoked","pgpdisabled", - "pgpkeycreatetime","pgpkeyexpiretime","modifytimestamp", - "pgpkeysize","pgpkeytype",NULL}; - enum ks_search_type search_type; - - search=malloc(2+1+9+1+3+strlen(searchkey)+3+1+15+14+1+1+20); - if(!search) - { - fprintf(console,"gpgkeys: out of memory when building search list\n"); - fprintf(output,"SEARCH %s FAILED %d\n",searchkey,KEYSERVER_NO_MEMORY); - return KEYSERVER_NO_MEMORY; - } - - fprintf(output,"SEARCH %s BEGIN\n",searchkey); - - search_type=classify_ks_search(&searchkey); - - if(opt->debug) - fprintf(console,"search type is %d, and key is \"%s\"\n", - search_type,searchkey); - - /* Build the search string */ - - search[0]='\0'; - - if(!opt->flags.include_disabled || !opt->flags.include_revoked) - strcat(search,"(&"); - - strcat(search,"("); - - switch(search_type) - { - case KS_SEARCH_KEYID_SHORT: - strcat(search,"pgpKeyID"); - break; - - case KS_SEARCH_KEYID_LONG: - strcat(search,"pgpCertID"); - break; - - default: - strcat(search,"pgpUserID"); - break; - } - - strcat(search,"="); - - switch(search_type) - { - case KS_SEARCH_SUBSTR: - strcat(search,"*"); - break; - - case KS_SEARCH_MAIL: - strcat(search,"*<"); - break; - - case KS_SEARCH_MAILSUB: - strcat(search,"*<*"); - break; - - case KS_SEARCH_EXACT: - case KS_SEARCH_KEYID_LONG: - case KS_SEARCH_KEYID_SHORT: - break; - } - - strcat(search,searchkey); - - switch(search_type) - { - case KS_SEARCH_SUBSTR: - strcat(search,"*"); - break; - - case KS_SEARCH_MAIL: - strcat(search,">*"); - break; - - case KS_SEARCH_MAILSUB: - strcat(search,"*>*"); - break; - - case KS_SEARCH_EXACT: - case KS_SEARCH_KEYID_LONG: - case KS_SEARCH_KEYID_SHORT: - break; - } - - strcat(search,")"); - - if(!opt->flags.include_disabled) - strcat(search,"(pgpDisabled=0)"); - - if(!opt->flags.include_revoked) - strcat(search,"(pgpRevoked=0)"); - - if(!opt->flags.include_disabled || !opt->flags.include_revoked) - strcat(search,")"); - - if(opt->verbose>2) - fprintf(console,"gpgkeys: LDAP search for: %s\n",search); - - err=ldap_search_s(ldap,basekeyspacedn, - LDAP_SCOPE_SUBTREE,search,attrs,0,&res); - free(search); - if(err!=LDAP_SUCCESS && err!=LDAP_SIZELIMIT_EXCEEDED) - { - int errtag=ldap_err_to_gpg_err(err); - - fprintf(output,"SEARCH %s FAILED %d\n",searchkey,errtag); - fprintf(console,"gpgkeys: LDAP search error: %s\n",ldap_err2string(err)); - return errtag; - } - - /* The LDAP server doesn't return a real count of unique keys, so we - can't use ldap_count_entries here. */ - each=ldap_first_entry(ldap,res); - while(each!=NULL) - { - char **certid=ldap_get_values(ldap,each,"pgpcertid"); - - if(certid!=NULL) - { - if(!key_in_keylist(certid[0],dupelist)) - { - int rc=add_key_to_keylist(certid[0],&dupelist); - if(rc!=0) - { - fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc); - free_keylist(dupelist); - return rc; - } - - count++; - } - } - - each=ldap_next_entry(ldap,each); - } - - if(err==LDAP_SIZELIMIT_EXCEEDED) - { - if(count==1) - fprintf(console,"gpgkeys: search results exceeded server limit." - " First %d result shown.\n",count); - else - fprintf(console,"gpgkeys: search results exceeded server limit." - " First %d results shown.\n",count); - } - - free_keylist(dupelist); - dupelist=NULL; - - if(count<1) - fprintf(output,"info:1:0\n"); - else - { - fprintf(output,"info:1:%d\n",count); - - each=ldap_first_entry(ldap,res); - while(each!=NULL) - { - char **certid; - - certid=ldap_get_values(ldap,each,"pgpcertid"); - if(certid!=NULL) - { - LDAPMessage *uids; - - /* Have we seen this certid before? */ - if(!key_in_keylist(certid[0],dupelist)) - { - int rc=add_key_to_keylist(certid[0],&dupelist); - if(rc) - { - fprintf(output,"SEARCH %s FAILED %d\n",searchkey,rc); - free_keylist(dupelist); - ldap_value_free(certid); - ldap_msgfree(res); - return rc; - } - - fprintf(output,"pub:%s:",certid[0]); - - vals=ldap_get_values(ldap,each,"pgpkeytype"); - if(vals!=NULL) - { - /* The LDAP server doesn't exactly handle this - well. */ - if(strcasecmp(vals[0],"RSA")==0) - fprintf(output,"1"); - else if(strcasecmp(vals[0],"DSS/DH")==0) - fprintf(output,"17"); - ldap_value_free(vals); - } - - fputc(':',output); - - vals=ldap_get_values(ldap,each,"pgpkeysize"); - if(vals!=NULL) - { - /* Not sure why, but some keys are listed with a - key size of 0. Treat that like an - unknown. */ - if(atoi(vals[0])>0) - fprintf(output,"%d",atoi(vals[0])); - ldap_value_free(vals); - } - - fputc(':',output); - - /* YYYYMMDDHHmmssZ */ - - vals=ldap_get_values(ldap,each,"pgpkeycreatetime"); - if(vals!=NULL && strlen(vals[0])==15) - { - fprintf(output,"%u", - (unsigned int)ldap2epochtime(vals[0])); - ldap_value_free(vals); - } - - fputc(':',output); - - vals=ldap_get_values(ldap,each,"pgpkeyexpiretime"); - if(vals!=NULL && strlen(vals[0])==15) - { - fprintf(output,"%u", - (unsigned int)ldap2epochtime(vals[0])); - ldap_value_free(vals); - } - - fputc(':',output); - - vals=ldap_get_values(ldap,each,"pgprevoked"); - if(vals!=NULL) - { - if(atoi(vals[0])==1) - fprintf(output,"r"); - ldap_value_free(vals); - } - - vals=ldap_get_values(ldap,each,"pgpdisabled"); - if(vals!=NULL) - { - if(atoi(vals[0])==1) - fprintf(output,"d"); - ldap_value_free(vals); - } - -#if 0 - /* This is not yet specified in the keyserver - protocol, but may be someday. */ - fputc(':',output); - - vals=ldap_get_values(ldap,each,"modifytimestamp"); - if(vals!=NULL && strlen(vals[0])==15) - { - fprintf(output,"%u", - (unsigned int)ldap2epochtime(vals[0])); - ldap_value_free(vals); - } -#endif - - fprintf(output,"\n"); - - /* Now print all the uids that have this certid */ - uids=ldap_first_entry(ldap,res); - while(uids!=NULL) - { - vals=ldap_get_values(ldap,uids,"pgpcertid"); - if(vals!=NULL) - { - if(strcasecmp(certid[0],vals[0])==0) - { - char **uidvals; - - fprintf(output,"uid:"); - - uidvals=ldap_get_values(ldap,uids,"pgpuserid"); - if(uidvals!=NULL) - { - /* Need to escape any colons */ - printquoted(output,uidvals[0],':'); - ldap_value_free(uidvals); - } - - fprintf(output,"\n"); - } - - ldap_value_free(vals); - } - - uids=ldap_next_entry(ldap,uids); - } - } - - ldap_value_free(certid); - } - - each=ldap_next_entry(ldap,each); - } - } - - ldap_msgfree(res); - free_keylist(dupelist); - - fprintf(output,"SEARCH %s END\n",searchkey); - - return KEYSERVER_OK; -} - -static void -fail_all(struct keylist *keylist,int err) -{ - if(!keylist) - return; - - if(opt->action==KS_SEARCH) - { - fprintf(output,"SEARCH "); - while(keylist) - { - fprintf(output,"%s ",keylist->str); - keylist=keylist->next; - } - fprintf(output,"FAILED %d\n",err); - } - else - while(keylist) - { - fprintf(output,"KEY %s FAILED %d\n",keylist->str,err); - keylist=keylist->next; - } -} - -static int -find_basekeyspacedn(void) -{ - int err,i; - char *attr[]={"namingContexts",NULL,NULL,NULL}; - LDAPMessage *res; - char **context; - - /* Look for namingContexts */ - err=ldap_search_s(ldap,"",LDAP_SCOPE_BASE,"(objectClass=*)",attr,0,&res); - if(err==LDAP_SUCCESS) - { - context=ldap_get_values(ldap,res,"namingContexts"); - if(context) - { - attr[0]="pgpBaseKeySpaceDN"; - attr[1]="pgpVersion"; - attr[2]="pgpSoftware"; - - real_ldap=1; - - /* We found some, so try each namingContext as the search base - and look for pgpBaseKeySpaceDN. Because we found this, we - know we're talking to a regular-ish LDAP server and not a - LDAP keyserver. */ - - for(i=0;context[i] && !basekeyspacedn;i++) - { - char **vals; - LDAPMessage *si_res; - char *object; - - object=malloc(17+strlen(context[i])+1); - if(!object) - return -1; - - strcpy(object,"cn=pgpServerInfo,"); - strcat(object,context[i]); - - err=ldap_search_s(ldap,object,LDAP_SCOPE_BASE, - "(objectClass=*)",attr,0,&si_res); - free(object); - - if(err==LDAP_NO_SUCH_OBJECT) - continue; - else if(err!=LDAP_SUCCESS) - return err; - - vals=ldap_get_values(ldap,si_res,"pgpBaseKeySpaceDN"); - if(vals) - { - basekeyspacedn=strdup(vals[0]); - ldap_value_free(vals); - } - - if(opt->verbose>1) - { - vals=ldap_get_values(ldap,si_res,"pgpSoftware"); - if(vals) - { - fprintf(console,"Server: \t%s\n",vals[0]); - ldap_value_free(vals); - } - - vals=ldap_get_values(ldap,si_res,"pgpVersion"); - if(vals) - { - fprintf(console,"Version:\t%s\n",vals[0]); - ldap_value_free(vals); - } - } - - ldap_msgfree(si_res); - } - - ldap_value_free(context); - } - - ldap_msgfree(res); - } - else - { - /* We don't have an answer yet, which means the server might be - a LDAP keyserver. */ - char **vals; - LDAPMessage *si_res; - - attr[0]="pgpBaseKeySpaceDN"; - attr[1]="version"; - attr[2]="software"; - - err=ldap_search_s(ldap,"cn=pgpServerInfo",LDAP_SCOPE_BASE, - "(objectClass=*)",attr,0,&si_res); - if(err!=LDAP_SUCCESS) - return err; - - /* For the LDAP keyserver, this is always "OU=ACTIVE,O=PGP - KEYSPACE,C=US", but it might not be in the future. */ - - vals=ldap_get_values(ldap,si_res,"baseKeySpaceDN"); - if(vals) - { - basekeyspacedn=strdup(vals[0]); - ldap_value_free(vals); - } - - if(opt->verbose>1) - { - vals=ldap_get_values(ldap,si_res,"software"); - if(vals) - { - fprintf(console,"Server: \t%s\n",vals[0]); - ldap_value_free(vals); - } - } - - vals=ldap_get_values(ldap,si_res,"version"); - if(vals) - { - if(opt->verbose>1) - fprintf(console,"Version:\t%s\n",vals[0]); - - /* If the version is high enough, use the new pgpKeyV2 - attribute. This design if iffy at best, but it matches how - PGP does it. I figure the NAI folks assumed that there would - never be a LDAP keyserver vendor with a different numbering - scheme. */ - if(atoi(vals[0])>1) - pgpkeystr="pgpKeyV2"; - - ldap_value_free(vals); - } - - ldap_msgfree(si_res); - } - - return LDAP_SUCCESS; -} - -static void -show_help (FILE *fp) -{ - fprintf (fp,"-h, --help\thelp\n"); - fprintf (fp,"-V\t\tmachine readable version\n"); - fprintf (fp,"--version\thuman readable version\n"); - fprintf (fp,"-o\t\toutput to this file\n"); -} - -int -main(int argc,char *argv[]) -{ - int port=0,arg,err,ret=KEYSERVER_INTERNAL_ERROR; - char line[MAX_LINE],*binddn=NULL,*bindpw=NULL; - int failed=0,use_ssl=0,use_tls=0,bound=0; - struct keylist *keylist=NULL,*keyptr=NULL; - - console=stderr; - - /* Kludge to implement standard GNU options. */ - if (argc > 1 && !strcmp (argv[1], "--version")) - { - fputs ("gpgkeys_ldap ("GNUPG_NAME") " VERSION"\n", stdout); - return 0; - } - else if (argc > 1 && !strcmp (argv[1], "--help")) - { - show_help (stdout); - return 0; - } - - while((arg=getopt(argc,argv,"hVo:"))!=-1) - switch(arg) - { - default: - case 'h': - show_help (console); - return KEYSERVER_OK; - - case 'V': - fprintf(stdout,"%d\n%s\n",KEYSERVER_PROTO_VERSION,VERSION); - return KEYSERVER_OK; - - case 'o': - output=fopen(optarg,"w"); - if(output==NULL) - { - fprintf(console,"gpgkeys: Cannot open output file '%s': %s\n", - optarg,strerror(errno)); - return KEYSERVER_INTERNAL_ERROR; - } - - break; - } - - if(argc>optind) - { - input=fopen(argv[optind],"r"); - if(input==NULL) - { - fprintf(console,"gpgkeys: Cannot open input file '%s': %s\n", - argv[optind],strerror(errno)); - return KEYSERVER_INTERNAL_ERROR; - } - } - - if(input==NULL) - input=stdin; - - if(output==NULL) - output=stdout; - - opt=init_ks_options(); - if(!opt) - return KEYSERVER_NO_MEMORY; - - /* Get the command and info block */ - - while(fgets(line,MAX_LINE,input)!=NULL) - { - char optionstr[MAX_OPTION+1]; - - if(line[0]=='\n') - break; - - err=parse_ks_options(line,opt); - if(err>0) - { - ret=err; - goto fail; - } - else if(err==0) - continue; - - if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",optionstr)==1) - { - int no=0; - char *start=&optionstr[0]; - - optionstr[MAX_OPTION]='\0'; - - if(strncasecmp(optionstr,"no-",3)==0) - { - no=1; - start=&optionstr[3]; - } - - if(strncasecmp(start,"tls",3)==0) - { - if(no) - use_tls=0; - else if(start[3]=='=') - { - if(strcasecmp(&start[4],"no")==0) - use_tls=0; - else if(strcasecmp(&start[4],"try")==0) - use_tls=1; - else if(strcasecmp(&start[4],"warn")==0) - use_tls=2; - else if(strcasecmp(&start[4],"require")==0) - use_tls=3; - else - use_tls=1; - } - else if(start[3]=='\0') - use_tls=1; - } - else if(strncasecmp(start,"basedn",6)==0) - { - if(no) - { - free(basekeyspacedn); - basekeyspacedn=NULL; - } - else if(start[6]=='=') - { - free(basekeyspacedn); - basekeyspacedn=strdup(&start[7]); - if(!basekeyspacedn) - { - fprintf(console,"gpgkeys: out of memory while creating " - "base DN\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - real_ldap=1; - } - } - else if(strncasecmp(start,"binddn",6)==0) - { - if(no) - { - free(binddn); - binddn=NULL; - } - else if(start[6]=='=') - { - free(binddn); - binddn=strdup(&start[7]); - if(!binddn) - { - fprintf(console,"gpgkeys: out of memory while creating " - "bind DN\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - real_ldap=1; - } - } - else if(strncasecmp(start,"bindpw",6)==0) - { - if(no) - { - free(bindpw); - bindpw=NULL; - } - else if(start[6]=='=') - { - free(bindpw); - bindpw=strdup(&start[7]); - if(!bindpw) - { - fprintf(console,"gpgkeys: out of memory while creating " - "bind password\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - real_ldap=1; - } - } - - continue; - } - } - - if(!opt->scheme) - { - fprintf(console,"gpgkeys: no scheme supplied!\n"); - ret=KEYSERVER_SCHEME_NOT_FOUND; - goto fail; - } - - if(strcasecmp(opt->scheme,"ldaps")==0) - { - port=636; - use_ssl=1; - } - - if(opt->port) - port=atoi(opt->port); - - if(!opt->host) - { - fprintf(console,"gpgkeys: no keyserver host provided\n"); - goto fail; - } - - if(opt->timeout && register_timeout()==-1) - { - fprintf(console,"gpgkeys: unable to register timeout handler\n"); - return KEYSERVER_INTERNAL_ERROR; - } - -#if defined(LDAP_OPT_X_TLS_CACERTFILE) && defined(HAVE_LDAP_SET_OPTION) - - if(opt->ca_cert_file) - { - err=ldap_set_option(NULL,LDAP_OPT_X_TLS_CACERTFILE,opt->ca_cert_file); - if(err!=LDAP_SUCCESS) - { - fprintf(console,"gpgkeys: unable to set ca-cert-file: %s\n", - ldap_err2string(err)); - ret=KEYSERVER_INTERNAL_ERROR; - goto fail; - } - } -#endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */ - - /* SSL trumps TLS */ - if(use_ssl) - use_tls=0; - - /* If it's a GET or a SEARCH, the next thing to come in is the - keyids. If it's a SEND, then there are no keyids. */ - - if(opt->action==KS_SEND) - while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n'); - else if(opt->action==KS_GET - || opt->action==KS_GETNAME || opt->action==KS_SEARCH) - { - for(;;) - { - struct keylist *work; - - if(fgets(line,MAX_LINE,input)==NULL) - break; - else - { - if(line[0]=='\n' || line[0]=='\0') - break; - - work=malloc(sizeof(struct keylist)); - if(work==NULL) - { - fprintf(console,"gpgkeys: out of memory while " - "building key list\n"); - ret=KEYSERVER_NO_MEMORY; - goto fail; - } - - strcpy(work->str,line); - - /* Trim the trailing \n */ - work->str[strlen(line)-1]='\0'; - - work->next=NULL; - - /* Always attach at the end to keep the list in proper - order for searching */ - if(keylist==NULL) - keylist=work; - else - keyptr->next=work; - - keyptr=work; - } - } - } - else - { - fprintf(console,"gpgkeys: no keyserver command specified\n"); - goto fail; - } - - /* Send the response */ - - fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION); - fprintf(output,"PROGRAM %s\n\n",VERSION); - - if(opt->verbose>1) - { - fprintf(console,"Host:\t\t%s\n",opt->host); - if(port) - fprintf(console,"Port:\t\t%d\n",port); - fprintf(console,"Command:\t%s\n",ks_action_to_string(opt->action)); - } - - if(opt->debug) - { -#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(HAVE_LDAP_SET_OPTION) - err=ldap_set_option(NULL,LDAP_OPT_DEBUG_LEVEL,&opt->debug); - if(err!=LDAP_SUCCESS) - fprintf(console,"gpgkeys: unable to set debug mode: %s\n", - ldap_err2string(err)); - else - fprintf(console,"gpgkeys: debug level %d\n",opt->debug); -#else - fprintf(console,"gpgkeys: not built with debugging support\n"); -#endif - } - - /* We have a timeout set for the setup stuff since it could time out - as well. */ - set_timeout(opt->timeout); - - /* Note that this tries all A records on a given host (or at least, - OpenLDAP does). */ - ldap=ldap_init(opt->host,port); - if(ldap==NULL) - { - fprintf(console,"gpgkeys: internal LDAP init error: %s\n", - strerror(errno)); - fail_all(keylist,KEYSERVER_INTERNAL_ERROR); - goto fail; - } - - if(use_ssl) - { -#if defined(LDAP_OPT_X_TLS) && defined(HAVE_LDAP_SET_OPTION) - int ssl=LDAP_OPT_X_TLS_HARD; - - err=ldap_set_option(ldap,LDAP_OPT_X_TLS,&ssl); - if(err!=LDAP_SUCCESS) - { - fprintf(console,"gpgkeys: unable to make SSL connection: %s\n", - ldap_err2string(err)); - fail_all(keylist,ldap_err_to_gpg_err(err)); - goto fail; - } - - if(!opt->flags.check_cert) - ssl=LDAP_OPT_X_TLS_NEVER; - - err=ldap_set_option(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,&ssl); - if(err!=LDAP_SUCCESS) - { - fprintf(console, - "gpgkeys: unable to set certificate validation: %s\n", - ldap_err2string(err)); - fail_all(keylist,ldap_err_to_gpg_err(err)); - goto fail; - } -#else - fprintf(console,"gpgkeys: unable to make SSL connection: %s\n", - "not built with LDAPS support"); - fail_all(keylist,KEYSERVER_INTERNAL_ERROR); - goto fail; -#endif - } - - if(!basekeyspacedn) - if((err=find_basekeyspacedn()) || !basekeyspacedn) - { - fprintf(console,"gpgkeys: unable to retrieve LDAP base: %s\n", - err?ldap_err2string(err):"not found"); - fail_all(keylist,ldap_err_to_gpg_err(err)); - goto fail; - } - - /* use_tls: 0=don't use, 1=try silently to use, 2=try loudly to use, - 3=force use. */ - if(use_tls) - { - if(!real_ldap) - { - if(use_tls>=2) - fprintf(console,"gpgkeys: unable to start TLS: %s\n", - "not supported by the NAI LDAP keyserver"); - if(use_tls==3) - { - fail_all(keylist,KEYSERVER_INTERNAL_ERROR); - goto fail; - } - } - else - { -#if defined(HAVE_LDAP_START_TLS_S) && defined(HAVE_LDAP_SET_OPTION) - int ver=LDAP_VERSION3; - - err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver); - -#ifdef LDAP_OPT_X_TLS - if(err==LDAP_SUCCESS) - { - if(opt->flags.check_cert) - ver=LDAP_OPT_X_TLS_HARD; - else - ver=LDAP_OPT_X_TLS_NEVER; - - err=ldap_set_option(NULL,LDAP_OPT_X_TLS_REQUIRE_CERT,&ver); - } -#endif - - if(err==LDAP_SUCCESS) - err=ldap_start_tls_s(ldap,NULL,NULL); - - if(err!=LDAP_SUCCESS) - { - if(use_tls>=2 || opt->verbose>2) - fprintf(console,"gpgkeys: unable to start TLS: %s\n", - ldap_err2string(err)); - /* Are we forcing it? */ - if(use_tls==3) - { - fail_all(keylist,ldap_err_to_gpg_err(err)); - goto fail; - } - } - else if(opt->verbose>1) - fprintf(console,"gpgkeys: TLS started successfully.\n"); -#else - if(use_tls>=2) - fprintf(console,"gpgkeys: unable to start TLS: %s\n", - "not built with TLS support"); - if(use_tls==3) - { - fail_all(keylist,KEYSERVER_INTERNAL_ERROR); - goto fail; - } -#endif - } - } - - /* By default we don't bind as there is usually no need to. For - cases where the server needs some authentication, the user can - use binddn and bindpw for auth. */ - - if(binddn) - { -#ifdef HAVE_LDAP_SET_OPTION - int ver=LDAP_VERSION3; - - err=ldap_set_option(ldap,LDAP_OPT_PROTOCOL_VERSION,&ver); - if(err!=LDAP_SUCCESS) - { - fprintf(console,"gpgkeys: unable to go to LDAP 3: %s\n", - ldap_err2string(err)); - fail_all(keylist,ldap_err_to_gpg_err(err)); - goto fail; - } -#endif - - if(opt->verbose>2) - fprintf(console,"gpgkeys: LDAP bind to %s, pw %s\n",binddn, - bindpw?">not shown<":">none<"); - err=ldap_simple_bind_s(ldap,binddn,bindpw); - if(err!=LDAP_SUCCESS) - { - fprintf(console,"gpgkeys: internal LDAP bind error: %s\n", - ldap_err2string(err)); - fail_all(keylist,ldap_err_to_gpg_err(err)); - goto fail; - } - else - bound=1; - } - - if(opt->action==KS_GET) - { - keyptr=keylist; - - while(keyptr!=NULL) - { - set_timeout(opt->timeout); - - if(get_key(keyptr->str)!=KEYSERVER_OK) - failed++; - - keyptr=keyptr->next; - } - } - else if(opt->action==KS_GETNAME) - { - keyptr=keylist; - - while(keyptr!=NULL) - { - set_timeout(opt->timeout); - - if(get_name(keyptr->str)!=KEYSERVER_OK) - failed++; - - keyptr=keyptr->next; - } - } - else if(opt->action==KS_SEND) - { - int eof_seen = 0; - - do - { - set_timeout(opt->timeout); - - if(real_ldap) - { - if (send_key(&eof_seen) != KEYSERVER_OK) - failed++; - } - else - { - if (send_key_keyserver(&eof_seen) != KEYSERVER_OK) - failed++; - } - } - while (!eof_seen); - } - else if(opt->action==KS_SEARCH) - { - char *searchkey=NULL; - int len=0; - - set_timeout(opt->timeout); - - /* To search, we stick a * in between each key to search for. - This means that if the user enters words, they'll get - "enters*words". If the user "enters words", they'll get - "enters words" */ - - keyptr=keylist; - while(keyptr!=NULL) - { - len+=strlen(keyptr->str)+1; - keyptr=keyptr->next; - } - - searchkey=malloc((len*3)+1); - if(searchkey==NULL) - { - ret=KEYSERVER_NO_MEMORY; - fail_all(keylist,KEYSERVER_NO_MEMORY); - goto fail; - } - - searchkey[0]='\0'; - - keyptr=keylist; - while(keyptr!=NULL) - { - ldap_quote(searchkey,keyptr->str); - strcat(searchkey,"*"); - keyptr=keyptr->next; - } - - /* Nail that last "*" */ - if(*searchkey) - searchkey[strlen(searchkey)-1]='\0'; - - if(search_key(searchkey)!=KEYSERVER_OK) - failed++; - - free(searchkey); - } - else - assert (!"bad action"); - - if(!failed) - ret=KEYSERVER_OK; - - fail: - - while(keylist!=NULL) - { - struct keylist *current=keylist; - keylist=keylist->next; - free(current); - } - - if(input!=stdin) - fclose(input); - - if(output!=stdout) - fclose(output); - - free_ks_options(opt); - - if(ldap!=NULL && bound) - ldap_unbind_s(ldap); - - free(basekeyspacedn); - - return ret; -} diff --git a/keyserver/ksutil.c b/keyserver/ksutil.c deleted file mode 100644 index 1f85f165f..000000000 --- a/keyserver/ksutil.c +++ /dev/null @@ -1,624 +0,0 @@ -/* ksutil.c - general keyserver utility functions - * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * 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 -#ifdef HAVE_SIGNAL_H -# include -#endif -#include -#include -#include -#include - -#ifdef HAVE_W32_SYSTEM -#include -#endif - -#ifdef HAVE_LIBCURL -#include -#else -#include "curl-shim.h" -#endif -#include "util.h" -#include "keyserver.h" -#include "ksutil.h" - -#ifdef HAVE_DOSISH_SYSTEM - -unsigned int set_timeout(unsigned int seconds) {return 0;} -int register_timeout(void) {return 0;} - -#else - -static void -catch_alarm(int foo) -{ - (void)foo; - _exit(KEYSERVER_TIMEOUT); -} - -unsigned int -set_timeout(unsigned int seconds) -{ - return alarm(seconds); -} - -int -register_timeout(void) -{ -#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION) - struct sigaction act; - - act.sa_handler=catch_alarm; - sigemptyset(&act.sa_mask); - act.sa_flags=0; - return sigaction(SIGALRM,&act,NULL); -#else - if(signal(SIGALRM,catch_alarm)==SIG_ERR) - return -1; - else - return 0; -#endif -} - -#endif /* !HAVE_DOSISH_SYSTEM */ - -#ifdef HAVE_W32_SYSTEM -void -w32_init_sockets (void) -{ - static int initialized; - static WSADATA wsdata; - - if (!initialized) - { - WSAStartup (0x0202, &wsdata); - initialized = 1; - } -} -#endif /*HAVE_W32_SYSTEM*/ - - -struct ks_options * -init_ks_options(void) -{ - struct ks_options *opt; - - opt=calloc(1,sizeof(struct ks_options)); - - if(opt) - { - opt->action=KS_UNKNOWN; - opt->flags.include_revoked=1; - opt->flags.include_subkeys=1; - opt->flags.check_cert=1; - opt->timeout=DEFAULT_KEYSERVER_TIMEOUT; - opt->path=strdup("/"); - if(!opt->path) - { - free(opt); - opt=NULL; - } - } - - return opt; -} - -void -free_ks_options(struct ks_options *opt) -{ - if(opt) - { - free(opt->host); - free(opt->port); - free(opt->scheme); - free(opt->auth); - free(opt->path); - free(opt->opaque); - free(opt->ca_cert_file); - free(opt); - } -} - -/* Returns 0 if we "ate" the line. Returns >0, a KEYSERVER_ error - code if that error applies. Returns -1 if we did not match the - line at all. */ -int -parse_ks_options(char *line,struct ks_options *opt) -{ - int version; - char command[MAX_COMMAND+1]; - char host[MAX_HOST+1]; - char port[MAX_PORT+1]; - char scheme[MAX_SCHEME+1]; - char auth[MAX_AUTH+1]; - char path[URLMAX_PATH+1]; - char opaque[MAX_OPAQUE+1]; - char option[MAX_OPTION+1]; - - if(line[0]=='#') - return 0; - - if(sscanf(line,"COMMAND %" MKSTRING(MAX_COMMAND) "s\n",command)==1) - { - command[MAX_COMMAND]='\0'; - - if(strcasecmp(command,"get")==0) - opt->action=KS_GET; - else if(strcasecmp(command,"getname")==0) - opt->action=KS_GETNAME; - else if(strcasecmp(command,"send")==0) - opt->action=KS_SEND; - else if(strcasecmp(command,"search")==0) - opt->action=KS_SEARCH; - - return 0; - } - - if(sscanf(line,"HOST %" MKSTRING(MAX_HOST) "s\n",host)==1) - { - host[MAX_HOST]='\0'; - free(opt->host); - opt->host=strdup(host); - if(!opt->host) - return KEYSERVER_NO_MEMORY; - return 0; - } - - if(sscanf(line,"PORT %" MKSTRING(MAX_PORT) "s\n",port)==1) - { - port[MAX_PORT]='\0'; - free(opt->port); - opt->port=strdup(port); - if(!opt->port) - return KEYSERVER_NO_MEMORY; - return 0; - } - - if(sscanf(line,"SCHEME %" MKSTRING(MAX_SCHEME) "s\n",scheme)==1) - { - scheme[MAX_SCHEME]='\0'; - free(opt->scheme); - opt->scheme=strdup(scheme); - if(!opt->scheme) - return KEYSERVER_NO_MEMORY; - return 0; - } - - if(sscanf(line,"AUTH %" MKSTRING(MAX_AUTH) "s\n",auth)==1) - { - auth[MAX_AUTH]='\0'; - free(opt->auth); - opt->auth=strdup(auth); - if(!opt->auth) - return KEYSERVER_NO_MEMORY; - return 0; - } - - if(sscanf(line,"PATH %" MKSTRING(URLMAX_PATH) "s\n",path)==1) - { - path[URLMAX_PATH]='\0'; - free(opt->path); - opt->path=strdup(path); - if(!opt->path) - return KEYSERVER_NO_MEMORY; - return 0; - } - - if(sscanf(line,"OPAQUE %" MKSTRING(MAX_OPAQUE) "s\n",opaque)==1) - { - opaque[MAX_OPAQUE]='\0'; - free(opt->opaque); - opt->opaque=strdup(opaque); - if(!opt->opaque) - return KEYSERVER_NO_MEMORY; - return 0; - } - - if(sscanf(line,"VERSION %d\n",&version)==1) - { - if(version!=KEYSERVER_PROTO_VERSION) - return KEYSERVER_VERSION_ERROR; - - return 0; - } - - if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",option)==1) - { - int no=0; - char *start=&option[0]; - - option[MAX_OPTION]='\0'; - - if(strncasecmp(option,"no-",3)==0) - { - no=1; - start=&option[3]; - } - - if(strncasecmp(start,"verbose",7)==0) - { - if(no) - opt->verbose=0; - else if(start[7]=='=') - opt->verbose=atoi(&start[8]); - else - opt->verbose++; - } - else if(strcasecmp(start,"include-disabled")==0) - { - if(no) - opt->flags.include_disabled=0; - else - opt->flags.include_disabled=1; - } - else if(strcasecmp(start,"include-revoked")==0) - { - if(no) - opt->flags.include_revoked=0; - else - opt->flags.include_revoked=1; - } - else if(strcasecmp(start,"include-subkeys")==0) - { - if(no) - opt->flags.include_subkeys=0; - else - opt->flags.include_subkeys=1; - } - else if(strcasecmp(start,"check-cert")==0) - { - if(no) - opt->flags.check_cert=0; - else - opt->flags.check_cert=1; - } - else if(strncasecmp(start,"debug",5)==0) - { - if(no) - opt->debug=0; - else if(start[5]=='=') - opt->debug=atoi(&start[6]); - else if(start[5]=='\0') - opt->debug=1; - } - else if(strncasecmp(start,"timeout",7)==0) - { - if(no) - opt->timeout=0; - else if(start[7]=='=') - opt->timeout=atoi(&start[8]); - else if(start[7]=='\0') - opt->timeout=DEFAULT_KEYSERVER_TIMEOUT; - } - else if(strncasecmp(start,"ca-cert-file",12)==0) - { - if(no) - { - free(opt->ca_cert_file); - opt->ca_cert_file=NULL; - } - else if(start[12]=='=') - { - free(opt->ca_cert_file); - opt->ca_cert_file = make_filename_try (start+13, NULL); - if(!opt->ca_cert_file) - return KEYSERVER_NO_MEMORY; - } - } - } - - return -1; -} - -const char * -ks_action_to_string(enum ks_action action) -{ - switch(action) - { - case KS_UNKNOWN: return "UNKNOWN"; - case KS_GET: return "GET"; - case KS_GETNAME: return "GETNAME"; - case KS_SEND: return "SEND"; - case KS_SEARCH: return "SEARCH"; - } - - return "?"; -} - -/* Canonicalize CRLF to just LF by stripping CRs. This actually makes - sense, since on Unix-like machines LF is correct, and on win32-like - machines, our output buffer is opened in textmode and will - re-canonicalize line endings back to CRLF. Since we only need to - handle armored keys, we don't have to worry about odd cases like - CRCRCR and the like. */ - -void -print_nocr(FILE *stream,const char *str) -{ - while(*str) - { - if(*str!='\r') - fputc(*str,stream); - str++; - } -} - -enum ks_search_type -classify_ks_search(const char **search) -{ - switch(**search) - { - case '*': - (*search)++; - return KS_SEARCH_SUBSTR; - case '=': - (*search)++; - return KS_SEARCH_EXACT; - case '<': - (*search)++; - return KS_SEARCH_MAIL; - case '@': - (*search)++; - return KS_SEARCH_MAILSUB; - case '0': - if((*search)[1]=='x') - { - if(strlen(*search)==10 - && strspn(*search,"abcdefABCDEF1234567890x")==10) - { - (*search)+=2; - return KS_SEARCH_KEYID_SHORT; - } - else if(strlen(*search)==18 - && strspn(*search,"abcdefABCDEF1234567890x")==18) - { - (*search)+=2; - return KS_SEARCH_KEYID_LONG; - } - } - /* fall through */ - default: - return KS_SEARCH_SUBSTR; - } -} - -int -curl_err_to_gpg_err(CURLcode error) -{ - switch(error) - { - case CURLE_OK: return KEYSERVER_OK; - case CURLE_UNSUPPORTED_PROTOCOL: return KEYSERVER_SCHEME_NOT_FOUND; - case CURLE_COULDNT_CONNECT: return KEYSERVER_UNREACHABLE; - case CURLE_FTP_COULDNT_RETR_FILE: return KEYSERVER_KEY_NOT_FOUND; - default: return KEYSERVER_INTERNAL_ERROR; - } -} - -#define B64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - -static void -curl_armor_writer(const unsigned char *buf,size_t size,void *cw_ctx) -{ - struct curl_writer_ctx *ctx=cw_ctx; - size_t idx=0; - - while(idxarmor_remaining<3 && idxarmor_remaining++,idx++) - ctx->armor_ctx[ctx->armor_remaining]=buf[idx]; - - if(ctx->armor_remaining==3) - { - /* Top 6 bytes of ctx->armor_ctx[0] */ - fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream); - /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of - ctx->armor_ctx[1] */ - fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30) - |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream); - /* Bottom 4 bytes of ctx->armor_ctx[1] and top 2 bytes of - ctx->armor_ctx[2] */ - fputc(B64[(((ctx->armor_ctx[1]<<2)&0x3C) - |((ctx->armor_ctx[2]>>6)&0x03))&0x3F],ctx->stream); - /* Bottom 6 bytes of ctx->armor_ctx[2] */ - fputc(B64[(ctx->armor_ctx[2]&0x3F)],ctx->stream); - - ctx->linelen+=4; - if(ctx->linelen>=70) - { - fputc('\n',ctx->stream); - ctx->linelen=0; - } - - ctx->armor_remaining=0; - } - } - -} - -size_t -curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx) -{ - struct curl_writer_ctx *ctx=cw_ctx; - const char *buf=ptr; - size_t i; - - if(!ctx->flags.initialized) - { - if(size*nmemb==0) - return 0; - - /* The object we're fetching is in binary form */ - if(*buf&0x80) - { - ctx->flags.armor=1; - fprintf(ctx->stream,BEGIN"\n\n"); - } - else - ctx->marker=BEGIN; - - ctx->flags.initialized=1; - } - - if(ctx->flags.armor) - curl_armor_writer(ptr,size*nmemb,cw_ctx); - else - { - /* scan the incoming data for our marker */ - for(i=0;!ctx->flags.done && i<(size*nmemb);i++) - { - if(buf[i]==ctx->marker[ctx->markeridx]) - { - ctx->markeridx++; - if(ctx->marker[ctx->markeridx]=='\0') - { - if(ctx->flags.begun) - ctx->flags.done=1; - else - { - /* We've found the BEGIN marker, so now we're - looking for the END marker. */ - ctx->flags.begun=1; - ctx->marker=END; - ctx->markeridx=0; - fprintf(ctx->stream,BEGIN); - continue; - } - } - } - else - ctx->markeridx=0; - - if(ctx->flags.begun) - { - /* Canonicalize CRLF to just LF by stripping CRs. This - actually makes sense, since on Unix-like machines LF - is correct, and on win32-like machines, our output - buffer is opened in textmode and will re-canonicalize - line endings back to CRLF. Since this code is just - for handling armored keys, we don't have to worry - about odd cases like CRCRCR and the like. */ - - if(buf[i]!='\r') - fputc(buf[i],ctx->stream); - } - } - } - - return size*nmemb; -} - -void -curl_writer_finalize(struct curl_writer_ctx *ctx) -{ - if(ctx->flags.armor) - { - if(ctx->armor_remaining==2) - { - /* Top 6 bytes of ctx->armorctx[0] */ - fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream); - /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of - ctx->armor_ctx[1] */ - fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30) - |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream); - /* Bottom 4 bytes of ctx->armor_ctx[1] */ - fputc(B64[((ctx->armor_ctx[1]<<2)&0x3C)],ctx->stream); - /* Pad */ - fputc('=',ctx->stream); - } - else if(ctx->armor_remaining==1) - { - /* Top 6 bytes of ctx->armor_ctx[0] */ - fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream); - /* Bottom 2 bytes of ctx->armor_ctx[0] */ - fputc(B64[((ctx->armor_ctx[0]<<4)&0x30)],ctx->stream); - /* Pad */ - fputc('=',ctx->stream); - /* Pad */ - fputc('=',ctx->stream); - } - - fprintf(ctx->stream,"\n"END); - ctx->flags.done=1; - } -} - - -int -ks_hextobyte (const char *s) -{ - int c; - - if ( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if ( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if ( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if ( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if ( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if ( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} - - -/* Non localized version of toupper. */ -int -ks_toupper (int c) -{ - if (c >= 'a' && c <= 'z') - c &= ~0x20; - return c; -} - - -/* Non localized version of strcasecmp. */ -int -ks_strcasecmp (const char *a, const char *b) -{ - if (a == b) - return 0; - - for (; *a && *b; a++, b++) - { - if (*a != *b && ks_toupper (*a) != ks_toupper (*b)) - break; - } - return *a == *b? 0 : (ks_toupper (*a) - ks_toupper (*b)); -} diff --git a/keyserver/ksutil.h b/keyserver/ksutil.h deleted file mode 100644 index 9f51359df..000000000 --- a/keyserver/ksutil.h +++ /dev/null @@ -1,149 +0,0 @@ -/* ksutil.h - * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * 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 -#else -#include "curl-shim.h" -#endif - -/* MAX_LINE must be at least 1 larger than the largest item we expect - to receive, including the name tag ("COMMAND", "PORT", etc) and - space between. In practice, that means it should be - strlen("OPAQUE")+1+sizeof_opaque+1 */ -#define MAX_LINE (6+1+1024+1) - -#define MAX_COMMAND 7 -#define MAX_OPTION 256 -#define MAX_SCHEME 20 -#define MAX_OPAQUE 1024 -#define MAX_AUTH 128 -#define MAX_HOST 80 -#define MAX_PORT 10 -#define URLMAX_PATH 1024 -#define MAX_PROXY 128 -#define MAX_URL (MAX_SCHEME+1+3+MAX_AUTH+1+1+MAX_HOST+1+1 \ - +MAX_PORT+1+1+URLMAX_PATH+1+50) - -#define STRINGIFY(x) #x -#define MKSTRING(x) STRINGIFY(x) - -#define BEGIN "-----BEGIN PGP PUBLIC KEY BLOCK-----" -#define END "-----END PGP PUBLIC KEY BLOCK-----" - -#ifdef __riscos__ -#define HTTP_PROXY_ENV "GnuPG$HttpProxy" -#else -#define HTTP_PROXY_ENV "http_proxy" -#endif - -struct keylist -{ - char str[MAX_LINE]; - struct keylist *next; -}; - -/* 2 minutes seems reasonable */ -#define DEFAULT_KEYSERVER_TIMEOUT 120 - -unsigned int set_timeout(unsigned int seconds); -int register_timeout(void); - -#ifdef HAVE_W32_SYSTEM -void w32_init_sockets (void); -#endif - - -enum ks_action {KS_UNKNOWN=0,KS_GET,KS_GETNAME,KS_SEND,KS_SEARCH}; - -enum ks_search_type {KS_SEARCH_SUBSTR,KS_SEARCH_EXACT, - KS_SEARCH_MAIL,KS_SEARCH_MAILSUB, - KS_SEARCH_KEYID_LONG,KS_SEARCH_KEYID_SHORT}; - -struct ks_options -{ - enum ks_action action; - char *host; - char *port; - char *scheme; - char *auth; - char *path; - char *opaque; - struct - { - unsigned int include_disabled:1; - unsigned int include_revoked:1; - unsigned int include_subkeys:1; - unsigned int check_cert:1; - } flags; - unsigned int verbose; - unsigned int debug; - unsigned int timeout; - char *ca_cert_file; -}; - -struct ks_options *init_ks_options(void); -void free_ks_options(struct ks_options *opt); -int parse_ks_options(char *line,struct ks_options *opt); -const char *ks_action_to_string(enum ks_action action); -void print_nocr(FILE *stream,const char *str); -enum ks_search_type classify_ks_search(const char **search); - -int curl_err_to_gpg_err(CURLcode error); - -struct curl_writer_ctx -{ - struct - { - unsigned int initialized:1; - unsigned int begun:1; - unsigned int done:1; - unsigned int armor:1; - } flags; - - int armor_remaining; - unsigned char armor_ctx[3]; - int markeridx,linelen; - const char *marker; - FILE *stream; -}; - -size_t curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx); -void curl_writer_finalize(struct curl_writer_ctx *ctx); - -int ks_hextobyte (const char *s); -int ks_toupper (int c); -int ks_strcasecmp (const char *a, const char *b); - - -#endif /* !_KSUTIL_H_ */ diff --git a/keyserver/no-libgcrypt.c b/keyserver/no-libgcrypt.c deleted file mode 100644 index 2cce156a7..000000000 --- a/keyserver/no-libgcrypt.c +++ /dev/null @@ -1,107 +0,0 @@ -/* no-libgcrypt.c - Replacement functions for libgcrypt. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is free software; as a special exception the author gives - * unlimited permission to copy and/or distribute it, with or without - * modifications, as long as this notice is preserved. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include -#include -#include -#include - -#include "../common/util.h" -#include "i18n.h" - - -/* Replace libgcrypt's malloc functions which are used by - ../jnlib/libjnlib.a . ../common/util.h defines macros to map them - to xmalloc etc. */ -static void -out_of_memory (void) -{ - fprintf (stderr, "error allocating enough memory: %s\n", strerror (errno)); - exit (2); -} - - -void * -gcry_malloc (size_t n) -{ - return malloc (n); -} - -void * -gcry_xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - out_of_memory (); - return p; -} - -char * -gcry_strdup (const char *string) -{ - char *p = malloc (strlen (string)+1); - if (p) - strcpy (p, string); - return p; -} - - -void * -gcry_realloc (void *a, size_t n) -{ - return realloc (a, n); -} - -void * -gcry_xrealloc (void *a, size_t n) -{ - void *p = realloc (a, n); - if (!p) - out_of_memory (); - return p; -} - - - -void * -gcry_calloc (size_t n, size_t m) -{ - return calloc (n, m); -} - -void * -gcry_xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - out_of_memory (); - return p; -} - - -char * -gcry_xstrdup (const char *string) -{ - void *p = malloc (strlen (string)+1); - if (!p) - out_of_memory (); - strcpy( p, string ); - return p; -} - -void -gcry_free (void *a) -{ - if (a) - free (a); -}