diff options
141 files changed, 9778 insertions, 2136 deletions
@@ -15,9 +15,9 @@ copyrightable year that would otherwise be listed individually. List of Copyright holders ========================= - Copyright (C) 1997-2016 Werner Koch - Copyright (C) 1994-2016 Free Software Foundation, Inc. - Copyright (C) 2003-2013,2015-2016 g10 Code GmbH + Copyright (C) 1997-2017 Werner Koch + Copyright (C) 1994-2017 Free Software Foundation, Inc. + Copyright (C) 2003-2013,2015-2017 g10 Code GmbH Copyright (C) 2002 Klarälvdalens Datakonsult AB Copyright (C) 1995-1997, 2000-2007 Ulrich Drepper <drepper@gnu.ai.mit.edu> Copyright (C) 1994 X Consortium @@ -204,6 +204,10 @@ Yann E. MORIN <yann.morin.1998@free.fr> Arnaud Fontaine <arnaud.fontaine at ssi.gouv.fr> 2016-10-17:580484F4.8040806@ssi.gouv.fr: +Phil Pennock <phil.pennock@spodhuis.org> +Phil Pennock <phil@pennock-tech.com> +2017-01-19:20170119061225.GA26207@breadbox.private.spodhuis.org: + Other authors ============= @@ -244,8 +248,8 @@ COPYING.CC0) which basically puts them into the public domain. ========= - Copyright 1998-2016 Free Software Foundation, Inc. - Copyright 1997-2016 Werner Koch + Copyright 1998-2017 Free Software Foundation, Inc. + Copyright 1997-2017 Werner Koch This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/Makefile.am b/Makefile.am index 735c72b..e220f8b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ ACLOCAL_AMFLAGS = -I m4 DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun --enable-g13 \ - --enable-gpg2-is-gpg + --enable-gpg2-is-gpg --enable-gpgtar --enable-wks-tools --disable-ntbtls GITLOG_TO_CHANGELOG=gitlog-to-changelog @@ -1,3 +1,67 @@ +Noteworthy changes in version 2.1.18 (2017-01-23) +------------------------------------------------- + + * gpg: Remove bogus subkey signature while cleaning a key (with + export-clean, import-clean, or --edit-key's sub-command clean) + + * gpg: Allow freezing the clock with --faked-system-time. + + * gpg: New --export-option flag "backup", new --import-option flag + "restore". + + * gpg-agent: Fixed long delay due to a regression in the progress + callback code. + + * scd: Lots of code cleanup and internal changes. + + * scd: Improved the internal CCID driver. + + * dirmngr: Fixed problem with the DNS glue code (removal of the + trailing dot in domain names). + + * dirmngr: Make sure that Tor is actually enabled after changing the + conf file and sending SIGHUP or "gpgconf --reload dirmngr". + + * dirmngr: Fixed Tor access to IPv6 addresses. Note that current + versions of Tor may require that the flag "IPv6Traffic" is used + with the option "SocksPort" in torrc to actually allow IPv6 + traffic. + + * dirmngr: Fixed HKP for literally given IPv6 addresses. + + * dirmngr: Enabled reverse DNS lookups via Tor. + + * dirmngr: Added experimental SRV record lookup for WKD. + See commit 88dc3af3d4ae1afe1d5e136bc4c38bc4e7d4cd10 for details. + + * dirmngr: For HKP use "pgpkey-hkps" and "pgpkey-hkp" in SRV record + lookups. Avoid SRV record lookup when a port is explicitly + specified. This fixes a regression from the 1.4 and 2.0 behavior. + + * dirmngr: Gracefully handle a missing /etc/nsswitch.conf. Ignore + negation terms (e.g. "[!UNAVAIL=return]" instead of bailing out. + + * dirmngr: Better debug output for flags "dns" and "network". + + * dirmngr: On reload mark all known HKP servers alive. + + * gpgconf: Allow keyword "all" for --launch, --kill, and --reload. + + * tools: gpg-wks-client now ignores a missing policy file on the + server. + + * Avoid unnecessary ambiguity error message in the option parsing. + + * Further improvements of the regression test suite. + + * Fixed building with --disable-libdns configure option. + + * Fixed a crash running the tests on 32 bit architectures. + + * Fixed spurious failures on BSD system in the spawn functions. + This affected for example gpg-wks-client and gpgconf. + + Noteworthy changes in version 2.1.17 (2016-12-20) ------------------------------------------------- @@ -33,6 +97,8 @@ Noteworthy changes in version 2.1.17 (2016-12-20) * Major improvements to the test suite. For example it is possible to run the external test suite of GPGME. + See-also: gnupg-announce/2016q4/000400.html + Noteworthy changes in version 2.1.16 (2016-11-18) ------------------------------------------------- @@ -105,6 +171,8 @@ Noteworthy changes in version 2.1.16 (2016-11-18) * Many changes and improvements for the test suite. + See-also: gnupg-announce/2016q4/000398.html + Noteworthy changes in version 2.1.15 (2016-08-18) ------------------------------------------------- @@ -156,6 +224,8 @@ Noteworthy changes in version 2.1.15 (2016-08-18) * Spelling and grammar fixes. + See-also: gnupg-announce/2016q3/000396.html + Noteworthy changes in version 2.1.14 (2016-07-14) ------------------------------------------------- @@ -214,6 +284,8 @@ Noteworthy changes in version 2.1.14 (2016-07-14) * The rendering of the man pages has been improved. + See-also: gnupg-announce/2016q3/000393.html + Noteworthy changes in version 2.1.13 (2016-06-16) ------------------------------------------------- @@ -264,6 +336,8 @@ Noteworthy changes in version 2.1.13 (2016-06-16) * Speedup fd closing after a fork. + See-also: gnupg-announce/2016q2/000390.html + Noteworthy changes in version 2.1.12 (2016-05-04) ------------------------------------------------- @@ -317,6 +391,8 @@ Noteworthy changes in version 2.1.12 (2016-05-04) * Lots of internal cleanups and bug fixes. + See-also: gnupg-announce/2016q2/000387.html + Noteworthy changes in version 2.1.11 (2016-01-26) ------------------------------------------------- @@ -368,6 +444,8 @@ Noteworthy changes in version 2.1.11 (2016-01-26) * Print a warning if a GnuPG component is using an older version of gpg-agent, dirmngr, or scdaemon. + See-also: gnupg-announce/2016q1/000383.html + Noteworthy changes in version 2.1.10 (2015-12-04) ------------------------------------------------- @@ -426,6 +504,8 @@ Noteworthy changes in version 2.1.10 (2015-12-04) * Many other cleanups and bug fixes. + See-also: gnupg-announce/2015q4/000381.html + Noteworthy changes in version 2.1.9 (2015-10-09) ------------------------------------------------ @@ -456,6 +536,8 @@ Noteworthy changes in version 2.1.9 (2015-10-09) * dirmngr: Add option --keyserver. Deprecate that option for gpg. Install a dirmngr.conf file from a skeleton for new installations. + See-also: gnupg-announce/2015q4/000380.html + Noteworthy changes in version 2.1.8 (2015-09-10) ------------------------------------------------ @@ -483,6 +565,8 @@ Noteworthy changes in version 2.1.8 (2015-09-10) * Various minor bug fixes. + See-also: gnupg-announce/2015q3/000379.html + Noteworthy changes in version 2.1.7 (2015-08-11) ------------------------------------------------ @@ -508,6 +592,8 @@ Noteworthy changes in version 2.1.7 (2015-08-11) * Various other bug fixes. + See-also: gnupg-announce/2015q3/000371.html + Noteworthy changes in version 2.1.6 (2015-07-01) ------------------------------------------------ @@ -538,6 +624,8 @@ Noteworthy changes in version 2.1.6 (2015-07-01) * Various other bug fixes. + See-also: gnupg-announce/2015q3/000370.html + Noteworthy changes in version 2.1.5 (2015-06-11) ------------------------------------------------ @@ -552,6 +640,8 @@ Noteworthy changes in version 2.1.5 (2015-06-11) * Code cleanups and minor bug fixes. + See-also: gnupg-announce/2015q2/000369.html + Noteworthy changes in version 2.1.4 (2015-05-12) ------------------------------------------------ @@ -577,6 +667,8 @@ Noteworthy changes in version 2.1.4 (2015-05-12) * Fixed lots of smaller bugs. + See-also: gnupg-announce/2015q2/000366.html + Noteworthy changes in version 2.1.3 (2015-04-11) ------------------------------------------------ @@ -587,7 +679,7 @@ Noteworthy changes in version 2.1.3 (2015-04-11) * gpg: New option --print-pka-records. Changed the PKA method to use CERT records and hashed names. [Update: --print-pka-records - replaced in 2.1.4.] + replaced in 2.1.14.] * gpg: New command --list-gcrypt-config. New parameter "curve" for --list-config. @@ -614,6 +706,8 @@ Noteworthy changes in version 2.1.3 (2015-04-11) * Fixed possible problems due to compiler optimization, two minor regressions, and other bugs. + See-also: gnupg-announce/2015q2/000365.html + Noteworthy changes in version 2.1.2 (2015-02-11) ------------------------------------------------ @@ -648,6 +742,8 @@ Noteworthy changes in version 2.1.2 (2015-02-11) * Fixed several bugs related to bogus keyrings and improved some other code. + See-also: gnupg-announce/2015q1/000361.html + Noteworthy changes in version 2.1.1 (2014-12-16) ------------------------------------------------ @@ -700,6 +796,8 @@ Noteworthy changes in version 2.1.1 (2014-12-16) * Improved portability and the usual bunch of bug fixes. + See-also: gnupg-announce/2014q4/000360.html + Noteworthy changes in version 2.1.0 (2014-11-06) ------------------------------------------------ @@ -1017,6 +1115,8 @@ Noteworthy changes in version 2.1.0 (2014-11-06) * Numerical values may now be used as an alternative to the debug-level keywords. + See-also: gnupg-announce/2014q4/000358.html + Version 2.0.28 (2015-06-02) Version 2.0.27 (2015-02-18) @@ -1060,6 +1160,8 @@ Noteworthy changes in version 2.0.13 (2009-09-04) * Minor bug fixes. + See-also: gnupg-announce/2009q3/000294.html + Noteworthy changes in version 2.0.12 (2009-06-17) ------------------------------------------------- @@ -1087,6 +1189,8 @@ Noteworthy changes in version 2.0.12 (2009-06-17) * Changed code to avoid a possible Mac OS X system freeze. + See-also: gnupg-announce/2009q2/000288.html + Noteworthy changes in version 2.0.11 (2009-03-03) ------------------------------------------------- @@ -1103,6 +1207,8 @@ Noteworthy changes in version 2.0.11 (2009-03-03) due to interoperability problems with Outlook 2003 which still can't cope with AES. + See-also: gnupg-announce/2009q1/000287.html + Noteworthy changes in version 2.0.10 (2009-01-12) ------------------------------------------------- @@ -1158,6 +1264,8 @@ Noteworthy changes in version 2.0.10 (2009-01-12) * Libgcrypt 1.4 is now required. + See-also: gnupg-announce/2009q1/000284.html + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ @@ -1181,6 +1289,7 @@ Noteworthy changes in version 2.0.9 (2008-03-26) * Minor bug fixes. + Noteworthy changes in version 2.0.8 (2007-12-20) ------------------------------------------------ @@ -1214,6 +1323,8 @@ Noteworthy changes in version 2.0.8 (2007-12-20) taken into account. This required a change of our socket emulation code and changed the IPC protocol under Windows. + See-also: gnupg-announce/2007q4/000267.html + Noteworthy changes in version 2.0.7 (2007-09-10) ------------------------------------------------ @@ -1232,6 +1343,8 @@ Noteworthy changes in version 2.0.7 (2007-09-10) installed versions of the programs and does not anymore search via PATH for them. + See-also: gnupg-announce/2007q3/000259.html + Noteworthy changes in version 2.0.6 (2007-08-16) ------------------------------------------------ @@ -1247,6 +1360,8 @@ Noteworthy changes in version 2.0.6 (2007-08-16) * Improved Windows support. + See-also: gnupg-announce/2007q3/000258.html + Noteworthy changes in version 2.0.5 (2007-07-05) ------------------------------------------------ @@ -1264,6 +1379,8 @@ Noteworthy changes in version 2.0.5 (2007-07-05) * Changed key generation to reveal less information about the machine. Bug fixes for gpg2's card key generation. + See-also: gnupg-announce/2007q3/000255.html + Noteworthy changes in version 2.0.4 (2007-05-09) ------------------------------------------------ @@ -1276,6 +1393,8 @@ Noteworthy changes in version 2.0.4 (2007-05-09) * Improved the libgcrypt logging support in all modules. + See-also: gnupg-announce/2007q2/000254.html + Noteworthy changes in version 2.0.3 (2007-03-08) ------------------------------------------------ @@ -1296,6 +1415,8 @@ Noteworthy changes in version 2.0.3 (2007-03-08) * The PIN pad of the Cherry XX44 keyboard is now supported. The DINSIG and the NKS applications are now also aware of PIN pads. + See-also: gnupg-announce/2007q1/000252.html + Noteworthy changes in version 2.0.2 (2007-01-31) ------------------------------------------------ @@ -1314,6 +1435,8 @@ Noteworthy changes in version 2.0.2 (2007-01-31) * The status code BEGIN_SIGNING now shows the used hash algorithms. + See-also: gnupg-announce/2007q1/000249.html + Noteworthy changes in version 2.0.1 (2006-11-28) ------------------------------------------------ @@ -1327,12 +1450,16 @@ Noteworthy changes in version 2.0.1 (2006-11-28) * Fixed a buffer overflow in gpg2. [bug#728,CVE-2006-6169] + See-also: gnupg-announce/2006q4/000242.html + Noteworthy changes in version 2.0.0 (2006-11-11) ------------------------------------------------ * First stable version of a GnuPG integrating OpenPGP and S/MIME. + See-also: gnupg-announce/2006q4/000239.html + Noteworthy changes in version 1.9.95 (2006-11-06) ------------------------------------------------- @@ -1373,6 +1500,8 @@ Noteworthy changes in version 1.9.92 (2006-10-11) * Bug fixes. + See-also: gnupg-announce/2006q4/000236.html + Noteworthy changes in version 1.9.91 (2006-10-04) ------------------------------------------------- @@ -1874,6 +2003,8 @@ Noteworthy changes in version 1.3.2 (2003-05-27) of GnuPG and other OpenPGP programs, please do not use this algorithm. + See-also: gnupg-announce/2003q2/000153.html + Noteworthy changes in version 1.3.1 (2002-11-12) ------------------------------------------------ @@ -2200,6 +2331,8 @@ Noteworthy changes in version 1.0.7 (2002-04-29) * Read only keyrings are now handled as expected. + See-also: gnupg-announce/2002q2/000135.html + Noteworthy changes in version 1.0.6 (2001-05-29) ------------------------------------------------ @@ -2218,6 +2351,8 @@ Noteworthy changes in version 1.0.6 (2001-05-29) * non-writable keyrings are now correctly handled. + See-also: gnupg-announce/2001q2/000123.html + Noteworthy changes in version 1.0.5 (2001-04-29) ------------------------------------------------ @@ -2276,6 +2411,8 @@ Noteworthy changes in version 1.0.5 (2001-04-29) * New translations: Estonian, Turkish. + See-also: gnupg-announce/2001q2/000122.html + Noteworthy changes in version 1.0.4 (2000-10-17) ------------------------------------------------ @@ -2291,6 +2428,9 @@ Noteworthy changes in version 1.0.4 (2000-10-17) * --with-colons now works with --print-md[s]. + See-also: gnupg-announce/2000q4/000082.html + + Noteworthy changes in version 1.0.3 (2000-09-18) ------------------------------------------------ @@ -2322,6 +2462,8 @@ Noteworthy changes in version 1.0.3 (2000-09-18) this. Older versions of GnuPG don't support it, so they should be upgraded to at least 1.0.2 + See-also: gnupg-announce/2000q3/000075.html + Noteworthy changes in version 1.0.2 (2000-07-12) ---------------------------------------------- @@ -2380,6 +2522,9 @@ Noteworthy changes in version 1.0.2 (2000-07-12) * Danish translation + See-also: gnupg-announce/2000q3/000069.html + + Noteworthy changes in version 1.0.1 (1999-12-16) ----------------------------------- @@ -2411,6 +2556,8 @@ Noteworthy changes in version 1.0.1 (1999-12-16) * Removed the GNU Privacy Handbook from the distribution as it will go into a separate one. + See-also: gnupg-announce/1999q4/000050.html + Noteworthy changes in version 1.0.0 (1999-09-07) ----------------------------------- @@ -2420,6 +2567,8 @@ Noteworthy changes in version 1.0.0 (1999-09-07) * Changed the version number to GnuPG 2001 ;-) + See-also: gnupg-announce/1999q3/000037.html + Noteworthy changes in version 0.9.11 (1999-09-03) ------------------------------------ @@ -2431,6 +2580,8 @@ Noteworthy changes in version 0.9.11 (1999-09-03) * Fixed a problem when importing new subkeys (duplicated signatures). + See-also: gnupg-announce/1999q3/000036.html + Noteworthy changes in version 0.9.10 (1999-07-23) ------------------------------------ @@ -2439,6 +2590,8 @@ Noteworthy changes in version 0.9.10 (1999-07-23) * Cleaned up the dox a bit. + See-also: gnupg-announce/1999q3/000034.html + Noteworthy changes in version 0.9.9 ----------------------------------- @@ -2466,6 +2619,8 @@ Noteworthy changes in version 0.9.9 * New option --allow-non-selfsigned-uid to work around a problem with the German IN way of separating signing and encryption keys. + See-also: gnupg-announce/1999q3/000028.html + Noteworthy changes in version 0.9.8 (1999-06-26) ----------------------------------- @@ -2487,6 +2642,8 @@ Noteworthy changes in version 0.9.8 (1999-06-26) * Better support for HPUX. + See-also: gnupg-announce/1999q2/000016.html + Noteworthy changes in version 0.9.7 (1999-05-23) ----------------------------------- @@ -2496,6 +2653,8 @@ Noteworthy changes in version 0.9.7 (1999-05-23) * Enhanced some status outputs. + See-also: gnupg-announce/1999q2/000000.html + Noteworthy changes in version 0.9.6 (1999-05-06) ----------------------------------- @@ -2812,7 +2971,7 @@ Noteworthy changes in version 0.3.3 (1998-08-08) a copy of the old program. 2. Disable the network, make sure that you are the only user, be sure that there are no Trojan horses etc .... - 3. Use your old gpg (version 0.3.[12]) and set the + 3. Use your old gpg (version 0.3.1 or 0.3.2) and set the passphrases of ALL your secret keys to empty! (gpg --change-passphrase your-user-id). 4. Save your ownertrusts (see the next point) @@ -2825,7 +2984,7 @@ Noteworthy changes in version 0.3.3 (1998-08-08) * The format of the trust database has changed; you must delete the old one, so gnupg can create a new one. - IMPORTANT: Use version 0.3.[12] to save your assigned ownertrusts + IMPORTANT: Use version 0.3.1 or .2 to save your assigned ownertrusts ("gpgm --list-ownertrust >saved-trust"); then build this new version and restore the ownertrust with this new version ("gpgm --import-ownertrust saved-trust"). Please note that @@ -2,8 +2,8 @@ ========================= Version 2.1 - Copyright 1997-2016 Werner Koch - Copyright 1998-2016 Free Software Foundation, Inc. + Copyright 1997-2017 Werner Koch + Copyright 1998-2017 Free Software Foundation, Inc. * INTRODUCTION diff --git a/agent/agent.h b/agent/agent.h index 89dc46d..2db5a5c 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -532,7 +532,7 @@ int agent_card_learn (ctrl_t ctrl, void (*sinfo_cb)(void*, const char *, size_t, const char *), void *sinfo_cb_arg); -int agent_card_serialno (ctrl_t ctrl, char **r_serialno); +int agent_card_serialno (ctrl_t ctrl, char **r_serialno, const char *demand); int agent_card_pksign (ctrl_t ctrl, const char *keyid, int (*getpin_cb)(void *, const char *, char*, size_t), diff --git a/agent/call-scd.c b/agent/call-scd.c index ba59c18..15a2ba5 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -679,16 +679,22 @@ get_serialno_cb (void *opaque, const char *line) /* Return the serial number of the card or an appropriate error. The serial number is returned as a hexstring. */ int -agent_card_serialno (ctrl_t ctrl, char **r_serialno) +agent_card_serialno (ctrl_t ctrl, char **r_serialno, const char *demand) { int rc; char *serialno = NULL; + char line[ASSUAN_LINELENGTH]; rc = start_scd (ctrl); if (rc) return rc; - rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO", + if (!demand) + strcpy (line, "SERIALNO"); + else + snprintf (line, DIM(line), "SERIALNO --demand=%s", demand); + + rc = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL, NULL, NULL, get_serialno_cb, &serialno); if (rc) diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 95cef41..f57bac3 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1,4 +1,4 @@ -/* command-ssh.c - gpg-agent's ssh-agent emulation layer +/* command-ssh.c - gpg-agent's implementation of the ssh-agent protocol. * Copyright (C) 2004-2006, 2009, 2012 Free Software Foundation, Inc. * Copyright (C) 2004-2006, 2009, 2012-2014 Werner Koch * @@ -2408,7 +2408,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED ) { /* Ask for the serial number to reset the card. */ - err = agent_card_serialno (ctrl, &serialno); + err = agent_card_serialno (ctrl, &serialno, NULL); if (err) { if (opt.verbose) @@ -3216,7 +3216,7 @@ ssh_identities_remove_all (void) err = 0; /* FIXME: shall we remove _all_ cache entries or only those - registered through the ssh emulation? */ + registered through the ssh-agent protocol? */ return err; } diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 7b07008..7331f58 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -58,7 +58,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid) for (;;) { - rc = agent_card_serialno (ctrl, &serialno); + rc = agent_card_serialno (ctrl, &serialno, want_sn); if (!rc) { log_debug ("detected card with S/N %s\n", serialno); @@ -72,11 +72,17 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid) return 0; /* yes, we have the correct card */ } } + else if (gpg_err_code (rc) == GPG_ERR_ENODEV) + { + log_debug ("no device present\n"); + rc = 0; + no_card = 1; + } else if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT) { log_debug ("no card present\n"); rc = 0; - no_card = 1; + no_card = 2; } else { diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index f4ed6c5..c0208cc 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -303,8 +303,10 @@ static int putty_support; #endif /*HAVE_W32_SYSTEM*/ /* The list of open file descriptors at startup. Note that this list - has been allocated using the standard malloc. */ + * has been allocated using the standard malloc. */ +#ifndef HAVE_W32_SYSTEM static int *startup_fd_list; +#endif /* The signal mask at startup and a flag telling whether it is valid. */ #ifdef HAVE_SIGPROCMASK @@ -344,7 +346,7 @@ static char *redir_socket_name_extra; static char *socket_name_browser; static char *redir_socket_name_browser; -/* Name of the communication socket used for ssh-agent-emulation. */ +/* Name of the communication socket used for ssh-agent protocol. */ static char *socket_name_ssh; static char *redir_socket_name_ssh; @@ -949,8 +951,10 @@ main (int argc, char **argv ) /* Before we do anything else we save the list of currently open file descriptors and the signal mask. This info is required to - do the exec call properly. */ + do the exec call properly. We don't need it on Windows. */ +#ifndef HAVE_W32_SYSTEM startup_fd_list = get_all_open_fds (); +#endif /*!HAVE_W32_SYSTEM*/ #ifdef HAVE_SIGPROCMASK if (!sigprocmask (SIG_UNBLOCK, NULL, &startup_signal_mask)) startup_signal_mask_valid = 1; @@ -1759,11 +1763,19 @@ agent_libgcrypt_progress_cb (void *data, const char *what, int printchar, /* Libgcrypt < 1.8 does not know about nPth and thus when it reads * from /dev/random this will block the process. To mitigate this - * problem we take a short nap when Libgcrypt tells us that it needs + * problem we yield the thread when Libgcrypt tells us that it needs * more entropy. This way other threads have chance to run. */ #if GCRYPT_VERSION_NUMBER < 0x010800 /* 1.8.0 */ if (what && !strcmp (what, "need_entropy")) - npth_usleep (100000); /* 100ms */ + { +#if GPGRT_VERSION_NUMBER < 0x011900 /* 1.25 */ + /* In older gpg-error versions gpgrt_yield is buggy for use with + * nPth and thus we need to resort to a sleep call. */ + npth_usleep (1000); /* 1ms */ +#else + gpgrt_yield (); +#endif + } #endif } diff --git a/agent/learncard.c b/agent/learncard.c index 57bce7a..cce9c3a 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -330,7 +330,7 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force) cparm.ctrl = ctrl; /* Check whether a card is present and get the serial number */ - rc = agent_card_serialno (ctrl, &serialno); + rc = agent_card_serialno (ctrl, &serialno, NULL); if (rc) goto leave; @@ -1,6 +1,6 @@ #! /bin/sh # autogen.sh -# Copyright (C) 2003, 2014 g10 Code GmbH +# Copyright (C) 2003, 2014, 2017 g10 Code GmbH # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without @@ -15,7 +15,7 @@ # configure it for the respective package. It is maintained as part of # GnuPG and source copied by other packages. # -# Version: 2014-06-06 +# Version: 2017-01-17 configure_ac="configure.ac" @@ -80,7 +80,17 @@ if [ -n "${AUTOGEN_SH_SILENT}" ]; then SILENT=" --silent" fi if test x"$1" = x"--help"; then - echo "usage: ./autogen.sh [--silent] [--force] [--build-TYPE] [ARGS]" + echo "usage: ./autogen.sh [OPTIONS] [ARGS]" + echo " Options:" + echo " --silent Silent operation" + echo " --force Pass --force to autoconf" + echo " --find-version Helper for configure.ac" + echo " --build-TYPE Configure to cross build for TYPE" + echo " --print-host Print only the host triplet" + echo " --print-build Print only the build platform triplet" + echo "" + echo " ARGS are passed to configure in --build-TYPE mode." + echo " Configuration for this script is expected in autogen.rc" exit 0 fi if test x"$1" = x"--silent"; then @@ -200,6 +210,11 @@ if [ "$myhost" = "find-version" ]; then minor="$3" micro="$4" + if [ -z "$package" -o -z "$major" -o -z "$minor" ]; then + echo "usage: ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO]" >&2 + exit 1 + fi + case "$version_parts" in 2) matchstr1="$package-$major.[0-9]*" @@ -217,15 +232,17 @@ if [ "$myhost" = "find-version" ]; then if [ -e .git ]; then ingit=yes tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null) + tmp=$(echo "$tmp" | sed s/^"$package"//) if [ -n "$tmp" ]; then - tmp=$(echo "$tmp"|awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}') + tmp=$(echo "$tmp" | sed s/^"$package"// \ + | awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}') else tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null \ | awk -F- '$4!=0{print"-beta"$4}') fi [ -n "$tmp" ] && beta=yes rev=$(git rev-parse --short HEAD | tr -d '\n\r') - rvd=$((0x$(echo ${rev} | head -c 4))) + rvd=$((0x$(echo ${rev} | dd bs=1 count=4 2>/dev/null))) else ingit=no beta=yes @@ -417,13 +434,16 @@ fi # Check the git setup. if [ -d .git ]; then - CP="cp -a" - [ -z "${SILENT}" ] && CP="$CP -v" + CP="cp -p" + # If we have a GNU cp we can add -v + if cp --version >/dev/null 2>/dev/null; then + [ -z "${SILENT}" ] && CP="$CP -v" + fi if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then [ -z "${SILENT}" ] && cat <<EOF *** Activating trailing whitespace git pre-commit hook. *** For more information see this thread: - http://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084.html + https://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084.html To deactivate this pre-commit hook again move .git/hooks/pre-commit and .git/hooks/pre-commit.sample out of the way. EOF diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog index 24a3d72..f70f499 100755 --- a/build-aux/gitlog-to-changelog +++ b/build-aux/gitlog-to-changelog @@ -179,6 +179,7 @@ sub parse_amend_file($) my $amend_file; my $append_dot = 0; my $tear_off = 0; + my $firstline; GetOptions ( help => sub { usage 0 }, @@ -338,7 +339,9 @@ sub parse_amend_file($) # Prefix each non-empty line with a TAB. @line = map { length $_ ? "\t$_" : '' } @line; - print "\n", join ("\n", @line), "\n"; + $firstline = shift @line; + print "\n", $firstline, "\n", "\t+ commit $sha\n"; + print join ("\n", @line), "\n"; } SKIPCOMMIT: diff --git a/common/argparse.c b/common/argparse.c index dce725a..b53efce 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -1,6 +1,6 @@ /* [argparse.c wk 17.06.97] Argument Parser for option handling * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc. - * Copyright (C) 1997-2001, 2006-2008, 2013-2016 Werner Koch + * Copyright (C) 1997-2001, 2006-2008, 2013-2017 Werner Koch * * This file is part of GnuPG. * @@ -71,7 +71,7 @@ #else /* Used by GnuPG */ # define ARGPARSE_GPL_VERSION 3 -# define ARGPARSE_CRIGHT_STR "Copyright (C) 2016 Free Software Foundation, Inc." +# define ARGPARSE_CRIGHT_STR "Copyright (C) 2017 Free Software Foundation, Inc." #endif /*GNUPG_MAJOR_VERSION*/ @@ -898,7 +898,9 @@ find_long_option( ARGPARSE_ARGS *arg, int j; for(j=i+1; opts[j].short_opt; j++ ) { if( opts[j].long_opt - && !strncmp( opts[j].long_opt, keyword, n ) ) + && !strncmp( opts[j].long_opt, keyword, n ) + && !(opts[j].short_opt == opts[i].short_opt + && opts[j].flags == opts[i].flags ) ) return -2; /* abbreviation is ambiguous */ } return i; diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index a7a6db3..e79ee5b 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -128,11 +128,14 @@ close_all_fds (int first, int *except) /* Returns an array with all currently open file descriptors. The end - of the array is marked by -1. The caller needs to release this - array using the *standard free* and not with xfree. This allow the - use of this function right at startup even before libgcrypt has - been initialized. Returns NULL on error and sets ERRNO - accordingly. */ + * of the array is marked by -1. The caller needs to release this + * array using the *standard free* and not with xfree. This allow the + * use of this function right at startup even before libgcrypt has + * been initialized. Returns NULL on error and sets ERRNO + * accordingly. Note that fstat prints a warning to DebugView for all + * invalid fds which is a bit annoying. We actually do not need this + * function in real code (close_all_fds is a dummy anyway) but we keep + * it for use by t-exechelp.c. */ int * get_all_open_fds (void) { diff --git a/common/exectool.c b/common/exectool.c index 4593abd..ed8225a 100644 --- a/common/exectool.c +++ b/common/exectool.c @@ -232,36 +232,38 @@ copy_buffer_do_copy (struct copy_buffer *c, estream_t source, estream_t sink) if (c->nread == 0) { c->writep = c->buffer; - err = es_read (source, c->buffer, sizeof c->buffer, &c->nread); - if (err) + if (es_read (source, c->buffer, sizeof c->buffer, &c->nread)) { - if (errno == EAGAIN) + err = my_error_from_syserror (); + if (gpg_err_code (err) == GPG_ERR_EAGAIN) return 0; /* We will just retry next time. */ - return my_error_from_syserror (); + return err; } - assert (c->nread <= sizeof c->buffer); + log_assert (c->nread <= sizeof c->buffer); } if (c->nread == 0) return 0; /* Done copying. */ - nwritten = 0; - err = sink? es_write (sink, c->writep, c->nread, &nwritten) : 0; + if (sink && es_write (sink, c->writep, c->nread, &nwritten)) + err = my_error_from_syserror (); + else + err = 0; - assert (nwritten <= c->nread); + log_assert (nwritten <= c->nread); c->writep += nwritten; c->nread -= nwritten; - assert (c->writep - c->buffer <= sizeof c->buffer); + log_assert (c->writep - c->buffer <= sizeof c->buffer); if (err) { - if (errno == EAGAIN) + if (gpg_err_code (err) == GPG_ERR_EAGAIN) return 0; /* We will just retry next time. */ - return my_error_from_syserror (); + return err; } if (sink && es_fflush (sink) && errno != EAGAIN) @@ -275,16 +277,24 @@ copy_buffer_do_copy (struct copy_buffer *c, estream_t source, estream_t sink) static gpg_error_t copy_buffer_flush (struct copy_buffer *c, estream_t sink) { - gpg_error_t err; + gpg_error_t err = 0; + size_t nwritten = 0; - while (c->nread > 0) - { - err = copy_buffer_do_copy (c, NULL, sink); - if (err) - return err; - } + if (es_write (sink, c->writep, c->nread, &nwritten)) + err = my_error_from_syserror (); + + log_assert (nwritten <= c->nread); + c->writep += nwritten; + c->nread -= nwritten; + log_assert (c->writep - c->buffer <= sizeof c->buffer); + + if (err) + return err; + + if (es_fflush (sink)) + err = my_error_from_syserror (); - return 0; + return err; } @@ -444,6 +454,8 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], if (es_feof (input)) { err = copy_buffer_flush (cpbuf_in, fds[0].stream); + if (gpg_err_code (err) == GPG_ERR_EAGAIN) + continue; /* Retry next time. */ if (err) { log_error ("error feeding data to '%s': %s\n", @@ -470,6 +482,8 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], if (es_feof (inextra)) { err = copy_buffer_flush (cpbuf_extra, fds[3].stream); + if (gpg_err_code (err) == GPG_ERR_EAGAIN) + continue; /* Retry next time. */ if (err) { log_error ("error feeding data to '%s': %s\n", @@ -606,9 +620,11 @@ gnupg_exec_tool (const char *pgmname, const char *argv[], if (len) { - err = es_read (output, *result, len, &nread); - if (err) - goto leave; + if (es_read (output, *result, len, &nread)) + { + err = my_error_from_syserror (); + goto leave; + } if (nread != len) log_fatal ("%s: short read from memstream\n", __func__); } diff --git a/common/gettime.c b/common/gettime.c index e5da4fb..3e1ee55 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -133,7 +133,7 @@ gnupg_set_time (time_t newtime, int freeze) else if (freeze) { timemode = FROZEN; - timewarp = current; + timewarp = newtime == (time_t)-1 ? current : newtime; } else if (newtime > current) { diff --git a/common/logging.c b/common/logging.c index ca1341c..8c70742 100644 --- a/common/logging.c +++ b/common/logging.c @@ -665,31 +665,10 @@ log_get_stream () return logstream; } + static void -do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr) +print_prefix (int level, int leading_backspace) { - if (!logstream) - { -#ifdef HAVE_W32_SYSTEM - char *tmp; - - tmp = (no_registry - ? NULL - : read_w32_registry_string (NULL, GNUPG_REGISTRY_DIR, - "DefaultLogFile")); - log_set_file (tmp && *tmp? tmp : NULL); - xfree (tmp); -#else - log_set_file (NULL); /* Make sure a log stream has been set. */ -#endif - assert (logstream); - } - - es_flockfile (logstream); - if (missing_lf && level != GPGRT_LOG_CONT) - es_putc_unlocked ('\n', logstream ); - missing_lf = 0; - if (level != GPGRT_LOG_CONT) { /* Note this does not work for multiple line logging as we would * need to print to a buffer first */ @@ -720,11 +699,9 @@ do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr) es_putc_unlocked (':', logstream); /* A leading backspace suppresses the extra space so that we can correctly output, programname, filename and linenumber. */ - if (fmt && *fmt == '\b') - fmt++; - else - if (with_time || with_prefix || with_pid || force_prefixes) - es_putc_unlocked (' ', logstream); + if (!leading_backspace + && (with_time || with_prefix || with_pid || force_prefixes)) + es_putc_unlocked (' ', logstream); } switch (level) @@ -741,6 +718,40 @@ do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr) es_fprintf_unlocked (logstream,"[Unknown log level %d]: ", level); break; } +} + + +static void +do_logv (int level, int ignore_arg_ptr, const char *extrastring, + const char *fmt, va_list arg_ptr) +{ + int leading_backspace = (fmt && *fmt == '\b'); + + if (!logstream) + { +#ifdef HAVE_W32_SYSTEM + char *tmp; + + tmp = (no_registry + ? NULL + : read_w32_registry_string (NULL, GNUPG_REGISTRY_DIR, + "DefaultLogFile")); + log_set_file (tmp && *tmp? tmp : NULL); + xfree (tmp); +#else + log_set_file (NULL); /* Make sure a log stream has been set. */ +#endif + assert (logstream); + } + + es_flockfile (logstream); + if (missing_lf && level != GPGRT_LOG_CONT) + es_putc_unlocked ('\n', logstream ); + missing_lf = 0; + + print_prefix (level, leading_backspace); + if (leading_backspace) + fmt++; if (fmt) { @@ -766,6 +777,48 @@ do_logv (int level, int ignore_arg_ptr, const char *fmt, va_list arg_ptr) missing_lf = 1; } + /* If we have an EXTRASTRING print it now while we still hold the + * lock on the logstream. */ + if (extrastring) + { + int c; + + if (missing_lf) + { + es_putc_unlocked ('\n', logstream); + missing_lf = 0; + } + print_prefix (level, leading_backspace); + es_fputs_unlocked (">> ", logstream); + missing_lf = 1; + while ((c = *extrastring++)) + { + missing_lf = 1; + if (c == '\\') + es_fputs_unlocked ("\\\\", logstream); + else if (c == '\r') + es_fputs_unlocked ("\\r", logstream); + else if (c == '\n') + { + es_fputs_unlocked ("\\n\n", logstream); + if (*extrastring) + { + print_prefix (level, leading_backspace); + es_fputs_unlocked (">> ", logstream); + } + else + missing_lf = 0; + } + else + es_putc_unlocked (c, logstream); + } + if (missing_lf) + { + es_putc_unlocked ('\n', logstream); + missing_lf = 0; + } + } + if (level == GPGRT_LOG_FATAL) { if (missing_lf) @@ -804,7 +857,7 @@ log_log (int level, const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt) ; - do_logv (level, 0, fmt, arg_ptr); + do_logv (level, 0, NULL, fmt, arg_ptr); va_end (arg_ptr); } @@ -812,7 +865,7 @@ log_log (int level, const char *fmt, ...) void log_logv (int level, const char *fmt, va_list arg_ptr) { - do_logv (level, 0, fmt, arg_ptr); + do_logv (level, 0, NULL, fmt, arg_ptr); } @@ -821,7 +874,7 @@ do_log_ignore_arg (int level, const char *str, ...) { va_list arg_ptr; va_start (arg_ptr, str); - do_logv (level, 1, str, arg_ptr); + do_logv (level, 1, NULL, str, arg_ptr); va_end (arg_ptr); } @@ -843,7 +896,7 @@ log_info (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_INFO, 0, fmt, arg_ptr); + do_logv (GPGRT_LOG_INFO, 0, NULL, fmt, arg_ptr); va_end (arg_ptr); } @@ -854,7 +907,7 @@ log_error (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_ERROR, 0, fmt, arg_ptr); + do_logv (GPGRT_LOG_ERROR, 0, NULL, fmt, arg_ptr); va_end (arg_ptr); /* Protect against counter overflow. */ if (errorcount < 30000) @@ -868,7 +921,7 @@ log_fatal (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_FATAL, 0, fmt, arg_ptr); + do_logv (GPGRT_LOG_FATAL, 0, NULL, fmt, arg_ptr); va_end (arg_ptr); abort (); /* Never called; just to make the compiler happy. */ } @@ -880,7 +933,7 @@ log_bug (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_BUG, 0, fmt, arg_ptr); + do_logv (GPGRT_LOG_BUG, 0, NULL, fmt, arg_ptr); va_end (arg_ptr); abort (); /* Never called; just to make the compiler happy. */ } @@ -892,7 +945,21 @@ log_debug (const char *fmt, ...) va_list arg_ptr ; va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_DEBUG, 0, fmt, arg_ptr); + do_logv (GPGRT_LOG_DEBUG, 0, NULL, fmt, arg_ptr); + va_end (arg_ptr); +} + + +/* The same as log_debug but at the end of the output STRING is + * printed with LFs expanded to include the prefix and a final --end-- + * marker. */ +void +log_debug_with_string (const char *string, const char *fmt, ...) +{ + va_list arg_ptr ; + + va_start (arg_ptr, fmt); + do_logv (GPGRT_LOG_DEBUG, 0, string, fmt, arg_ptr); va_end (arg_ptr); } @@ -903,7 +970,7 @@ log_printf (const char *fmt, ...) va_list arg_ptr; va_start (arg_ptr, fmt); - do_logv (fmt ? GPGRT_LOG_CONT : GPGRT_LOG_BEGIN, 0, fmt, arg_ptr); + do_logv (fmt ? GPGRT_LOG_CONT : GPGRT_LOG_BEGIN, 0, NULL, fmt, arg_ptr); va_end (arg_ptr); } @@ -1007,7 +1074,7 @@ void _log_assert (const char *expr, const char *file, int line) { log_log (GPGRT_LOG_BUG, "Assertion \"%s\" failed (%s:%d)\n", - file, line, func); + expr, file, line); abort (); /* Never called; just to make the compiler happy. */ } #endif /*!GPGRT_HAVE_MACRO_FUNCTION*/ diff --git a/common/logging.h b/common/logging.h index 64b999d..ed1d3b9 100644 --- a/common/logging.h +++ b/common/logging.h @@ -56,18 +56,18 @@ estream_t log_get_stream (void); void _log_assert (const char *expr, const char *file, int line, const char *func) GPGRT_ATTR_NORETURN; # define BUG() bug_at( __FILE__ , __LINE__, __FUNCTION__) -# define log_assert(expr) do { \ - if (!(expr)) \ - _log_assert (#expr, __FILE__, __LINE__, __FUNCTION__); \ - } while (0) +# define log_assert(expr) \ + ((expr) \ + ? (void) 0 \ + : _log_assert (#expr, __FILE__, __LINE__, __FUNCTION__)) #else /*!GPGRT_HAVE_MACRO_FUNCTION*/ void bug_at (const char *file, int line); - void _log_assert (const char *expr, const char *file, int line; + void _log_assert (const char *expr, const char *file, int line); # define BUG() bug_at( __FILE__ , __LINE__ ) -# define log_assert(expr) do { \ - if (!(expr)) \ - _log_assert (#expr, __FILE__, __LINE__); \ - } while (0) +# define log_assert(expr) \ + ((expr) \ + ? (void) 0 \ + : _log_assert (#expr, __FILE__, __LINE__)) #endif /*!GPGRT_HAVE_MACRO_FUNCTION*/ /* Flag values for log_set_prefix. */ @@ -96,6 +96,8 @@ void log_fatal (const char *fmt, ...) GPGRT_ATTR_NR_PRINTF(1,2); void log_error (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); void log_info (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); void log_debug (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); +void log_debug_with_string (const char *string, const char *fmt, + ...) GPGRT_ATTR_PRINTF(2,3); void log_printf (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); void log_flush (void); diff --git a/common/t-exectool.c b/common/t-exectool.c index 8b6ee6a..9cea2d1 100644 --- a/common/t-exectool.c +++ b/common/t-exectool.c @@ -39,21 +39,27 @@ static void test_executing_true (void) { gpg_error_t err; - const char *argv[] = { "/bin/true", NULL }; + const char *pgmname = "/bin/true"; + const char *alt_pgmname = "/usr/bin/true"; + const char *argv[] = { NULL, NULL }; char *result; size_t len; - if (access (argv[0], X_OK)) + if (access (pgmname, X_OK)) { - fprintf (stderr, "skipping test: %s not executable: %s", - argv[0], strerror (errno)); - return; + if (access (alt_pgmname, X_OK)) + { + fprintf (stderr, "skipping test: %s not executable: %s\n", + pgmname, strerror (errno)); + return; + } + pgmname = alt_pgmname; } if (verbose) - fprintf (stderr, "Executing %s...\n", argv[0]); + fprintf (stderr, "Executing %s...\n", pgmname); - err = gnupg_exec_tool (argv[0], &argv[1], "", &result, &len); + err = gnupg_exec_tool (pgmname, argv, "", &result, &len); if (err) fail ("gnupg_exec_tool", err); @@ -66,24 +72,31 @@ static void test_executing_false (void) { gpg_error_t err; - const char *argv[] = { "/bin/false", NULL }; + const char *pgmname = "/bin/false"; + const char *alt_pgmname = "/usr/bin/false"; + const char *argv[] = { NULL, NULL }; char *result; size_t len; - if (access (argv[0], X_OK)) + if (access (pgmname, X_OK)) { - fprintf (stderr, "skipping test: %s not executable: %s", - argv[0], strerror (errno)); - return; + if (access (alt_pgmname, X_OK)) + { + fprintf (stderr, "skipping test: %s not executable: %s\n", + pgmname, strerror (errno)); + return; + } + pgmname = alt_pgmname; } if (verbose) - fprintf (stderr, "Executing %s...\n", argv[0]); + fprintf (stderr, "Executing %s...\n", pgmname); - err = gnupg_exec_tool (argv[0], &argv[1], "", &result, &len); + err = gnupg_exec_tool (pgmname, argv, "", &result, &len); assert (err == GPG_ERR_GENERAL); } + static void test_executing_cat (const char *vector) { @@ -94,7 +107,7 @@ test_executing_cat (const char *vector) if (access (argv[0], X_OK)) { - fprintf (stderr, "skipping test: %s not executable: %s", + fprintf (stderr, "skipping test: %s not executable: %s\n", argv[0], strerror (errno)); return; } @@ -131,7 +144,7 @@ test_catting_cat (void) if (access (argv[0], X_OK)) { - fprintf (stderr, "skipping test: %s not executable: %s", + fprintf (stderr, "skipping test: %s not executable: %s\n", argv[0], strerror (errno)); return; } @@ -139,7 +152,7 @@ test_catting_cat (void) in = es_fopen (argv[1], "r"); if (in == NULL) { - fprintf (stderr, "skipping test: could not open %s: %s", + fprintf (stderr, "skipping test: could not open %s: %s\n", argv[1], strerror (errno)); return; } @@ -147,7 +160,7 @@ test_catting_cat (void) err = es_fseek (in, 0L, SEEK_END); if (err) { - fprintf (stderr, "skipping test: could not seek in %s: %s", + fprintf (stderr, "skipping test: could not seek in %s: %s\n", argv[1], gpg_strerror (err)); return; } diff --git a/common/t-gettime.c b/common/t-gettime.c index 9d9881a..13cb1a2 100644 --- a/common/t-gettime.c +++ b/common/t-gettime.c @@ -20,9 +20,18 @@ #include <config.h> #include <stdio.h> #include <stdlib.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif #include "util.h" +/* In case we do not have stdint.h and no other version of that + * conversion macro provide shortcut it. */ +#ifndef UINTMAX_C +#define UINTMAX_C (c) (c) +#endif + #define pass() do { ; } while(0) #define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ __FILE__,__LINE__, (a)); \ @@ -55,10 +64,10 @@ test_isotime2epoch (void) { "20070629T160000\n", 1183132800 }, { "20070629T160000.", INVALID }, #if SIZEOF_TIME_T > 4 - { "21060207T062815", (time_t)0x0ffffffff }, - { "21060207T062816", (time_t)0x100000000 }, - { "21060207T062817", (time_t)0x100000001 }, - { "21060711T120001", (time_t)4308292801 }, + { "21060207T062815", (time_t)UINTMAX_C(0x0ffffffff) }, + { "21060207T062816", (time_t)UINTMAX_C(0x100000000) }, + { "21060207T062817", (time_t)UINTMAX_C(0x100000001) }, + { "21060711T120001", (time_t)UINTMAX_C(4308292801) }, #endif /*SIZEOF_TIME_T > 4*/ { NULL, 0 } }; diff --git a/common/t-iobuf.c b/common/t-iobuf.c index 0e6f508..bdeab99 100644 --- a/common/t-iobuf.c +++ b/common/t-iobuf.c @@ -362,10 +362,12 @@ main (int argc, char *argv[]) { iobuf_t iobuf; int rc; - char *content = "0123456789"; + char content[] = "0123456789"; int n; int c; - char buffer[strlen (content)]; + char buffer[10]; + + assert (sizeof buffer == sizeof content - 1); iobuf = iobuf_temp_with_content (content, strlen (content)); assert (iobuf); diff --git a/common/tlv.c b/common/tlv.c index 6813c58..0058b67 100644 --- a/common/tlv.c +++ b/common/tlv.c @@ -214,9 +214,9 @@ parse_ber_header (unsigned char const **buffer, size_t *size, else { unsigned long len = 0; - int count = c & 0x7f; + int count = (c & 0x7f); - if (count > sizeof (len) || count > sizeof (size_t)) + if (count > (sizeof(len)<sizeof(size_t)?sizeof(len):sizeof(size_t))) return gpg_err_make (default_errsource, GPG_ERR_BAD_BER); for (; count; count--) diff --git a/common/ttyio.c b/common/ttyio.c index 5fb620d..29af1b3 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -309,95 +309,59 @@ tty_fprintf (estream_t fp, const char *fmt, ... ) } -/**************** - * Print a string, but filter all control characters out. If FP is - * not NULL print to that stream instead to the tty. - */ -void -tty_print_string (estream_t fp, const byte *p, size_t n ) +/* Print a string, but filter all control characters out. If FP is + * not NULL print to that stream instead to the tty. */ +static void +do_print_string (estream_t fp, const byte *p, size_t n ) { - if (no_terminal && !fp) - return; + if (no_terminal && !fp) + return; - if( !initialized & !fp) - init_ttyfp(); + if (!initialized && !fp) + init_ttyfp(); + + if (fp) + { + print_utf8_buffer (fp, p, n); + return; + } #ifdef USE_W32_CONSOLE - /* not so effective, change it if you want */ - if (fp) - { - for( ; n; n--, p++ ) - { - if( iscntrl( *p ) ) - { - if( *p == '\n' ) - tty_fprintf (fp, "\\n"); - else if( !*p ) - tty_fprintf (fp, "\\0"); - else - tty_fprintf (fp, "\\x%02x", *p); - } - else - tty_fprintf (fp, "%c", *p); - } - } - else - { - for( ; n; n--, p++ ) - { - if( iscntrl( *p ) ) - { - if( *p == '\n' ) - tty_printf ("\\n"); - else if( !*p ) - tty_printf ("\\0"); - else - tty_printf ("\\x%02x", *p); - } - else - tty_printf ("%c", *p); - } - } + /* Not so effective, change it if you want */ + for (; n; n--, p++) + { + if (iscntrl (*p)) + { + if( *p == '\n' ) + tty_printf ("\\n"); + else if( !*p ) + tty_printf ("\\0"); + else + tty_printf ("\\x%02x", *p); + } + else + tty_printf ("%c", *p); + } #else - if (fp) - { - for( ; n; n--, p++ ) - { - if (iscntrl (*p)) - { - es_putc ('\\', fp); - if ( *p == '\n' ) - es_putc ('n', fp); - else if ( !*p ) - es_putc ('0', fp); - else - es_fprintf (fp, "x%02x", *p); - } - else - es_putc (*p, fp); - } - } - else - { - for (; n; n--, p++) - { - if (iscntrl (*p)) - { - putc ('\\', ttyfp); - if ( *p == '\n' ) - putc ('n', ttyfp); - else if ( !*p ) - putc ('0', ttyfp); - else - fprintf (ttyfp, "x%02x", *p ); - } - else - putc (*p, ttyfp); - } - } + for (; n; n--, p++) + { + if (iscntrl (*p)) + { + putc ('\\', ttyfp); + if ( *p == '\n' ) + putc ('n', ttyfp); + else if ( !*p ) + putc ('0', ttyfp); + else + fprintf (ttyfp, "x%02x", *p ); + } + else + putc (*p, ttyfp); + } #endif } + void tty_print_utf8_string2 (estream_t fp, const byte *p, size_t n, size_t max_n) { @@ -425,7 +389,7 @@ tty_print_utf8_string2 (estream_t fp, const byte *p, size_t n, size_t max_n) if( max_n && (n > max_n) ) { n = max_n; } - tty_print_string (fp, p, n ); + do_print_string (fp, p, n ); } } diff --git a/common/ttyio.h b/common/ttyio.h index 004aa85..5bff82f 100644 --- a/common/ttyio.h +++ b/common/ttyio.h @@ -47,7 +47,6 @@ void tty_printf (const char *fmt, ... ); void tty_fprintf (estream_t fp, const char *fmt, ... ); char *tty_getf (const char *promptfmt, ... ); #endif -void tty_print_string (estream_t fp, const unsigned char *p, size_t n); void tty_print_utf8_string (const unsigned char *p, size_t n); void tty_print_utf8_string2 (estream_t fp, const unsigned char *p, size_t n, size_t max_n); diff --git a/common/w32info-rc.h.in b/common/w32info-rc.h.in index d7909dd..4e46b97 100644 --- a/common/w32info-rc.h.in +++ b/common/w32info-rc.h.in @@ -29,4 +29,4 @@ built on @BUILD_HOSTNAME@ at @BUILD_TIMESTAMP@\0" #define W32INFO_PRODUCTVERSION "@VERSION@\0" #define W32INFO_LEGALCOPYRIGHT "Copyright \xa9 \ -2015 Free Software Foundation, Inc.\0" +2017 Free Software Foundation, Inc.\0" diff --git a/configure.ac b/configure.ac index 6630610..f929cb6 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ min_automake_version="1.14" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [1]) -m4_define([mym4_micro], [17]) +m4_define([mym4_micro], [18]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release @@ -1258,7 +1258,7 @@ AC_MSG_NOTICE([checking for header files]) AC_HEADER_STDC AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \ pty.h utmp.h pwd.h inttypes.h signal.h sys/select.h \ - signal.h]) + stdint.h signal.h]) AC_HEADER_TIME @@ -1574,6 +1574,15 @@ if test "$GCC" = yes; then if test x"$_gcc_wopt" = xyes ; then mycflags="$mycflags -Wdeclaration-after-statement" fi + + AC_MSG_CHECKING([if gcc supports -Wlogical-op and -Wvla]) + CFLAGS="-Wlogical-op -Wvla" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no) + AC_MSG_RESULT($_gcc_wopt) + if test x"$_gcc_wopt" = xyes ; then + mycflags="$mycflags -Wlogical-op -Wvla" + fi + else mycflags="$mycflags -Wall" fi @@ -1894,6 +1903,7 @@ tests/Makefile tests/gpgscm/Makefile tests/openpgp/Makefile tests/migrations/Makefile +tests/gpgsm/Makefile tests/gpgme/Makefile tests/pkits/Makefile g10/gpg.w32-manifest diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 07fa5b1..2e471cb 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -127,7 +127,7 @@ static const char oidstr_crlNumber[] = "2.5.29.20"; -static const char oidstr_issuingDistributionPoint[] = "2.5.29.28"; +/* static const char oidstr_issuingDistributionPoint[] = "2.5.29.28"; */ static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35"; diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 5ee589e..061cfc3 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -481,6 +481,9 @@ set_tor_mode (void) { if (opt.use_tor) { + /* Enable Tor mode and when called again force a new curcuit + * (e.g. on SIGHUP). */ + enable_dns_tormode (1); if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1)) { log_error ("error enabling Tor mode: %s\n", strerror (errno)); @@ -648,6 +651,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) } set_dns_verbose (opt.verbose, !!DBG_DNS); + http_set_verbose (opt.verbose, !!DBG_NETWORK); return 1; /* Handled. */ } @@ -919,13 +923,6 @@ main (int argc, char **argv) log_info ("NOTE: this is a development version!\n"); #endif - if (opt.use_tor) - { - log_info ("WARNING: ***************************************\n"); - log_info ("WARNING: Tor mode (--use-tor) MAY NOT FULLY WORK!\n"); - log_info ("WARNING: ***************************************\n"); - } - /* Print a warning if an argument looks like an option. */ if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN)) { @@ -1705,6 +1702,7 @@ dirmngr_sighup_action (void) cert_cache_init (); crl_cache_init (); reload_dns_stuff (0); + ks_hkp_reload (); } diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 9a87878..35bc000 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -194,6 +194,7 @@ const char* dirmngr_get_current_socket_name (void); /*-- Various housekeeping functions. --*/ void ks_hkp_housekeeping (time_t curtime); +void ks_hkp_reload (void); /*-- server.c --*/ diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 491fcce..9347196 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -181,7 +181,9 @@ void enable_recursive_resolver (int yes) { recursive_resolver = yes; +#ifdef USE_LIBDNS libdns_reinit_pending = 1; +#endif } @@ -197,9 +199,9 @@ recursive_resolver_p (void) } -/* Sets the module in Tor mode. Returns 0 is this is possible or an - error code. */ -gpg_error_t +/* Puts this module eternally into Tor mode. When called agained with + * NEW_CIRCUIT request a new TOR circuit for the next DNS query. */ +void enable_dns_tormode (int new_circuit) { if (!*tor_socks_user || new_circuit) @@ -213,7 +215,6 @@ enable_dns_tormode (int new_circuit) counter++; } tor_mode = 1; - return 0; } @@ -251,8 +252,10 @@ set_dns_nameserver (const char *ipaddr) strncpy (tor_nameserver, ipaddr? ipaddr : DEFAULT_NAMESERVER, sizeof tor_nameserver -1); tor_nameserver[sizeof tor_nameserver -1] = 0; +#ifdef USE_LIBDNS libdns_reinit_pending = 1; libdns_tor_port = 0; /* Start again with the default port. */ +#endif } @@ -278,7 +281,7 @@ get_h_errno_as_gpg_error (void) switch (h_errno) { - case HOST_NOT_FOUND: ec = GPG_ERR_UNKNOWN_HOST; break; + case HOST_NOT_FOUND: ec = GPG_ERR_NO_NAME; break; case TRY_AGAIN: ec = GPG_ERR_TRY_LATER; break; case NO_RECOVERY: ec = GPG_ERR_SERVER_FAILED; break; case NO_DATA: ec = GPG_ERR_NO_DATA; break; @@ -475,7 +478,17 @@ libdns_init (void) if (err) { log_error ("failed to load '%s': %s\n", fname, gpg_strerror (err)); - goto leave; + /* not fatal, nsswitch.conf is not used on all systems; assume + * classic behavior instead. Our dns library states "bf" which tries + * DNS then Files, which is not classic; FreeBSD + * /usr/src/lib/libc/net/gethostnamadr.c defines default_src[] which + * is Files then DNS, which is. */ + if (opt_debug) + log_debug ("dns: fallback resolution order, files then DNS\n"); + ld.resolv_conf->lookup[0] = 'f'; + ld.resolv_conf->lookup[1] = 'b'; + ld.resolv_conf->lookup[2] = '\0'; + err = GPG_ERR_NO_ERROR; } #endif /* Unix */ @@ -503,6 +516,9 @@ libdns_init (void) /* All fine. Make the data global. */ libdns = ld; + if (opt_debug) + log_debug ("dns: libdns initialized%s\n", tor_mode?" (tor mode)":""); + leave: xfree (cfgstr); return err; @@ -534,15 +550,20 @@ libdns_deinit (void) void reload_dns_stuff (int force) { +#ifdef USE_LIBDNS if (force) { -#ifdef USE_LIBDNS libdns_deinit (); -#endif libdns_reinit_pending = 0; } else - libdns_reinit_pending = 1; + { + libdns_reinit_pending = 1; + libdns_tor_port = 0; /* Start again with the default port. */ + } +#else + (void)force; +#endif } @@ -589,7 +610,7 @@ libdns_res_open (struct dns_resolver **r_res) #ifdef USE_LIBDNS -/* Helper to test whether we need totry again after having swicthed +/* Helper to test whether we need to try again after having switched * the Tor port. */ static int libdns_switch_port_p (gpg_error_t err) @@ -674,6 +695,8 @@ resolve_name_libdns (const char *name, unsigned short port, hints.ai_flags = AI_ADDRCONFIG; if (r_canonname) hints.ai_flags |= AI_CANONNAME; + if (is_ip_address (name)) + hints.ai_flags |= AI_NUMERICHOST; if (port) { @@ -726,6 +749,10 @@ resolve_name_libdns (const char *name, unsigned short port, err = gpg_error_from_syserror (); goto leave; } + /* Libdns appends the root zone part which is problematic + * for most other functions - strip it. */ + if (**r_canonname && (*r_canonname)[strlen (*r_canonname)-1] == '.') + (*r_canonname)[strlen (*r_canonname)-1] = 0; } dai = xtrymalloc (sizeof *dai + ent->ai_addrlen -1); @@ -791,6 +818,8 @@ resolve_name_standard (const char *name, unsigned short port, hints.ai_flags = AI_ADDRCONFIG; if (r_canonname) hints.ai_flags |= AI_CANONNAME; + if (is_ip_address (name)) + hints.ai_flags |= AI_NUMERICHOST; if (port) snprintf (portstr, sizeof portstr, "%hu", port); @@ -873,6 +902,177 @@ resolve_name_standard (const char *name, unsigned short port, } +/* This a wrapper around getaddrinfo with slightly different semantics. + NAME is the name to resolve. + PORT is the requested port or 0. + WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4. + WANT_SOCKETTYPE is either SOCK_STREAM or SOCK_DGRAM. + + On success the result is stored in a linked list with the head + stored at the address R_AI; the caller must call gpg_addrinfo_free + on this. If R_CANONNAME is not NULL the official name of the host + is stored there as a malloced string; if that name is not available + NULL is stored. */ +gpg_error_t +resolve_dns_name (const char *name, unsigned short port, + int want_family, int want_socktype, + dns_addrinfo_t *r_ai, char **r_canonname) +{ + gpg_error_t err; + +#ifdef USE_LIBDNS + if (!standard_resolver) + { + err = resolve_name_libdns (name, port, want_family, want_socktype, + r_ai, r_canonname); + if (err && libdns_switch_port_p (err)) + err = resolve_name_libdns (name, port, want_family, want_socktype, + r_ai, r_canonname); + } + else +#endif /*USE_LIBDNS*/ + err = resolve_name_standard (name, port, want_family, want_socktype, + r_ai, r_canonname); + if (opt_debug) + log_debug ("dns: resolve_dns_name(%s): %s\n", name, gpg_strerror (err)); + return err; +} + + +#ifdef USE_LIBDNS +/* Resolve an address using libdns. */ +static gpg_error_t +resolve_addr_libdns (const struct sockaddr *addr, int addrlen, + unsigned int flags, char **r_name) +{ + gpg_error_t err; + char host[DNS_D_MAXNAME + 1]; + struct dns_resolver *res = NULL; + struct dns_packet *ans = NULL; + struct dns_ptr ptr; + int derr; + + *r_name = NULL; + + /* First we turn ADDR into a DNS name (with ".arpa" suffix). */ + err = 0; + if (addr->sa_family == AF_INET6) + { + const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr; + if (!dns_aaaa_arpa (host, sizeof host, (void*)&a6->sin6_addr)) + err = gpg_error (GPG_ERR_INV_OBJ); + } + else if (addr->sa_family == AF_INET) + { + const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr; + if (!dns_a_arpa (host, sizeof host, (void*)&a4->sin_addr)) + err = gpg_error (GPG_ERR_INV_OBJ); + } + else + err = gpg_error (GPG_ERR_EAFNOSUPPORT); + if (err) + goto leave; + + + err = libdns_res_open (&res); + if (err) + goto leave; + + err = libdns_res_submit (res, host, DNS_T_PTR, DNS_C_IN); + if (err) + goto leave; + + err = libdns_res_wait (res); + if (err) + goto leave; + + ans = dns_res_fetch (res, &derr); + if (!ans) + { + err = libdns_error_to_gpg_error (derr); + goto leave; + } + + /* Check the rcode. */ + switch (dns_p_rcode (ans)) + { + case DNS_RC_NOERROR: + break; + case DNS_RC_NXDOMAIN: + err = gpg_error (GPG_ERR_NO_NAME); + break; + default: + err = GPG_ERR_SERVER_FAILED; + goto leave; + } + + /* Parse the result. */ + if (!err) + { + struct dns_rr rr; + struct dns_rr_i rri; + + memset (&rri, 0, sizeof rri); + dns_rr_i_init (&rri, ans); + rri.section = DNS_S_ALL & ~DNS_S_QD; + rri.name = host; + rri.type = DNS_T_PTR; + + if (!dns_rr_grep (&rr, 1, &rri, ans, &derr)) + { + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; + } + + err = libdns_error_to_gpg_error (dns_ptr_parse (&ptr, &rr, ans)); + if (err) + goto leave; + + /* Copy result. */ + *r_name = xtrystrdup (ptr.host); + if (!*r_name) + { + err = gpg_error_from_syserror (); + goto leave; + } + /* Libdns appends the root zone part which is problematic + * for most other functions - strip it. */ + if (**r_name && (*r_name)[strlen (*r_name)-1] == '.') + (*r_name)[strlen (*r_name)-1] = 0; + } + else /* GPG_ERR_NO_NAME */ + { + char *buffer, *p; + int buflen; + int ec; + + buffer = ptr.host; + buflen = sizeof ptr.host; + + p = buffer; + if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET)) + { + *p++ = '['; + buflen -= 2; + } + ec = getnameinfo (addr, addrlen, p, buflen, NULL, 0, NI_NUMERICHOST); + if (ec) + { + err = map_eai_to_gpg_error (ec); + goto leave; + } + if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET)) + strcat (buffer, "]"); + } + + leave: + dns_free (ans); + dns_res_close (res); + return err; +} +#endif /*USE_LIBDNS*/ + + /* Resolve an address using the standard system function. */ static gpg_error_t resolve_addr_standard (const struct sockaddr *addr, int addrlen, @@ -933,53 +1133,35 @@ resolve_addr_standard (const struct sockaddr *addr, int addrlen, } -/* This a wrapper around getaddrinfo with slightly different semantics. - NAME is the name to resolve. - PORT is the requested port or 0. - WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4. - WANT_SOCKETTYPE is either SOCK_STREAM or SOCK_DGRAM. - - On success the result is stored in a linked list with the head - stored at the address R_AI; the caller must call gpg_addrinfo_free - on this. If R_CANONNAME is not NULL the official name of the host - is stored there as a malloced string; if that name is not available - NULL is stored. */ +/* A wrapper around getnameinfo. */ gpg_error_t -resolve_dns_name (const char *name, unsigned short port, - int want_family, int want_socktype, - dns_addrinfo_t *r_ai, char **r_canonname) +resolve_dns_addr (const struct sockaddr *addr, int addrlen, + unsigned int flags, char **r_name) { gpg_error_t err; #ifdef USE_LIBDNS - if (!standard_resolver) + /* Note that we divert to the standard resolver for NUMERICHOST. */ + if (!standard_resolver && !(flags & DNS_NUMERICHOST)) { - err = resolve_name_libdns (name, port, want_family, want_socktype, - r_ai, r_canonname); + err = resolve_addr_libdns (addr, addrlen, flags, r_name); if (err && libdns_switch_port_p (err)) - err = resolve_name_libdns (name, port, want_family, want_socktype, - r_ai, r_canonname); + err = resolve_addr_libdns (addr, addrlen, flags, r_name); } else #endif /*USE_LIBDNS*/ - err = resolve_name_standard (name, port, want_family, want_socktype, - r_ai, r_canonname); + err = resolve_addr_standard (addr, addrlen, flags, r_name); + if (opt_debug) - log_debug ("dns: resolve_dns_name(%s): %s\n", name, gpg_strerror (err)); + log_debug ("dns: resolve_dns_addr(): %s\n", gpg_strerror (err)); return err; } -gpg_error_t -resolve_dns_addr (const struct sockaddr *addr, int addrlen, - unsigned int flags, char **r_name) -{ - return resolve_addr_standard (addr, addrlen, flags, r_name); -} - - -/* Check whether NAME is an IP address. Returns true if it is either - an IPv6 or IPv4 numerical address. */ +/* Check whether NAME is an IP address. Returns a true if it is + * either an IPv6 or a IPv4 numerical address. The actual return + * values can also be used to identify whether it is v4 or v6: The + * true value will surprisingly be 4 for IPv4 and 6 for IPv6. */ int is_ip_address (const char *name) { @@ -987,7 +1169,7 @@ is_ip_address (const char *name) int ndots, dblcol, n; if (*name == '[') - return 1; /* yes: A legal DNS name may not contain this character; + return 6; /* yes: A legal DNS name may not contain this character; this mut be bracketed v6 address. */ if (*name == '.') return 0; /* No. A leading dot is not a valid IP address. */ @@ -1020,7 +1202,7 @@ is_ip_address (const char *name) if (ndots > 7) return 0; /* No: Too many colons. */ else if (ndots > 1) - return 1; /* Yes: At least 2 colons indicate an v6 address. */ + return 6; /* Yes: At least 2 colons indicate an v6 address. */ legacy: /* Check whether it is legacy IP address. */ @@ -1041,7 +1223,7 @@ is_ip_address (const char *name) else if (++n > 3) return 0; /* No: More than 3 digits. */ } - return !!(ndots == 3); + return (ndots == 3)? 4 : 0; } @@ -1075,7 +1257,7 @@ get_dns_cert_libdns (const char *name, int want_certtype, int derr; int qtype; - /* Gte the query type from WANT_CERTTYPE (which in general indicates + /* Get the query type from WANT_CERTTYPE (which in general indicates * the subtype we want). */ qtype = (want_certtype < DNS_CERTTYPE_RRBASE ? T_CERT @@ -1576,6 +1758,10 @@ getsrv_libdns (const char *name, struct srventry **list, unsigned int *r_count) srv->weight = dsrv.weight; srv->port = dsrv.port; mem2str (srv->target, dsrv.target, sizeof srv->target); + /* Libdns appends the root zone part which is problematic for + * most other functions - strip it. */ + if (*srv->target && (srv->target)[strlen (srv->target)-1] == '.') + (srv->target)[strlen (srv->target)-1] = 0; } *r_count = srvcount; @@ -1721,17 +1907,37 @@ getsrv_standard (const char *name, } -/* Note that we do not return NONAME but simply store 0 at R_COUNT. */ +/* Query a SRV record for SERVICE and PROTO for NAME. If SERVICE is + * NULL, NAME is expected to contain the full query name. Note that + * we do not return NONAME but simply store 0 at R_COUNT. On error an + * error code is returned and 0 stored at R_COUNT. */ gpg_error_t -get_dns_srv (const char *name, struct srventry **list, unsigned int *r_count) +get_dns_srv (const char *name, const char *service, const char *proto, + struct srventry **list, unsigned int *r_count) { gpg_error_t err; + char *namebuffer = NULL; unsigned int srvcount; int i; *list = NULL; *r_count = 0; srvcount = 0; + + /* If SERVICE is given construct the query from it and PROTO. */ + if (service) + { + namebuffer = xtryasprintf ("_%s._%s.%s", + service, proto? proto:"tcp", name); + if (!namebuffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + name = namebuffer; + } + + #ifdef USE_LIBDNS if (!standard_resolver) { @@ -1833,6 +2039,7 @@ get_dns_srv (const char *name, struct srventry **list, unsigned int *r_count) } if (!err) *r_count = srvcount; + xfree (namebuffer); return err; } @@ -1893,6 +2100,13 @@ get_dns_cname_libdns (const char *name, char **r_cname) *r_cname = xtrystrdup (cname.host); if (!*r_cname) err = gpg_error_from_syserror (); + else + { + /* Libdns appends the root zone part which is problematic + * for most other functions - strip it. */ + if (**r_cname && (*r_cname)[strlen (*r_cname)-1] == '.') + (*r_cname)[strlen (*r_cname)-1] = 0; + } leave: dns_free (ans); diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h index 0a4a4de..d68dd17 100644 --- a/dirmngr/dns-stuff.h +++ b/dirmngr/dns-stuff.h @@ -113,9 +113,9 @@ void enable_recursive_resolver (int yes); /* Return true iff the recursive resolver is used. */ int recursive_resolver_p (void); -/* Calling this function switches the DNS code into Tor mode if - possibe. Return 0 on success. */ -gpg_error_t enable_dns_tormode (int new_circuit); +/* Put this module eternally into Tor mode. When called agained with + * NEW_CIRCUIT request a new TOR circuit for the next DNS query. */ +void enable_dns_tormode (int new_circuit); /* Change the default IP address of the nameserver to IPADDR. The address needs to be a numerical IP address and will be used for the @@ -153,6 +153,7 @@ gpg_error_t get_dns_cert (const char *name, int want_certtype, /* Return an array of SRV records. */ gpg_error_t get_dns_srv (const char *name, + const char *service, const char *proto, struct srventry **list, unsigned int *r_count); diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 4b61b72..869e7ed 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -288,6 +288,10 @@ int dns_v_api(void) { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#ifndef EPROTO +# define EPROTO EPROTONOSUPPORT +#endif + #if _WIN32 #define DNS_EINTR WSAEINTR @@ -4242,6 +4246,15 @@ size_t dns_txt_print(void *_dst, size_t lim, struct dns_txt *txt) { } /* dns_txt_print() */ +/* Some of the function pointers of DNS_RRTYPES are initialized with + * slighlly different fucntions, thus we can't use prototypes. */ +DNS_PRAGMA_PUSH +#if __clang__ +#pragma clang diagnostic ignored "-Wstrict-prototypes" +#elif DNS_GNUC_PREREQ(4,6,0) +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + static const struct dns_rrtype { enum dns_type type; const char *name; @@ -4267,6 +4280,10 @@ static const struct dns_rrtype { { DNS_T_AXFR, "AXFR", 0, 0, 0, 0, 0, 0, }, }; /* dns_rrtypes[] */ +DNS_PRAGMA_POP /*(-Wstrict-prototypes)*/ + + + static const struct dns_rrtype *dns_rrtype(enum dns_type type) { const struct dns_rrtype *t; @@ -6054,7 +6071,15 @@ int dns_nssconf_loadfile(struct dns_resolv_conf *resconf, FILE *fp) { if ('[' == dns_anyconf_peek(fp)) { dns_anyconf_skip("[ \t", fp); - while (dns_anyconf_scan(&cf, "%w_", fp, &error)) { + for (;;) { + if ('!' == dns_anyconf_peek(fp)) { + dns_anyconf_skip("! \t", fp); + /* FIXME: negating statuses; currently not implemented */ + dns_anyconf_skip("^#;]\n", fp); /* skip to end of criteria */ + break; + } + + if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) break; dns_anyconf_skip("= \t", fp); if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) { dns_anyconf_pop(&cf); /* discard status */ diff --git a/dirmngr/http.c b/dirmngr/http.c index 14d60df..35877d2 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2,7 +2,7 @@ * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010, * 2011 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015-2017 g10 Code GmbH * * This file is part of GnuPG. * @@ -255,6 +255,12 @@ struct http_context_s }; +/* Two flags to enable verbose and debug mode. Although currently not + * set-able a value > 1 for OPT_DEBUG enables debugging of the session + * reference counting. */ +static int opt_verbose; +static int opt_debug; + /* The global callback for the verification function. */ static gpg_error_t (*tls_callback) (http_t, http_session_t, int); @@ -330,9 +336,9 @@ _my_socket_new (int lnr, assuan_fd_t fd) } so->fd = fd; so->refcount = 1; - /* log_debug ("http.c:socket_new(%d): object %p for fd %d created\n", */ - /* lnr, so, so->fd); */ - (void)lnr; + if (opt_debug) + log_debug ("http.c:%d:socket_new: object %p for fd %d created\n", + lnr, so, so->fd); return so; } #define my_socket_new(a) _my_socket_new (__LINE__, (a)) @@ -342,9 +348,9 @@ static my_socket_t _my_socket_ref (int lnr, my_socket_t so) { so->refcount++; - /* log_debug ("http.c:socket_ref(%d) object %p for fd %d refcount now %d\n", */ - /* lnr, so, so->fd, so->refcount); */ - (void)lnr; + if (opt_debug > 1) + log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n", + lnr, so, so->fd, so->refcount); return so; } #define my_socket_ref(a) _my_socket_ref (__LINE__,(a)) @@ -360,9 +366,10 @@ _my_socket_unref (int lnr, my_socket_t so, if (so) { so->refcount--; - /* log_debug ("http.c:socket_unref(%d): object %p for fd %d ref now %d\n", */ - /* lnr, so, so->fd, so->refcount); */ - (void)lnr; + if (opt_debug > 1) + log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n", + lnr, so, so->fd, so->refcount); + if (!so->refcount) { if (preclose) @@ -469,6 +476,15 @@ make_header_line (const char *prefix, const char *suffix, +/* Set verbosity and debug mode for this module. */ +void +http_set_verbose (int verbose, int debug) +{ + opt_verbose = verbose; + opt_debug = debug; +} + + /* Register a non-standard global TLS callback function. If no verification is desired a callback needs to be registered which always returns NULL. */ @@ -562,9 +578,9 @@ session_unref (int lnr, http_session_t sess) return; sess->refcount--; - /* log_debug ("http.c:session_unref(%d): sess %p ref now %d\n", */ - /* lnr, sess, sess->refcount); */ - (void)lnr; + if (opt_debug > 1) + log_debug ("http.c:%d:session_unref: sess %p ref now %d\n", + lnr, sess, sess->refcount); if (sess->refcount) return; @@ -605,16 +621,93 @@ http_session_new (http_session_t *r_session, const char *tls_priority, #if HTTP_USE_NTBTLS { + x509_cert_t ca_chain; + char line[256]; + estream_t fp, mem_p; + size_t nread, nbytes; + struct b64state state; + void *buf; + size_t buflen; + char *pemname; + (void)tls_priority; - /* ntbtls_set_debug (99, NULL, NULL); */ + pemname = make_filename_try (gnupg_datadir (), + "sks-keyservers.netCA.pem", NULL); + if (!pemname) + { + err = gpg_error_from_syserror (); + log_error ("setting CA from file '%s' failed: %s\n", + pemname, gpg_strerror (err)); + goto leave; + } + + fp = es_fopen (pemname, "r"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't open '%s': %s\n", pemname, gpg_strerror (err)); + xfree (pemname); + goto leave; + } + xfree (pemname); + + mem_p = es_fopenmem (0, "r+b"); + err = b64dec_start (&state, "CERTIFICATE"); + if (err) + { + log_error ("b64dec failure: %s\n", gpg_strerror (err)); + goto leave; + } + + while ( (nread = es_fread (line, 1, DIM (line), fp)) ) + { + err = b64dec_proc (&state, line, nread, &nbytes); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_EOF) + break; + + log_error ("b64dec failure: %s\n", gpg_strerror (err)); + es_fclose (fp); + es_fclose (mem_p); + goto leave; + } + else if (nbytes) + es_fwrite (line, 1, nbytes, mem_p); + } + err = b64dec_finish (&state); + if (err) + { + log_error ("b64dec failure: %s\n", gpg_strerror (err)); + es_fclose (fp); + es_fclose (mem_p); + goto leave; + } + + es_fclose_snatch (mem_p, &buf, &buflen); + es_fclose (fp); + + err = ntbtls_x509_cert_new (&ca_chain); + if (err) + { + log_error ("ntbtls_x509_new failed: %s\n", gpg_strerror (err)); + xfree (buf); + goto leave; + } + + err = ntbtls_x509_append_cert (ca_chain, buf, buflen); + xfree (buf); err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT); if (err) { log_error ("ntbtls_new failed: %s\n", gpg_strerror (err)); + ntbtls_x509_cert_release (ca_chain); goto leave; } + + err = ntbtls_set_ca_chain (sess->tls_session, ca_chain, NULL); } #elif HTTP_USE_GNUTLS { @@ -731,7 +824,8 @@ http_session_new (http_session_t *r_session, const char *tls_priority, } #endif /*!HTTP_USE_GNUTLS*/ - /* log_debug ("http.c:session_new: sess %p created\n", sess); */ + if (opt_debug > 1) + log_debug ("http.c:session_new: sess %p created\n", sess); err = 0; #if USE_TLS @@ -754,8 +848,9 @@ http_session_ref (http_session_t sess) if (sess) { sess->refcount++; - /* log_debug ("http.c:session_ref: sess %p ref now %d\n", sess, */ - /* sess->refcount); */ + if (opt_debug > 1) + log_debug ("http.c:session_ref: sess %p ref now %d\n", + sess, sess->refcount); } return sess; } @@ -937,6 +1032,8 @@ http_start_data (http_t hd) { if (!hd->in_data) { + if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) + log_debug_with_string ("\r\n", "http.c:request-header:"); es_fputs ("\r\n", hd->fp_write); es_fflush (hd->fp_write); hd->in_data = 1; @@ -1169,6 +1266,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part, uri->opaque = 0; uri->v6lit = 0; uri->onion = 0; + uri->explicit_port = 0; /* A quick validity check. */ if (strspn (p, VALID_URI_CHARS) != n) @@ -1241,6 +1339,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part, { *p3++ = '\0'; uri->port = atoi (p3); + uri->explicit_port = 1; } if ((n = remove_escapes (uri->host)) < 0) @@ -1879,7 +1978,8 @@ send_request (http_t hd, const char *httphost, const char *auth, return err; } - /* log_debug ("request:\n%s\nEND request\n", request); */ + if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) + log_debug_with_string (request, "http.c:request:"); /* First setup estream so that we can write even the first line using estream. This is also required for the sake of gnutls. */ @@ -1914,6 +2014,8 @@ send_request (http_t hd, const char *httphost, const char *auth, { for (;headers; headers=headers->next) { + if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) + log_debug_with_string (headers->d, "http.c:request-header:"); if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) { @@ -2165,8 +2267,7 @@ parse_response (http_t hd) return GPG_ERR_EOF; if ((hd->flags & HTTP_FLAG_LOG_RESP)) - log_info ("RESP: '%.*s'\n", - (int)strlen(line)-(*line&&line[1]?2:0),line); + log_debug_with_string (line, "http.c:response:\n"); } while (!*line); @@ -2211,7 +2312,7 @@ parse_response (http_t hd) if ((*line == '\r' && line[1] == '\n') || *line == '\n') *line = 0; if ((hd->flags & HTTP_FLAG_LOG_RESP)) - log_info ("RESP: '%.*s'\n", + log_info ("http.c:RESP: '%.*s'\n", (int)strlen(line)-(*line&&line[1]?2:0),line); if (*line) { @@ -2313,6 +2414,68 @@ start_server () } #endif + + +/* Return true if SOCKS shall be used. This is the case if tor_mode + * is enabled and the desired address is not the loopback address. + * This function is basically a copy of the same internal fucntion in + * Libassuan. */ +static int +use_socks (struct sockaddr *addr) +{ + int mode; + + if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode) + return 0; /* Not in Tor mode. */ + else if (addr->sa_family == AF_INET6) + { + struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr; + const unsigned char *s; + int i; + + s = (unsigned char *)&addr_in6->sin6_addr.s6_addr; + if (s[15] != 1) + return 1; /* Last octet is not 1 - not the loopback address. */ + for (i=0; i < 15; i++, s++) + if (*s) + return 1; /* Non-zero octet found - not the loopback address. */ + + return 0; /* This is the loopback address. */ + } + else if (addr->sa_family == AF_INET) + { + struct sockaddr_in *addr_in = (struct sockaddr_in *)addr; + + if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127) + return 0; /* Loopback (127.0.0.0/8) */ + + return 1; + } + else + return 0; +} + + +/* Wrapper around assuan_sock_new which takes the domain from an + * address parameter. */ +static assuan_fd_t +my_sock_new_for_addr (struct sockaddr *addr, int type, int proto) +{ + int domain; + + if (use_socks (addr)) + { + /* Libassaun always uses 127.0.0.1 to connect to the socks + * server (i.e. the Tor daemon). */ + domain = AF_INET; + } + else + domain = addr->sa_family; + + return assuan_sock_new (domain, type, proto); +} + + /* Actually connect to a server. Returns the file descriptor or -1 on error. ERRNO is set on error. */ static assuan_fd_t @@ -2339,6 +2502,9 @@ connect_server (const char *server, unsigned short port, { #ifdef ASSUAN_SOCK_TOR + if (opt_debug) + log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n", + server, port); sock = assuan_sock_connect_byname (server, port, 0, NULL, ASSUAN_SOCK_TOR); if (sock == ASSUAN_INVALID_FD) @@ -2362,29 +2528,11 @@ connect_server (const char *server, unsigned short port, /* Do the SRV thing */ if (srvtag) { - /* We're using SRV, so append the tags. */ - if (1 + strlen (srvtag) + 6 + strlen (server) + 1 - <= DIMof (struct srventry, target)) - { - char *srvname = xtrymalloc (DIMof (struct srventry, target)); - - if (!srvname) /* Out of core */ - { - serverlist = NULL; - srvcount = 0; - } - else - { - stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag), - "._tcp."), server); - err = get_dns_srv (srvname, &serverlist, &srvcount); - if (err) - log_info ("getting SRV '%s' failed: %s\n", - srvname, gpg_strerror (err)); - xfree (srvname); - /* Note that on error SRVCOUNT is zero. */ - } - } + err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount); + if (err) + log_info ("getting '%s' SRV for '%s' failed: %s\n", + srvtag, server, gpg_strerror (err)); + /* Note that on error SRVCOUNT is zero. */ } if (!serverlist) @@ -2405,6 +2553,9 @@ connect_server (const char *server, unsigned short port, { dns_addrinfo_t aibuf, ai; + if (opt_debug) + log_debug ("http.c:connect_server: trying name='%s' port=%hu\n", + serverlist[srv].target, port); err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM, &aibuf, NULL); if (err) @@ -2424,7 +2575,7 @@ connect_server (const char *server, unsigned short port, if (sock != ASSUAN_INVALID_FD) assuan_sock_close (sock); - sock = assuan_sock_new (ai->family, ai->socktype, ai->protocol); + sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol); if (sock == ASSUAN_INVALID_FD) { int save_errno = errno; @@ -2555,7 +2706,8 @@ cookie_read (void *cookie, void *buffer, size_t size) ntbtls_get_stream (c->session->tls_session, &in, &out); nread = es_fread (buffer, 1, size, in); - log_debug ("TLS network read: %d/%u\n", nread, size); + if (opt_debug) + log_debug ("TLS network read: %d/%zu\n", nread, size); } else #elif HTTP_USE_GNUTLS @@ -2647,7 +2799,8 @@ cookie_write (void *cookie, const void *buffer_arg, size_t size) es_fflush (out); else nwritten = es_fwrite (buffer, 1, size, out); - log_debug ("TLS network write: %d/%u\n", nwritten, size); + if (opt_debug) + log_debug ("TLS network write: %d/%zu\n", nwritten, size); } else #elif HTTP_USE_GNUTLS diff --git a/dirmngr/http.h b/dirmngr/http.h index 2a36fda..0b581fe 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -53,6 +53,7 @@ struct parsed_uri_s unsigned int opaque:1;/* Unknown scheme; PATH has the rest. */ unsigned int v6lit:1; /* Host was given as a literal v6 address. */ unsigned int onion:1; /* .onion address given. */ + unsigned int explicit_port :1; /* The port was explicitly specified. */ char *auth; /* username/password for basic auth. */ char *host; /* Host (converted to lowercase). */ unsigned short port; /* Port (always set if the host is set). */ @@ -96,6 +97,8 @@ typedef struct http_session_s *http_session_t; struct http_context_s; typedef struct http_context_s *http_t; +void http_set_verbose (int verbose, int debug); + void http_register_tls_callback (gpg_error_t (*cb)(http_t,http_session_t,int)); void http_register_tls_ca (const char *fname); void http_register_netactivity_cb (void (*cb)(void)); diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index a6c22f8..45965ce 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -85,7 +85,7 @@ struct hostinfo_s time_t died_at; /* The time the host was marked dead. If this is 0 the host has been manually marked dead. */ char *cname; /* Canonical name of the host. Only set if this - is a pool. */ + is a pool or NAME has a numerical IP address. */ char *v4addr; /* A string with the v4 IP address of the host. NULL if NAME has a numeric IP address or no v4 address is available. */ @@ -374,21 +374,24 @@ add_host (const char *name, int is_pool, /* Map the host name NAME to the actual to be used host name. This - allows us to manage round robin DNS names. We use our own strategy - to choose one of the hosts. For example we skip those hosts which - failed for some time and we stick to one host for a time - independent of DNS retry times. If FORCE_RESELECT is true a new - host is always selected. The selected host is stored as a malloced - string at R_HOST; on error NULL is stored. If we know the port - used by the selected host, a string representation is written to - R_PORTSTR, otherwise it is left untouched. If R_HTTPFLAGS is not - NULL it will receive flags which are to be passed to http_open. If - R_POOLNAME is not NULL a malloced name of the pool is stored or - NULL if it is not a pool. */ + * allows us to manage round robin DNS names. We use our own strategy + * to choose one of the hosts. For example we skip those hosts which + * failed for some time and we stick to one host for a time + * independent of DNS retry times. If FORCE_RESELECT is true a new + * host is always selected. If SRVTAG is NULL no service record + * lookup will be done, if it is set that service name is used. The + * selected host is stored as a malloced string at R_HOST; on error + * NULL is stored. If we know the port used by the selected host from + * a service record, a string representation is written to R_PORTSTR, + * otherwise it is left untouched. If R_HTTPFLAGS is not NULL it will + * receive flags which are to be passed to http_open. If R_HTTPHOST + * is not NULL a malloced name of the host is stored there; this might + * be different from R_HOST in case it has been selected from a + * pool. */ static gpg_error_t -map_host (ctrl_t ctrl, const char *name, int force_reselect, +map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect, char **r_host, char *r_portstr, - unsigned int *r_httpflags, char **r_poolname) + unsigned int *r_httpflags, char **r_httphost) { gpg_error_t err = 0; hostinfo_t hi; @@ -397,8 +400,8 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, *r_host = NULL; if (r_httpflags) *r_httpflags = 0; - if (r_poolname) - *r_poolname = NULL; + if (r_httphost) + *r_httphost = NULL; /* No hostname means localhost. */ if (!name || !*name) @@ -426,7 +429,6 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, int refidx; int is_pool = 0; char *cname; - char *srvrecord; struct srventry *srvs; unsigned int srvscount; @@ -445,19 +447,10 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, } hi = hosttable[idx]; - if (!is_ip_address (name)) + if (srvtag && !is_ip_address (name)) { /* Check for SRV records. */ - srvrecord = xtryasprintf ("_hkp._tcp.%s", name); - if (srvrecord == NULL) - { - err = gpg_error_from_syserror (); - xfree (reftbl); - return err; - } - - err = get_dns_srv (srvrecord, &srvs, &srvscount); - xfree (srvrecord); + err = get_dns_srv (name, srvtag, NULL, &srvs, &srvscount); if (err) { xfree (reftbl); @@ -543,10 +536,10 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, if (hi->pool) { /* Deal with the pool name before selecting a host. */ - if (r_poolname) + if (r_httphost) { - *r_poolname = xtrystrdup (hi->cname? hi->cname : hi->name); - if (!*r_poolname) + *r_httphost = xtrystrdup (hi->cname? hi->cname : hi->name); + if (!*r_httphost) return gpg_error_from_syserror (); } @@ -565,10 +558,10 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, if (hi->poolidx == -1) { log_error ("no alive host found in pool '%s'\n", name); - if (r_poolname) + if (r_httphost) { - xfree (*r_poolname); - *r_poolname = NULL; + xfree (*r_httphost); + *r_httphost = NULL; } return gpg_error (GPG_ERR_NO_KEYSERVER); } @@ -578,14 +571,42 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, hi = hosttable[hi->poolidx]; assert (hi); } + else if (r_httphost && is_ip_address (hi->name)) + { + /* This is a numerical IP address and not a pool. We want to + * find the canonical name so that it can be used in the HTTP + * Host header. Fixme: We should store that name in the + * hosttable. */ + dns_addrinfo_t aibuf, ai; + char *host; + + err = resolve_dns_name (hi->name, 0, 0, SOCK_STREAM, &aibuf, NULL); + if (!err) + { + for (ai = aibuf; ai; ai = ai->next) + { + if (ai->family == AF_INET6 || ai->family == AF_INET) + { + err = resolve_dns_addr (ai->addr, ai->addrlen, 0, &host); + if (!err) + { + /* Okay, we return the first found name. */ + *r_httphost = host; + break; + } + } + } + } + free_dns_addrinfo (aibuf); + } if (hi->dead) { log_error ("host '%s' marked as dead\n", hi->name); - if (r_poolname) + if (r_httphost) { - xfree (*r_poolname); - *r_poolname = NULL; + xfree (*r_httphost); + *r_httphost = NULL; } return gpg_error (GPG_ERR_NO_KEYSERVER); } @@ -612,10 +633,10 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, if (!*r_host) { err = gpg_error_from_syserror (); - if (r_poolname) + if (r_httphost) { - xfree (*r_poolname); - *r_poolname = NULL; + xfree (*r_httphost); + *r_httphost = NULL; } return err; } @@ -830,7 +851,7 @@ ks_hkp_print_hosttable (ctrl_t ctrl) gpg_error_t ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri) { - const char const data[] = + const char data[] = "Handler for HKP URLs:\n" " hkp://\n" #if HTTP_USE_GNUTLS || HTTP_USE_NTBTLS @@ -858,55 +879,65 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri) /* Build the remote part of the URL from SCHEME, HOST and an optional - PORT. Returns an allocated string at R_HOSTPORT or NULL on failure - If R_POOLNAME is not NULL it receives a malloced string with the - poolname. */ + * PORT. If NO_SRV is set no SRV record lookup will be done. Returns + * an allocated string at R_HOSTPORT or NULL on failure. If + * R_HTTPHOST is not NULL it receives a malloced string with the + * hostname; this may be different from HOST if HOST is selected from + * a pool. */ static gpg_error_t make_host_part (ctrl_t ctrl, const char *scheme, const char *host, unsigned short port, - int force_reselect, - char **r_hostport, unsigned int *r_httpflags, char **r_poolname) + int force_reselect, int no_srv, + char **r_hostport, unsigned int *r_httpflags, char **r_httphost) { gpg_error_t err; + const char *srvtag; char portstr[10]; char *hostname; *r_hostport = NULL; - portstr[0] = 0; - err = map_host (ctrl, host, force_reselect, - &hostname, portstr, r_httpflags, r_poolname); - if (err) - return err; - - /* Map scheme and port. */ if (!strcmp (scheme, "hkps") || !strcmp (scheme,"https")) { scheme = "https"; - if (! *portstr) - strcpy (portstr, "443"); + srvtag = no_srv? NULL : "pgpkey-https"; } else /* HKP or HTTP. */ { scheme = "http"; - if (! *portstr) - strcpy (portstr, "11371"); + srvtag = no_srv? NULL : "pgpkey-http"; } - if (port) + + portstr[0] = 0; + err = map_host (ctrl, host, srvtag, force_reselect, + &hostname, portstr, r_httpflags, r_httphost); + if (err) + return err; + + /* If map_host did not return a port (from a SRV record) but a port + * has been specified (implicitly or explicitly) then use that port. + * In the case that a port was not specified (which is probably a + * bug in https.c) we will set up defaults. */ + if (*portstr) + ; + else if (!*portstr && port) snprintf (portstr, sizeof portstr, "%hu", port); + else if (!strcmp (scheme,"https")) + strcpy (portstr, "443"); else - { - /*fixme_do_srv_lookup ()*/ - } + strcpy (portstr, "11371"); - *r_hostport = strconcat (scheme, "://", hostname, ":", portstr, NULL); + if (*hostname != '[' && is_ip_address (hostname) == 6) + *r_hostport = strconcat (scheme, "://[", hostname, "]:", portstr, NULL); + else + *r_hostport = strconcat (scheme, "://", hostname, ":", portstr, NULL); xfree (hostname); if (!*r_hostport) { - if (r_poolname) + if (r_httphost) { - xfree (*r_poolname); - *r_poolname = NULL; + xfree (*r_httphost); + *r_httphost = NULL; } return gpg_error_from_syserror (); } @@ -923,7 +954,11 @@ ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri) gpg_error_t err; char *hostport = NULL; - err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, 1, + /* NB: With an explicitly given port we do not want to consult a + * service record because that might be in conflict with the port + * from such a service record. */ + err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, + 1, uri->explicit_port, &hostport, NULL, NULL); if (err) { @@ -968,6 +1003,29 @@ ks_hkp_housekeeping (time_t curtime) } +/* Reload (SIGHUP) action for this module. We mark all host alive + * even those which have been manually shot. */ +void +ks_hkp_reload (void) +{ + int idx, count; + hostinfo_t hi; + + for (idx=count=0; idx < hosttable_size; idx++) + { + hi = hosttable[idx]; + if (!hi) + continue; + if (!hi->dead) + continue; + hi->dead = 0; + count++; + } + if (count) + log_info ("number of resurrected hosts: %d", count); +} + + /* Send an HTTP request. On success returns an estream object at R_FP. HOSTPORTSTR is only used for diagnostics. If HTTPHOST is not NULL it will be used as HTTP "Host" header. If POST_CB is not @@ -1131,10 +1189,25 @@ handle_send_request_error (gpg_error_t err, const char *request, { int retry = 0; + /* Fixme: Should we disable all hosts of a protocol family if a + * request for an address of that familiy returned ENETDOWN? */ + switch (gpg_err_code (err)) { case GPG_ERR_ECONNREFUSED: + if (opt.use_tor) + { + assuan_fd_t sock; + + sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR); + if (sock == ASSUAN_INVALID_FD) + log_info ("(it seems Tor is not running)\n"); + else + assuan_sock_close (sock); + } + /*FALLTHRU*/ case GPG_ERR_ENETUNREACH: + case GPG_ERR_ENETDOWN: case GPG_ERR_UNKNOWN_HOST: case GPG_ERR_NETWORK: if (mark_host_dead (request) && *tries_left) @@ -1147,6 +1220,7 @@ handle_send_request_error (gpg_error_t err, const char *request, log_info ("selecting a different host due to a timeout\n"); retry = 1; } + break; default: break; @@ -1229,7 +1303,8 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, xfree (hostport); hostport = NULL; xfree (httphost); httphost = NULL; - err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect, + err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, + reselect, uri->explicit_port, &hostport, &httpflags, &httphost); if (err) goto leave; @@ -1370,7 +1445,8 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp) /* Build the request string. */ xfree (hostport); hostport = NULL; xfree (httphost); httphost = NULL; - err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect, + err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, + reselect, uri->explicit_port, &hostport, &httpflags, &httphost); if (err) goto leave; @@ -1482,7 +1558,8 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen) again: xfree (hostport); hostport = NULL; xfree (httphost); httphost = NULL; - err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect, + err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, + reselect, uri->explicit_port, &hostport, &httpflags, &httphost); if (err) goto leave; diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 4c4ab1e..858c943 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -35,7 +35,7 @@ gpg_error_t ks_http_help (ctrl_t ctrl, parsed_uri_t uri) { - const char const data[] = + const char data[] = "Handler for HTTP URLs:\n" " http://\n" #if HTTP_USE_GNUTLS || HTTP_USE_NTBTLS diff --git a/dirmngr/ks-engine-kdns.c b/dirmngr/ks-engine-kdns.c index d49d046..9bb0d42 100644 --- a/dirmngr/ks-engine-kdns.c +++ b/dirmngr/ks-engine-kdns.c @@ -33,7 +33,7 @@ gpg_error_t ks_kdns_help (ctrl_t ctrl, parsed_uri_t uri) { - const char const data[] = + const char data[] = "This keyserver engine accepts URLs of the form:\n" " kdns://[NAMESERVER]/[ROOT][?at=STRING]\n" "with\n" diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index ee55bf2..6d520e9 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -289,7 +289,7 @@ epoch2ldaptime (time_t stamp) gpg_error_t ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri) { - const char const data[] = + const char data[] = "Handler for LDAP URLs:\n" " ldap://host:port/[BASEDN]???[bindname=BINDNAME,password=PASSWORD]\n" "\n" diff --git a/dirmngr/misc.c b/dirmngr/misc.c index ac3856e..2ee6d82 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -296,6 +296,7 @@ dump_cert (const char *text, ksba_cert_t cert) ksba_sexp_t sexp; char *p; ksba_isotime_t t; + int idx; log_debug ("BEGIN Certificate '%s':\n", text? text:""); if (cert) @@ -326,6 +327,13 @@ dump_cert (const char *text, ksba_cert_t cert) dump_string (p); ksba_free (p); log_printf ("\n"); + for (idx=1; (p = ksba_cert_get_subject (cert, idx)); idx++) + { + log_debug (" aka: "); + dump_string (p); + ksba_free (p); + log_printf ("\n"); + } log_debug (" hash algo: %s\n", ksba_cert_get_digest_algo (cert)); diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c index 8c893aa..9127cf7 100644 --- a/dirmngr/ocsp.c +++ b/dirmngr/ocsp.c @@ -44,7 +44,7 @@ static const char oidstr_ocsp[] = "1.3.6.1.5.5.7.48.1"; HashAlgorithm AlgorithmIdentifier, certificateHash OCTET STRING } */ -static const char oidstr_certHash[] = "1.3.36.8.3.13"; +/* static const char oidstr_certHash[] = "1.3.36.8.3.13"; */ diff --git a/dirmngr/server.c b/dirmngr/server.c index a785238..c9c4ad4 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -709,13 +709,6 @@ cmd_dns_cert (assuan_context_t ctx, char *line) } } - if (opt.use_tor && (err = enable_dns_tormode (0))) - { - /* Tor mode is requested but the DNS code can't enable it. */ - assuan_set_error (ctx, err, "error enabling Tor mode"); - goto leave; - } - if (pka_mode || dane_mode) { char *domain; /* Points to mbox. */ @@ -833,13 +826,15 @@ cmd_wkd_get (assuan_context_t ctx, char *line) ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; char *mbox = NULL; - char *domain; /* Points to mbox. */ + char *domainbuf = NULL; + char *domain; /* Points to mbox or domainbuf. */ char sha1buf[20]; char *uri = NULL; char *encodedhash = NULL; int opt_submission_addr; int opt_policy_flags; int no_log = 0; + char portstr[20] = { 0 }; opt_submission_addr = has_option (line, "--submission-address"); opt_policy_flags = has_option (line, "--policy-flags"); @@ -853,6 +848,50 @@ cmd_wkd_get (assuan_context_t ctx, char *line) } *domain++ = 0; + /* Check for SRV records. */ + if (1) + { + struct srventry *srvs; + unsigned int srvscount; + size_t domainlen, targetlen; + int i; + + err = get_dns_srv (domain, "openpgpkey", NULL, &srvs, &srvscount); + if (err) + goto leave; + + /* Find the first target which also ends in DOMAIN or is equal + * to DOMAIN. */ + domainlen = strlen (domain); + for (i = 0; i < srvscount; i++) + { + log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port); + targetlen = strlen (srvs[i].target); + if ((targetlen > domainlen + 1 + && srvs[i].target[targetlen - domainlen - 1] == '.' + && !ascii_strcasecmp (srvs[i].target + targetlen - domainlen, + domain)) + || (targetlen == domainlen + && !ascii_strcasecmp (srvs[i].target, domain))) + { + /* found. */ + domainbuf = xtrystrdup (srvs[i].target); + if (!domainbuf) + { + err = gpg_error_from_syserror (); + xfree (srvs); + goto leave; + } + domain = domainbuf; + if (srvs[i].port) + snprintf (portstr, sizeof portstr, ":%hu", srvs[i].port); + break; + } + } + xfree (srvs); + log_debug ("srv: got '%s%s'\n", domain, portstr); + } + gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox)); encodedhash = zb32_encode (sha1buf, 8*20); if (!encodedhash) @@ -865,6 +904,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line) { uri = strconcat ("https://", domain, + portstr, "/.well-known/openpgpkey/submission-address", NULL); } @@ -872,6 +912,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line) { uri = strconcat ("https://", domain, + portstr, "/.well-known/openpgpkey/policy", NULL); } @@ -879,6 +920,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line) { uri = strconcat ("https://", domain, + portstr, "/.well-known/openpgpkey/hu/", encodedhash, NULL); @@ -914,6 +956,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line) xfree (uri); xfree (encodedhash); xfree (mbox); + xfree (domainbuf); return leave_cmd (ctx, err); } diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c index b087b5e..23c0c6a 100644 --- a/dirmngr/t-dns-stuff.c +++ b/dirmngr/t-dns-stuff.c @@ -51,7 +51,6 @@ main (int argc, char **argv) gpg_error_t err; int any_options = 0; int opt_tor = 0; - int opt_new_circuit = 0; int opt_cert = 0; int opt_srv = 0; int opt_bracket = 0; @@ -103,11 +102,6 @@ main (int argc, char **argv) opt_tor = 1; argc--; argv++; } - else if (!strcmp (*argv, "--new-circuit")) - { - opt_new_circuit = 1; - argc--; argv++; - } else if (!strcmp (*argv, "--standard-resolver")) { enable_standard_resolver (1); @@ -171,15 +165,7 @@ main (int argc, char **argv) init_sockets (); if (opt_tor) - { - err = enable_dns_tormode (opt_new_circuit); - if (err) - { - fprintf (stderr, "error switching into Tor mode: %s\n", - gpg_strerror (err)); - exit (1); - } - } + enable_dns_tormode (0); if (opt_cert) { @@ -249,7 +235,7 @@ main (int argc, char **argv) int i; err = get_dns_srv (name? name : "_hkp._tcp.wwwkeys.pgp.net", - &srv, &count); + NULL, NULL, &srv, &count); if (err) printf ("get_dns_srv failed: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); diff --git a/doc/DETAILS b/doc/DETAILS index 568500e..ac599fc 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -761,6 +761,19 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: takes on value 0. Instead, if there is a conflict, VALIDITY still reflects the key's validity (values: 1-4). + SUMMARY values use the euclidean distance (m = sqrt(a² + b²)) rather + then the sum of the magnitudes (m = a + b) to ensure a balance between + verified signatures and encrypted messages. + + Values are calculated based on the number of days where a key was used + for verifying a signature or to encrypt to it. + The ranges for the values are: + + - 1 :: signature_days + encryption_days == 0 + - 2 :: 1 <= sqrt(signature_days² + encryption_days²) < 8 + - 3 :: 8 <= sqrt(signature_days² + encryption_days²) < 42 + - 4 :: sqrt(signature_days² + encryption_days²) >= 42 + SIGN-COUNT and ENCRYPTION-COUNT are the number of messages that we have seen that have been signed by this key / encryption to this key. diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 5b4e68b..e27157c 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -131,6 +131,10 @@ will thus trigger reading of fresh CRLs. @node Dirmngr Options @section Option Summary +Note that all long options with the exception of @option{--options} +and @option{--homedir} may also be given in the configuration file +after stripping off the two leading dashes. + @table @gnupgtabopt @item --options @var{file} @@ -194,9 +198,11 @@ however carefully selected to best aid in debugging. @item --debug @var{flags} @opindex debug -This option is only useful for debugging and the behavior may change at -any time without notice. FLAGS are bit encoded and may be given in -usual C-Syntax. +Set debugging flags. This option is only useful for debugging and its +behavior may change with a new release. All flags are or-ed and may +be given in C syntax (e.g. 0x0042) or as a comma separated list of +flag names. To get a list of all supported flags the single word +"help" can be used. @item --debug-all @opindex debug-all @@ -239,10 +245,8 @@ useful for debugging. @item --use-tor @opindex use-tor This option switches Dirmngr and thus GnuPG into ``Tor mode'' to route -all network access via Tor (an anonymity network). WARNING: As of now -this still leaks the DNS queries; e.g. to lookup the hosts in a -keyserver pool. Certain other features are disabled if this mode is -active. +all network access via Tor (an anonymity network). Certain other +features are disabled if this mode is active. @item --standard-resolver @opindex standard-resolver @@ -266,7 +270,13 @@ the list of current software versions. If this option is enabled, or if @option{use-tor} is active, the list is retrieved when the local copy does not exist or is older than 5 to 7 days. See the option @option{--query-swdb} of the command @command{gpgconf} for more -details. +details. Note, that regardless of this option a version check can +always be triggered using this command: + +@example + gpg-connect-agent --dirmngr 'loadswdb --force' /bye +@end example + @item --keyserver @var{name} @opindex keyserver @@ -493,11 +503,20 @@ certificate for that pool. Otherwise, it will use the system CAs. @section Configuration Dirmngr makes use of several directories when running in daemon mode: +There are a few configuration files whih control the operation of +dirmngr. By default they may all be found in the current home +directory (@pxref{option --homedir}). @table @file -@item ~/.gnupg -This is the standard home directory for all configuration files. +@item dirmngr.conf +@efindex dirmngr.conf +This is the standard configuration file read by @command{dirmngr} on +startup. It may contain any valid long option; the leading two dashes +may not be entered and the option may not be abbreviated. This file +is also read after a @code{SIGHUP} however not all options will +actually have an effect. This default name may be changed on the +command line (@pxref{option --options}). You should backup this file. @item /etc/gnupg/trusted-certs This directory should be filled with certificates of Root CAs you diff --git a/doc/examples/systemd-user/dirmngr.service b/doc/examples/systemd-user/dirmngr.service index c79dfc5..ded533b 100644 --- a/doc/examples/systemd-user/dirmngr.service +++ b/doc/examples/systemd-user/dirmngr.service @@ -8,3 +8,4 @@ RefuseManualStart=true [Service] ExecStart=/usr/bin/dirmngr --supervised +ExecReload=/usr/bin/gpgconf --reload dirmngr diff --git a/doc/examples/systemd-user/gpg-agent.service b/doc/examples/systemd-user/gpg-agent.service index 9ab9220..e88dc7f 100644 --- a/doc/examples/systemd-user/gpg-agent.service +++ b/doc/examples/systemd-user/gpg-agent.service @@ -8,3 +8,4 @@ RefuseManualStart=true [Service] ExecStart=/usr/bin/gpg-agent --supervised +ExecReload=/usr/bin/gpgconf --reload gpg-agent diff --git a/doc/gpg.texi b/doc/gpg.texi index 469e548..8e1a5e6 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -255,6 +255,13 @@ out the actual signed data, but there are other pitfalls with this format as well. It is suggested to avoid cleartext signatures in favor of detached signatures. +Note: Sometimes the use of the @command{gpgv} tool is easier than +using the full-fledged @command{gpg} with this option. @command{gpgv} +is designed to compare signed data against a list of trusted keys and +returns with success only for a good signature. It has its own manual +page. + + @item --multifile @opindex multifile This modifies certain other commands to accept multiple files for @@ -2276,6 +2283,12 @@ opposite meaning. The options are: the most recent self-signature on each user ID. This option is the same as running the @option{--edit-key} command "minimize" after import. Defaults to no. + + @item restore + @itemx import-restore + Import in key restore mode. This imports all data which is usually + skipped during import; including all GnuPG specific data. All other + contradicting options are overridden. @end table @item --import-filter @code{@var{name}=@var{expr}} @@ -2386,6 +2399,13 @@ opposite meaning. The options are: @c when the exported subkey is to be used on an unattended machine where @c a passphrase doesn't necessarily make sense. Defaults to no. + @item backup + @itemx export-backup + Export for use as a backup. The exported data includes all data + which is needed to restore the key or keys later with GnuPG. The + format is basically the OpenPGP format but enhanced with GnuPG + specific data. All other contradicting options are overridden. + @item export-clean Compact (remove all signatures from) user IDs on the key being exported if the user IDs are not usable. Also, do not export any @@ -2741,6 +2761,9 @@ forth to @var{epoch} which is the number of seconds elapsed since the year 1970. Alternatively @var{epoch} may be given as a full ISO time string (e.g. "20070924T154812"). +If you suffix @var{epoch} with an exclamation mark (!), the system time +will appear to be frozen at the specified time. + @item --enable-progress-filter @opindex enable-progress-filter Enable certain PROGRESS status outputs. This option allows frontends diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 4cf44bc..1617801 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -516,11 +516,10 @@ done on the same card unless he call this function. Return the serial number of the card using a status response like: @example - S SERIALNO D27600000000000000000000 0 + S SERIALNO D27600000000000000000000 @end example -The trailing 0 should be ignored for now, it is reserved for a future -extension. The serial number is the hex encoded value identified by +The serial number is the hex encoded value identified by the @code{0x5A} tag in the GDO file (FIX=0x2F02). @@ -537,7 +536,7 @@ used without the @option{--force} option, the command might do an INQUIRE like this: @example - INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp> + INQUIRE KNOWNCARDP <hexstring_with_serialNumber> @end example The client should just send an @code{END} if the processing should go on diff --git a/doc/tools.texi b/doc/tools.texi index d321b69..bdef6a2 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -54,13 +54,14 @@ other utilities. This tool is not available for Windows. @command{watchgnupg} is commonly invoked as @example -watchgnupg --force ~/.gnupg/S.log +watchgnupg --force $(gpgconf --list-dirs socketdir)/S.log @end example @manpause @noindent -This starts it on the current terminal for listening on the socket -@file{~/.gnupg/S.log}. +This starts it on the current terminal for listening on the standard +logging socket (which is either @file{~/.gnupg/S.log} or +@file{/var/run/user/UID/gnupg/S.log}). @mansect options @noindent @@ -77,6 +78,10 @@ Delete an already existing socket file. Instead of reading from a local socket, listen for connects on TCP port @var{n}. +@item --time-only +@opindex time-only +Do not print the date part of the timestamp. + @item --verbose @opindex verbose Enable extra informational output. @@ -96,21 +101,22 @@ Display a brief help page and exit. @chapheading Examples @example -$ watchgnupg --force /home/foo/.gnupg/S.log +$ watchgnupg --force --time-only $(gpgconf --list-dirs socketdir)/S.log @end example This waits for connections on the local socket -@file{/home/foo/.gnupg/S.log} and shows all log entries. To make this -work the option @option{log-file} needs to be used with all modules -which logs are to be shown. The value for that option must be given -with a special prefix (e.g. in the conf files): +(e.g. @file{/home/foo/.gnupg/S.log}) and shows all log entries. To +make this work the option @option{log-file} needs to be used with all +modules which logs are to be shown. The suggested entry for the +configuration files is: @example -log-file socket:///home/foo/.gnupg/S.log +log-file socket:// @end example -If only @code{socket://} is used a default socket file named -@file{S.log} in the standard socket directory is used. +If the default socket as given above and returned by "echo $(gpgconf +--list-dirs socketdir)/S.log" is not desired an arbitrary socket name +can be specified, for example @file{socket:///home/foo/bar/mysocket}. For debugging purposes it is also possible to do remote logging. Take care if you use this feature because the information is send in the clear over the network. Use this syntax in the conf files: @@ -119,13 +125,14 @@ clear over the network. Use this syntax in the conf files: log-file tcp://192.168.1.1:4711 @end example -You may use any port and not just 4711 as shown above; only IP addresses -are supported (v4 and v6) and no host names. You need to start -@command{watchgnupg} with the @option{tcp} option. Note that under -Windows the registry entry @var{HKCU\Software\GNU\GnuPG:DefaultLogFile} -can be used to change the default log output from @code{stderr} to -whatever is given by that entry. However the only useful entry is a TCP -name for remote debugging. +You may use any port and not just 4711 as shown above; only IP +addresses are supported (v4 and v6) and no host names. You need to +start @command{watchgnupg} with the @option{tcp} option. Note that +under Windows the registry entry +@var{HKCU\Software\GNU\GnuPG:DefaultLogFile} can be used to change the +default log output from @code{stderr} to whatever is given by that +entry. However the only useful entry is a TCP name for remote +debugging. @mansect see also @@ -329,9 +336,10 @@ force an update of that file this command can be used: @item --reload [@var{component}] @opindex reload -Reload all or the given component. This is basically the same as sending -a SIGHUP to the component. Components which don't support reloading are -ignored. +Reload all or the given component. This is basically the same as +sending a SIGHUP to the component. Components which don't support +reloading are ignored. Without @var{component} or by using "all" for +@var{component} all components which are daemons are reloaded. @item --launch [@var{component}] @opindex launch @@ -339,14 +347,16 @@ If the @var{component} is not already running, start it. @command{component} must be a daemon. This is in general not required because the system starts these daemons as needed. However, external software making direct use of @command{gpg-agent} or @command{dirmngr} -may use this command to ensure that they are started. +may use this command to ensure that they are started. Using "all" for +@var{component} launches all components which are daemons. @item --kill [@var{component}] @opindex kill Kill the given component. Components which support killing are @command{gpg-agent} and @command{scdaemon}. Components which don't -support reloading are ignored. Note that as of now reload and kill -have the same effect for @command{scdaemon}. +support reloading are ignored. Using "all" for @var{component} kills +all components running as daemons. Note that as of now reload and +kill have the same effect for @command{scdaemon}. @item --create-socketdir @opindex create-socketdir diff --git a/g10/export.c b/g10/export.c index ad42b41..f354ca0 100644 --- a/g10/export.c +++ b/g10/export.c @@ -116,6 +116,10 @@ parse_export_options(char *str,unsigned int *options,int noisy) {"export-pka", EXPORT_PKA_FORMAT, NULL, NULL }, {"export-dane", EXPORT_DANE_FORMAT, NULL, NULL }, + {"backup", EXPORT_BACKUP, NULL, + N_("use the GnuPG key backup format")}, + {"export-backup", EXPORT_BACKUP, NULL, NULL }, + /* Aliases for backward compatibility */ {"include-local-sigs",EXPORT_LOCAL_SIGS,NULL,NULL}, {"include-attributes",EXPORT_ATTRIBUTES,NULL,NULL}, @@ -127,8 +131,18 @@ parse_export_options(char *str,unsigned int *options,int noisy) {NULL,0,NULL,NULL} /* add tags for include revoked and disabled? */ }; + int rc; - return parse_options(str,options,export_opts,noisy); + rc = parse_options (str, options, export_opts, noisy); + if (rc && (*options & EXPORT_BACKUP)) + { + /* Alter other options we want or don't want for restore. */ + *options |= (EXPORT_LOCAL_SIGS | EXPORT_ATTRIBUTES + | EXPORT_SENSITIVE_REVKEYS); + *options &= ~(EXPORT_CLEAN | EXPORT_MINIMAL + | EXPORT_PKA_FORMAT | EXPORT_DANE_FORMAT); + } + return rc; } @@ -1518,6 +1532,7 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, u32 subkidbuf[2], *subkid; kbnode_t kbctx, node; + /* NB: walk_kbnode skips packets marked as deleted. */ for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) { if (skip_until_subkey) @@ -1534,8 +1549,9 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, if (node->pkt->pkttype == PKT_COMMENT) continue; - /* Make sure that ring_trust packets never get exported. */ - if (node->pkt->pkttype == PKT_RING_TRUST) + /* Make sure that ring_trust packets are only exported in backup + * mode. */ + if (node->pkt->pkttype == PKT_RING_TRUST && !(options & EXPORT_BACKUP)) continue; /* If exact is set, then we only export what was requested @@ -3493,10 +3493,20 @@ main (int argc, char **argv) case oFakedSystemTime: { - time_t faked_time = isotime2epoch (pargs.r.ret_str); + size_t len = strlen (pargs.r.ret_str); + int freeze = 0; + time_t faked_time; + + if (len > 0 && pargs.r.ret_str[len-1] == '!') + { + freeze = 1; + pargs.r.ret_str[len-1] = '\0'; + } + + faked_time = isotime2epoch (pargs.r.ret_str); if (faked_time == (time_t)(-1)) faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10); - gnupg_set_time (faked_time, 0); + gnupg_set_time (faked_time, freeze); } break; diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index 512cb45..fafbfd2 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -1654,13 +1654,17 @@ mksubpkt_callback (PKT_signature *sig, void *cookie) if (si->reason_for_revocation) { - int l = 1 + strlen (si->reason_for_revocation); - char buf[l]; + int len = 1 + strlen (si->reason_for_revocation); + char *buf; + + buf = xmalloc (len); buf[0] = si->reason_for_revocation_code; - memcpy (&buf[1], si->reason_for_revocation, l - 1); + memcpy (&buf[1], si->reason_for_revocation, len - 1); + + build_sig_subpkt (sig, SIGSUBPKT_REVOC_REASON, buf, len); - build_sig_subpkt (sig, SIGSUBPKT_REVOC_REASON, buf, l); + xfree (buf); } if (si->features) @@ -2540,10 +2544,13 @@ encrypted (const char *option, int argc, char *argv[], void *cookie) if (do_debug) { - char buf[2 * session_key.keylen + 1]; + char *buf; + + buf = xmalloc (2 * session_key.keylen + 1); debug ("session key: algo: %d; keylen: %d; key: %s\n", session_key.algo, session_key.keylen, bin2hex (session_key.key, session_key.keylen, buf)); + xfree (buf); } if (strcmp (option, "--encrypted-mdc") == 0) diff --git a/g10/import.c b/g10/import.c index 1ed11bf..b6c04dc 100644 --- a/g10/import.c +++ b/g10/import.c @@ -175,6 +175,10 @@ parse_import_options(char *str,unsigned int *options,int noisy) {"import-export", IMPORT_EXPORT, NULL, N_("run import filters and export key immediately")}, + {"restore", IMPORT_RESTORE, NULL, + N_("assume the GnuPG key backup format")}, + {"import-restore", IMPORT_RESTORE, NULL, NULL}, + /* Aliases for backward compatibility */ {"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL}, {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL}, @@ -186,8 +190,18 @@ parse_import_options(char *str,unsigned int *options,int noisy) the new design. */ {NULL,0,NULL,NULL} }; + int rc; - return parse_options(str,options,import_opts,noisy); + rc = parse_options (str, options, import_opts, noisy); + if (rc && (*options & IMPORT_RESTORE)) + { + /* Alter other options we want or don't want for restore. */ + *options |= (IMPORT_LOCAL_SIGS | IMPORT_KEEP_OWNERTTRUST); + *options &= ~(IMPORT_MINIMAL | IMPORT_CLEAN + | IMPORT_REPAIR_PKS_SUBKEY_BUG + | IMPORT_MERGE_ONLY); + } + return rc; } @@ -833,7 +847,9 @@ read_block( IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys) break; case PKT_RING_TRUST: - /* Skip those packets. */ + /* Skip those packets unless we are in restore mode. */ + if ((opt.import_options & IMPORT_RESTORE)) + goto x_default; free_packet( pkt ); init_packet(pkt); break; @@ -848,6 +864,7 @@ read_block( IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys) } in_cert = 1; default: + x_default: if (in_cert && valid_keyblock_packet (pkt->pkttype)) { if (!root ) diff --git a/g10/keydb.h b/g10/keydb.h index 8daa9ee..c9f5b1c 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -61,12 +61,6 @@ struct kbnode_struct { #define is_cloned_kbnode(a) ((a)->private_flag & 2) -enum resource_type { - rt_UNKNOWN = 0, - rt_RING = 1 -}; - - /* Bit flags used with build_pk_list. */ enum { @@ -75,28 +69,14 @@ enum PK_LIST_CONFIG = 4, /* Specified via config file. */ PK_LIST_FROM_FILE = 8 /* Take key from file with that name. */ }; + /* To store private data in the flags the private data must be left - shifted by this value. */ + * shifted by this value. */ enum { PK_LIST_SHIFT = 4 }; -/**************** - * A data structure to hold information about the external position - * of a keyblock. - */ -struct keyblock_pos_struct { - int resno; /* resource number */ - enum resource_type rt; - off_t offset; /* position information */ - unsigned count; /* length of the keyblock in packets */ - iobuf_t fp; /* Used by enum_keyblocks. */ - int secret; /* working on a secret keyring */ - PACKET *pkt; /* ditto */ - int valid; -}; -typedef struct keyblock_pos_struct KBPOS; /* Structure to hold a couple of public key certificates. */ typedef struct pk_list *PK_LIST; /* Deprecated. */ diff --git a/g10/keyedit.c b/g10/keyedit.c index dadf586..1456d28 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -281,11 +281,11 @@ print_one_sig (int rc, KBNODE keyblock, KBNODE node, if (sig->flags.policy_url && ((opt.list_options & LIST_SHOW_POLICY_URLS) || extended)) - show_policy_url (sig, 3, 0); + show_policy_url (sig, 3, -1); if (sig->flags.notation && ((opt.list_options & LIST_SHOW_NOTATIONS) || extended)) - show_notation (sig, 3, 0, + show_notation (sig, 3, -1, ((opt. list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + ((opt. @@ -293,7 +293,7 @@ print_one_sig (int rc, KBNODE keyblock, KBNODE node, if (sig->flags.pref_ks && ((opt.list_options & LIST_SHOW_KEYSERVER_URLS) || extended)) - show_keyserver_url (sig, 3, 0); + show_keyserver_url (sig, 3, -1); if (extended) { diff --git a/g10/keygen.c b/g10/keygen.c index b4fddba..98ef29e 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -434,9 +434,11 @@ keygen_set_std_prefs (const char *string,int personal) if(strlen(string)) { - char *dup, *tok, *prefstring; + char *prefstringbuf; + char *tok, *prefstring; - dup = prefstring = xstrdup (string); /* need a writable string! */ + /* We need a writable string. */ + prefstring = prefstringbuf = xstrdup (string); while((tok=strsep(&prefstring," ,"))) { @@ -470,7 +472,7 @@ keygen_set_std_prefs (const char *string,int personal) } } - xfree (dup); + xfree (prefstringbuf); } if(!rc) diff --git a/g10/keylist.c b/g10/keylist.c index a5fdc06..4fe1e40 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -304,6 +304,7 @@ status_one_subpacket (sigsubpkttype_t type, size_t len, int flags, /* Print a policy URL. Allowed values for MODE are: + * -1 - print to the TTY * 0 - print to stdout. * 1 - use log_info and emit status messages. * 2 - emit only status messages. @@ -314,50 +315,48 @@ show_policy_url (PKT_signature * sig, int indent, int mode) const byte *p; size_t len; int seq = 0, crit; - estream_t fp = mode ? log_get_stream () : es_stdout; + estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout; while ((p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit))) { if (mode != 2) { - int i; const char *str; - for (i = 0; i < indent; i++) - es_putc (' ', fp); + tty_fprintf (fp, "%*s", indent, ""); if (crit) str = _("Critical signature policy: "); else str = _("Signature policy: "); - if (mode) + if (mode > 0) log_info ("%s", str); else - es_fprintf (fp, "%s", str); - print_utf8_buffer (fp, p, len); - es_fprintf (fp, "\n"); + tty_fprintf (fp, "%s", str); + tty_print_utf8_string2 (fp, p, len, 0); + tty_fprintf (fp, "\n"); } - if (mode) + if (mode > 0) write_status_buffer (STATUS_POLICY_URL, p, len, 0); } } -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only -*/ -/* TODO: use this */ +/* Print a keyserver URL. Allowed values for MODE are: + * -1 - print to the TTY + * 0 - print to stdout. + * 1 - use log_info and emit status messages. + * 2 - emit only status messages. + */ void show_keyserver_url (PKT_signature * sig, int indent, int mode) { const byte *p; size_t len; int seq = 0, crit; - estream_t fp = mode ? log_get_stream () : es_stdout; + estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout; while ((p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq, @@ -365,43 +364,43 @@ show_keyserver_url (PKT_signature * sig, int indent, int mode) { if (mode != 2) { - int i; const char *str; - for (i = 0; i < indent; i++) - es_putc (' ', es_stdout); + tty_fprintf (fp, "%*s", indent, ""); if (crit) str = _("Critical preferred keyserver: "); else str = _("Preferred keyserver: "); - if (mode) + if (mode > 0) log_info ("%s", str); else - es_fprintf (es_stdout, "%s", str); - print_utf8_buffer (fp, p, len); - es_fprintf (fp, "\n"); + tty_fprintf (es_stdout, "%s", str); + tty_print_utf8_string2 (fp, p, len, 0); + tty_fprintf (fp, "\n"); } - if (mode) + if (mode > 0) status_one_subpacket (SIGSUBPKT_PREF_KS, len, (crit ? 0x02 : 0) | 0x01, p); } } -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only - - Defined bits in WHICH: - 1 == standard notations - 2 == user notations -*/ + +/* Print notation data. Allowed values for MODE are: + * -1 - print to the TTY + * 0 - print to stdout. + * 1 - use log_info and emit status messages. + * 2 - emit only status messages. + * + * Defined bits in WHICH: + * 1 - standard notations + * 2 - user notations + */ void show_notation (PKT_signature * sig, int indent, int mode, int which) { - estream_t fp = mode ? log_get_stream () : es_stdout; + estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout; notation_t nd, notations; if (which == 0) @@ -418,34 +417,32 @@ show_notation (PKT_signature * sig, int indent, int mode, int which) if ((which & 1 && !has_at) || (which & 2 && has_at)) { - int i; const char *str; - for (i = 0; i < indent; i++) - es_putc (' ', es_stdout); + tty_fprintf (fp, "%*s", indent, ""); if (nd->flags.critical) str = _("Critical signature notation: "); else str = _("Signature notation: "); - if (mode) + if (mode > 0) log_info ("%s", str); else - es_fprintf (es_stdout, "%s", str); + tty_fprintf (es_stdout, "%s", str); /* This is all UTF8 */ - print_utf8_buffer (fp, nd->name, strlen (nd->name)); - es_fprintf (fp, "="); - print_utf8_buffer (fp, nd->value, strlen (nd->value)); + tty_print_utf8_string2 (fp, nd->name, strlen (nd->name), 0); + tty_fprintf (fp, "="); + tty_print_utf8_string2 (fp, nd->value, strlen (nd->value), 0); /* (We need to use log_printf so that the next call to a log function does not insert an extra LF.) */ - if (mode) + if (mode > 0) log_printf ("\n"); else - es_putc ('\n', fp); + tty_fprintf (fp, "\n"); } } - if (mode) + if (mode > 0) { write_status_buffer (STATUS_NOTATION_NAME, nd->name, strlen (nd->name), 0); diff --git a/g10/options.h b/g10/options.h index 589b68e..88a8f32 100644 --- a/g10/options.h +++ b/g10/options.h @@ -349,6 +349,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define IMPORT_NO_SECKEY (1<<7) #define IMPORT_KEEP_OWNERTTRUST (1<<8) #define IMPORT_EXPORT (1<<9) +#define IMPORT_RESTORE (1<<10) #define EXPORT_LOCAL_SIGS (1<<0) #define EXPORT_ATTRIBUTES (1<<1) @@ -358,6 +359,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define EXPORT_CLEAN (1<<5) #define EXPORT_PKA_FORMAT (1<<6) #define EXPORT_DANE_FORMAT (1<<7) +#define EXPORT_BACKUP (1<<10) #define LIST_SHOW_PHOTOS (1<<0) #define LIST_SHOW_POLICY_URLS (1<<1) diff --git a/g10/pubring.asc b/g10/pubring.asc index 09b099b..5b4e9f1 100644 --- a/g10/pubring.asc +++ b/g10/pubring.asc @@ -1,6 +1,6 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.0.0e (GNU/Linux) -Comment: For info see http://www.gnupg.org +Comment: For info see https://www.gnupg.org mQGiBDVBlNMRBADeX96LvyNiop30YPeeCBJZzeqQuQ3yQ+SK3AHoXLQ1qsGHrdoi HfHbVV2GfulRq+H/z97vUtA3APE2NZ7HuvBJzhXZCOE93wT59OZV8Pp5ir6TAEYm diff --git a/g10/sqrtu32.c b/g10/sqrtu32.c index 11513b0..1490b31 100644 --- a/g10/sqrtu32.c +++ b/g10/sqrtu32.c @@ -7,7 +7,7 @@ * to this file. * * You should have received a copy of the CC0 legalcode along with this - * work. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. + * work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>. */ /* The R code to generate the following table. */ diff --git a/g10/t-stutter.c b/g10/t-stutter.c index a2e9666..359cdf6 100644 --- a/g10/t-stutter.c +++ b/g10/t-stutter.c @@ -68,8 +68,8 @@ log_hexdump (byte *buffer, int length) { int have = length > 16 ? 16 : length; int i; - char formatted[2 * have + 1]; - char text[have + 1]; + char formatted[2 * 16 + 1]; + char text[16 + 1]; fprintf (stderr, "%-8d ", written); bin2hex (buffer, have, formatted); @@ -87,10 +87,12 @@ log_hexdump (byte *buffer, int length) } for (i = 0; i < have; i ++) - if (isprint (buffer[i])) - text[i] = buffer[i]; - else - text[i] = '.'; + { + if (isprint (buffer[i])) + text[i] = buffer[i]; + else + text[i] = '.'; + } text[i] = 0; fprintf (stderr, " "); @@ -347,8 +349,9 @@ oracle (int debug, byte *ciphertext, int len, byte **plaintextp, byte **cfbp) static int oracle_test (unsigned int d, int b, int debug) { - byte probe[blocksize + 2]; + byte probe[32 + 2]; + log_assert (blocksize + 2 <= sizeof probe); log_assert (d < 256 * 256); if (b == 1) @@ -2457,16 +2457,16 @@ get_policy (tofu_dbs_t dbs, PKT_public_key *pk, /* See if the key is signed by an ultimately trusted key. */ { int fingerprint_raw_len = strlen (fingerprint) / 2; - char fingerprint_raw[fingerprint_raw_len]; + char fingerprint_raw[20]; int len = 0; - if (fingerprint_raw_len != 20 + if (fingerprint_raw_len != sizeof fingerprint_raw || ((len = hex2bin (fingerprint, fingerprint_raw, fingerprint_raw_len)) != strlen (fingerprint))) { if (DBG_TRUST) - log_debug ("TOFU: Bad fingerprint: %s (len: %zd, parsed: %d)\n", + log_debug ("TOFU: Bad fingerprint: %s (len: %zu, parsed: %d)\n", fingerprint, strlen (fingerprint), len); } else diff --git a/g10/trust.c b/g10/trust.c index 080926a..888b4ca 100644 --- a/g10/trust.c +++ b/g10/trust.c @@ -434,7 +434,8 @@ mark_usable_uid_certs (kbnode_t keyblock, kbnode_t uidnode, node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12); if (node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY) break; /* ready */ if (node->pkt->pkttype != PKT_SIGNATURE) continue; @@ -476,7 +477,8 @@ mark_usable_uid_certs (kbnode_t keyblock, kbnode_t uidnode, u32 kid[2]; u32 sigdate; - if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY) break; if ( !(node->flag & (1<<9)) ) continue; /* not a node to look at */ @@ -491,7 +493,8 @@ mark_usable_uid_certs (kbnode_t keyblock, kbnode_t uidnode, /* Now find the latest and greatest signature */ for (n=uidnode->next; n; n = n->next) { - if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) + if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY + || n->pkt->pkttype == PKT_SECRET_SUBKEY) break; if ( !(n->flag & (1<<9)) ) continue; @@ -588,7 +591,8 @@ clean_sigs_from_uid (kbnode_t keyblock, kbnode_t uidnode, kbnode_t node; u32 keyid[2]; - log_assert (keyblock->pkt->pkttype==PKT_PUBLIC_KEY); + log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_SECRET_KEY); keyid_from_pk (keyblock->pkt->pkt.public_key, keyid); @@ -681,7 +685,8 @@ clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy) PKT_user_id *uid = uidnode->pkt->pkt.user_id; int deleted = 0; - log_assert (keyblock->pkt->pkttype==PKT_PUBLIC_KEY); + log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_SECRET_KEY); log_assert (uidnode->pkt->pkttype==PKT_USER_ID); /* Skip valid user IDs, compacted user IDs, and non-self-signed user @@ -733,7 +738,8 @@ clean_one_uid (kbnode_t keyblock, kbnode_t uidnode, int noisy, int self_only, { int dummy = 0; - log_assert (keyblock->pkt->pkttype==PKT_PUBLIC_KEY); + log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_SECRET_KEY); log_assert (uidnode->pkt->pkttype==PKT_USER_ID); if (!uids_cleaned) @@ -750,20 +756,41 @@ clean_one_uid (kbnode_t keyblock, kbnode_t uidnode, int noisy, int self_only, } +/* NB: This function marks the deleted nodes only and the caller is + * responsible to skip or remove them. */ void clean_key (kbnode_t keyblock, int noisy, int self_only, int *uids_cleaned, int *sigs_cleaned) { - kbnode_t uidnode; + kbnode_t node; merge_keys_and_selfsig (keyblock); - for (uidnode = keyblock->next; - uidnode && uidnode->pkt->pkttype != PKT_PUBLIC_SUBKEY; - uidnode = uidnode->next) + for (node = keyblock->next; + node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY); + node = node->next) { - if (uidnode->pkt->pkttype == PKT_USER_ID) - clean_one_uid (keyblock, uidnode,noisy, self_only, + if (node->pkt->pkttype == PKT_USER_ID) + clean_one_uid (keyblock, node, noisy, self_only, uids_cleaned, sigs_cleaned); } + + /* Remove bogus subkey binding signatures: The only signatures + * allowed are of class 0x18 and 0x28. */ + log_assert (!node || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY)); + for (; node; node = node->next) + { + if (is_deleted_kbnode (node)) + continue; + if (node->pkt->pkttype == PKT_SIGNATURE + && !(IS_SUBKEY_SIG (node->pkt->pkt.signature) + || IS_SUBKEY_REV (node->pkt->pkt.signature))) + { + delete_kbnode (node); + if (sigs_cleaned) + ++*sigs_cleaned; + } + } } diff --git a/g10/trustdb.c b/g10/trustdb.c index d402cb2..75714ab 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1002,9 +1002,9 @@ tdb_get_validity_core (ctrl_t ctrl, ulong recno; #ifdef USE_TOFU unsigned int tofu_validity = TRUST_UNKNOWN; + int free_kb = 0; #endif unsigned int validity = TRUST_UNKNOWN; - int free_kb = 0; if (kb && pk) log_assert (keyid_cmp (pk_main_keyid (pk), @@ -1550,14 +1550,14 @@ check_regexp(const char *expr,const char *string) { ret=regexec(&pat,string,0,NULL,0); regfree(&pat); - ret=(ret==0); } + ret=(ret==0); } #endif if(DBG_TRUST) log_debug("regexp '%s' ('%s') on '%s': %s\n", - regexp,expr,string,ret==0?"YES":"NO"); + regexp,expr,string,ret?"YES":"NO"); xfree(regexp); diff --git a/g13/g13tuple.c b/g13/g13tuple.c index f79c82d..b10ebbc 100644 --- a/g13/g13tuple.c +++ b/g13/g13tuple.c @@ -282,7 +282,7 @@ all_printable (const void *buf, size_t buflen) const unsigned char *s; for (s=buf ; buflen; s++, buflen--) - if (*s < 32 && *s > 126) + if (*s < 32 || *s > 126) return 0; return 1; } @@ -1844,6 +1844,9 @@ msgstr "la clau secreta és inusable" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2673,6 +2676,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "es descarta un bloc de tipus %d\n" @@ -1698,6 +1698,9 @@ msgstr "odstranit nepoužitelné Äásti z klÃÄe pÅ™i exportu" msgid "remove as much as possible from key during export" msgstr "odstranit pÅ™i exportu z klÃÄe vÅ¡e, co lze" +msgid "use the GnuPG key backup format" +msgstr "" + msgid " - skipped" msgstr " – pÅ™eskoÄeno" @@ -2483,6 +2486,11 @@ msgstr "odstranit po importu z klÃÄe vÅ¡e, co lze" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "pÅ™edpokládat vstup v binárnÃm formátu" + #, c-format msgid "skipping block of type %d\n" msgstr "blok typu %d byl pÅ™eskoÄen\n" @@ -1807,6 +1807,9 @@ msgstr "fjern nøgledele der ikke kan bruges under eksport" msgid "remove as much as possible from key during export" msgstr "fjern sÃ¥ meget som muligt fra nøglen under eksport" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2624,6 +2627,11 @@ msgstr "fjern sÃ¥ meget som muligt fra nøgle efter import" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "antag inddata er i binært format" + #, c-format msgid "skipping block of type %d\n" msgstr " udelader bloktype %d\n" @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2016-12-20 11:14+0100\n" +"PO-Revision-Date: 2017-01-23 19:23+0100\n" "Last-Translator: Werner Koch <wk@gnupg.org>\n" "Language-Team: German <de@li.org>\n" "Language: de\n" @@ -1694,6 +1694,9 @@ msgstr "Unbrauchbare Teile des Schlüssel während des Exports entfernen" msgid "remove as much as possible from key during export" msgstr "Während des Exports soviel wie möglich vom Schlüssel entfernen" +msgid "use the GnuPG key backup format" +msgstr "Das GnuPG Datensicherungsformat für Schlüssel benutzen" + msgid " - skipped" msgstr " - übersprungen" @@ -2451,6 +2454,9 @@ msgstr "nach dem Import soviel wie möglich aus dem Schlüssel entfernen" msgid "run import filters and export key immediately" msgstr "Import-Filter anwenden und Schlüssel direkt exportieren" +msgid "assume the GnuPG key backup format" +msgstr "Eingabedaten sind im GnuPG Datensicherungsformat für Schlüssel" + #, c-format msgid "skipping block of type %d\n" msgstr "überspringe den Block vom Typ %d\n" @@ -3423,7 +3429,7 @@ msgstr "verfällt: %s" #, c-format msgid "usage: %s" -msgstr "Aufruf: %s" +msgstr "Nutzung: %s" msgid "card-no: " msgstr "Kartennummer:" @@ -3760,7 +3766,7 @@ msgstr "Authentisierung" #. q = Finish #. msgid "SsEeAaQq" -msgstr "UuVvAaQq" +msgstr "SsVvAaQq" #, c-format msgid "Possible actions for a %s key: " @@ -3771,15 +3777,15 @@ msgstr "Derzeit erlaubte Vorgänge: " #, c-format msgid " (%c) Toggle the sign capability\n" -msgstr " (%c) Umschalten der Signaturfähigkeit\n" +msgstr " (%c) Umschalten der Signaturnutzbarkeit\n" #, c-format msgid " (%c) Toggle the encrypt capability\n" -msgstr " (%c) Umschalten der Verschlüsselungsfähigkeit\n" +msgstr " (%c) Umschalten der Verschlüsselungsnutzbarkeit\n" #, c-format msgid " (%c) Toggle the authenticate capability\n" -msgstr " (%c) Umschalten der Authentisierungsfähigkeit\n" +msgstr " (%c) Umschalten der Authentisierungsnutzbarkeit\n" #, c-format msgid " (%c) Finished\n" @@ -3814,11 +3820,11 @@ msgstr " (%d) RSA (nur verschlüsseln)\n" #, c-format msgid " (%d) DSA (set your own capabilities)\n" -msgstr " (%d) DSA (Leistungsfähigkeit selber einstellbar)\n" +msgstr " (%d) DSA (Nutzung selber einstellbar)\n" #, c-format msgid " (%d) RSA (set your own capabilities)\n" -msgstr " (%d) RSA (Leistungsfähigkeit selber einstellbar)\n" +msgstr " (%d) RSA (Nutzung selber einstellbar)\n" #, c-format msgid " (%d) ECC and ECC\n" @@ -3830,7 +3836,7 @@ msgstr " (%d) ECC (nur signieren)\n" #, c-format msgid " (%d) ECC (set your own capabilities)\n" -msgstr " (%d) ECC (Leistungsfähigkeit selber einstellbar)\n" +msgstr " (%d) ECC (Nutzung selber einstellbar)\n" #, c-format msgid " (%d) ECC (encrypt only)\n" @@ -1777,6 +1777,9 @@ msgstr "μη χÏησιμοποιήσιμο μυστικό κλειδί" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2594,6 +2597,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "παÏάλειψη τμήματος του Ï„Ïπου %d\n" @@ -1765,6 +1765,9 @@ msgstr "neuzebla sekreta Ålosilo" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2578,6 +2581,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "ignoras blokon de speco %d\n" @@ -1826,6 +1826,9 @@ msgstr "borrar partes inutilizables de la clave al exportar" msgid "remove as much as possible from key during export" msgstr "borrar tanto como sea posible de la clave al exportar" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2653,6 +2656,11 @@ msgstr "borrar tanto como sea posible de la clave tras importar" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "asumir entrada en formato binario" + #, c-format msgid "skipping block of type %d\n" msgstr "omitiendo bloque de tipo %d\n" @@ -1770,6 +1770,9 @@ msgstr "mittekasutatav salajane võti" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2579,6 +2582,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "jätan bloki tüübiga %d vahele\n" @@ -1785,6 +1785,9 @@ msgstr "salaista avainta ei voi käyttää" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2595,6 +2598,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "ohitetaan tyypin %d lohko\n" @@ -1726,6 +1726,9 @@ msgstr "supprimer les parties inutilisables de la clef pendant l'exportation" msgid "remove as much as possible from key during export" msgstr "supprimer autant que possible de la clef pendant l'exportation" +msgid "use the GnuPG key backup format" +msgstr "" + msgid " - skipped" msgstr " — ignoré" @@ -2524,6 +2527,11 @@ msgstr "supprimer autant que possible de la clef après l'importation" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "entrée supposée au format binaire" + #, c-format msgid "skipping block of type %d\n" msgstr "un bloc de type %d a été ignoré\n" @@ -1779,6 +1779,9 @@ msgstr "chave secreta non utilizable" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2589,6 +2592,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "pasando por alto un bloque de tipo %d\n" @@ -1766,6 +1766,9 @@ msgstr "használhatatlan titkos kulcs" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2577,6 +2580,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "%d tÃpusú blokkot kihagyom.\n" @@ -1771,6 +1771,9 @@ msgstr "kunci rahasia tidak dapat dipakai" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2582,6 +2585,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "melewati blok tipe %d\n" @@ -1778,6 +1778,9 @@ msgstr "chiave segreta inutilizzabile" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2588,6 +2591,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "salto un blocco di tipo %d\n" @@ -1639,6 +1639,9 @@ msgstr "エクスãƒãƒ¼ãƒˆã®éš›ã€åˆ©ç”¨ã§ããªã„部分を除去ã™ã‚‹" msgid "remove as much as possible from key during export" msgstr "エクスãƒãƒ¼ãƒˆã®éš›ã€ã§ãã‚‹ã ã‘除去ã™ã‚‹" +msgid "use the GnuPG key backup format" +msgstr "" + msgid " - skipped" msgstr " - スã‚ップã•ã‚Œã¾ã—ãŸ" @@ -2370,6 +2373,11 @@ msgstr "インãƒãƒ¼ãƒˆå¾Œã€ã§ãã‚‹ã ã‘除去ã—ã¾ã™" msgid "run import filters and export key immediately" msgstr "インãƒãƒ¼ãƒˆãƒ»ãƒ•ã‚£ãƒ«ã‚¿ã‚’実行ã—éµã‚’ã™ãã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ã¾ã™" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "ãƒã‚¤ãƒŠãƒªãƒ»ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã®å…¥åŠ›ã‚’仮定ã™ã‚‹" + #, c-format msgid "skipping block of type %d\n" msgstr "åž‹%dã®ãƒ–ãƒãƒƒã‚¯ã‚’スã‚ップã—ã¾ã™\n" @@ -1653,6 +1653,9 @@ msgstr "fjern ubrukelige deler fra nøkkelen under eksportering" msgid "remove as much as possible from key during export" msgstr "fjern sÃ¥ mye som mulig fra nøkkelen under eksportering" +msgid "use the GnuPG key backup format" +msgstr "" + msgid " - skipped" msgstr ". Hoppet over" @@ -2400,6 +2403,11 @@ msgstr "fjern sÃ¥ mye som mulig fra nøkkel etter importering" msgid "run import filters and export key immediately" msgstr "kjør importeringsfiltre og eksporter nøkkel umiddelbart" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "forvent inndata i binærformat" + #, c-format msgid "skipping block of type %d\n" msgstr "hopper over blokk av typen %d\n" @@ -1791,6 +1791,9 @@ msgstr "usuniÄ™cie bezużytecznych części z klucza przy eksporcie" msgid "remove as much as possible from key during export" msgstr "usuniÄ™cie jak najwiÄ™kszej części klucza przy eksporcie" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2631,6 +2634,11 @@ msgstr "usuwanie jak najwiÄ™kszej części kluczy po imporcie" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "przyjÄ™cie wejÅ›cia w formacie binarnym" + #, c-format msgid "skipping block of type %d\n" msgstr "blok typu %d zostaje pominiÄ™ty\n" @@ -1770,6 +1770,9 @@ msgstr "chave secreta não utilizável" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2583,6 +2586,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "ignorando bloco do tipo %d\n" @@ -1774,6 +1774,9 @@ msgstr "cheie secretă de nefolosit" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2615,6 +2618,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "bloc de tip %d sărit\n" @@ -1655,6 +1655,9 @@ msgstr "удалить при ÑкÑпорте непригодные чаÑти msgid "remove as much as possible from key during export" msgstr "при ÑкÑпорте удалить из ключа как можно больше" +msgid "use the GnuPG key backup format" +msgstr "" + msgid " - skipped" msgstr " - пропущено" @@ -2415,6 +2418,11 @@ msgstr "удалить поÑле импорта из ключа как можн msgid "run import filters and export key immediately" msgstr "применить фильтры импорта и немедленно ÑкÑпортировать ключ" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "предполагаю, что входные данные в двоичном формате" + #, c-format msgid "skipping block of type %d\n" msgstr "пропущен блок типа %d\n" @@ -1774,6 +1774,9 @@ msgstr "nepoužiteľný tajný kľúÄ" msgid "remove as much as possible from key during export" msgstr "" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2595,6 +2598,9 @@ msgstr "" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "blok typu %d bol preskoÄený\n" @@ -1839,6 +1839,9 @@ msgstr "ta bort oanvändbara delar frÃ¥n nyckeln under exportering" msgid "remove as much as possible from key during export" msgstr "ta bort sÃ¥ mycket som möjligt frÃ¥n nyckeln under exportering" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2683,6 +2686,11 @@ msgstr "ta bort sÃ¥ mycket som möjligt frÃ¥n nyckeln efter importering" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "anta att inmatning är i binärformat" + #, c-format msgid "skipping block of type %d\n" msgstr "hoppar över block av typen %d\n" @@ -1785,6 +1785,9 @@ msgstr "ihraç sırasında anahtardan kullanışsız parçalar kaldırılır" msgid "remove as much as possible from key during export" msgstr "ihraç sırasında anahtardan mümkün olduÄŸunca çok ÅŸey kaldırılır" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2612,6 +2615,11 @@ msgstr "ithalat sonrası anahtardan mümkün olduÄŸunca çok ÅŸey kaldırır" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "girdinin ikilik biçimde olduÄŸu kabul edilir" + #, c-format msgid "skipping block of type %d\n" msgstr "%d türündeki blok atlanıyor\n" @@ -1673,6 +1673,9 @@ msgstr "вилучити невикориÑтовувані чаÑтини ÐºÐ»Ñ msgid "remove as much as possible from key during export" msgstr "вилучити макÑимум чаÑтин з ключа під Ñ‡Ð°Ñ ÐµÐºÑпортуваннÑ" +msgid "use the GnuPG key backup format" +msgstr "" + msgid " - skipped" msgstr " - пропущено" @@ -2459,6 +2462,11 @@ msgstr "вилучити макÑимум чаÑтин з ключа піÑÐ»Ñ msgid "run import filters and export key immediately" msgstr "запуÑтити фільтри Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° екÑпортувати ключ негайно" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "вважати вхідні дані даними у двійковому форматі" + #, c-format msgid "skipping block of type %d\n" msgstr "пропуÑкаємо блок типу %d\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index 1417627..4566cbf 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -1743,6 +1743,9 @@ msgstr "导出时清除密钥ä¸çš„ä¸å¯ç”¨éƒ¨åˆ†" msgid "remove as much as possible from key during export" msgstr "导出时尽å¯èƒ½æ¸…除密钥ä¸çš„å¯é€‰éƒ¨åˆ†" +msgid "use the GnuPG key backup format" +msgstr "" + #, fuzzy #| msgid "%s: skipped: %s\n" msgid " - skipped" @@ -2559,6 +2562,9 @@ msgstr "导入åŽå°½å¯èƒ½æ¸…除密钥ä¸çš„å¯é€‰éƒ¨åˆ†" msgid "run import filters and export key immediately" msgstr "" +msgid "assume the GnuPG key backup format" +msgstr "" + #, c-format msgid "skipping block of type %d\n" msgstr "跳过 %d æ ·å¼çš„区å—\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index 0151cec..a3df85e 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -1655,6 +1655,9 @@ msgstr "匯出時從金鑰ä¸ç§»é™¤ç„¡æ³•ä½¿ç”¨çš„部分" msgid "remove as much as possible from key during export" msgstr "匯出時盡å¯èƒ½åœ°å¾žé‡‘é‘°ä¸ç§»é™¤" +msgid "use the GnuPG key backup format" +msgstr "" + msgid " - skipped" msgstr " - 已跳éŽ" @@ -2416,6 +2419,11 @@ msgstr "匯入後盡å¯èƒ½åœ°å¾žé‡‘é‘°ä¸ç§»é™¤" msgid "run import filters and export key immediately" msgstr "" +#, fuzzy +#| msgid "assume input is in binary format" +msgid "assume the GnuPG key backup format" +msgstr "å‡è¨è¼¸å…¥çš„æ˜¯äºŒé€²åˆ¶æ ¼å¼" + #, c-format msgid "skipping block of type %d\n" msgstr "æ£åœ¨è·³éŽ %d åž‹æ…‹çš„å€å¡Š\n" @@ -66,6 +66,13 @@ #define CCID_DRIVER_INCLUDE_USB_IDS 1 #include "ccid-driver.h" +struct dev_list { + struct ccid_dev_table *ccid_table; + const char *portstr; + int idx; + int idx_max; +}; + /* Due to conflicting use of threading libraries we usually can't link against libpcsclite if we are using Pth. Instead we use a wrapper program. Note that with nPth there is no need for a wrapper. */ @@ -134,9 +141,6 @@ struct reader_table_s { } rapdu; #endif /*USE_G10CODE_RAPDU*/ char *rdrname; /* Name of the connected reader or NULL if unknown. */ - int any_status; /* True if we have seen any status. */ - int last_status; - int status; int is_t0; /* True if we know that we are running T=0. */ int is_spr532; /* True if we know that the reader is a SPR532. */ int pinpad_varlen_supported; /* True if we know that the reader @@ -146,9 +150,7 @@ struct reader_table_s { size_t atrlen; /* A zero length indicates that the ATR has not yet been read; i.e. the card is not ready for use. */ - unsigned int change_counter; #ifdef USE_NPTH - int lock_initialized; npth_mutex_t lock; #endif }; @@ -157,6 +159,10 @@ typedef struct reader_table_s *reader_table_t; /* A global table to keep track of active readers. */ static struct reader_table_s reader_table[MAX_READER]; +#ifdef USE_NPTH +static npth_mutex_t reader_table_lock; +#endif + /* ct API function pointer. */ static char (* DLSTDCALL CT_init) (unsigned short ctn, unsigned short Pn); @@ -217,7 +223,7 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn); #define PCSC_STATE_ATRMATCH 0x0040 /* ATR matches card. */ #define PCSC_STATE_EXCLUSIVE 0x0080 /* Exclusive Mode. */ #define PCSC_STATE_INUSE 0x0100 /* Shared mode. */ -#define PCSC_STATE_MUTE 0x0200 /* Unresponsive card. */ +#define PCSC_STATE_MUTE 0x0200 /* Unresponsive card. */ #ifdef HAVE_W32_SYSTEM # define PCSC_STATE_UNPOWERED 0x0400 /* Card not powerred up. */ #endif @@ -251,7 +257,7 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn); #ifdef _WIN32 #include <winioctl.h> #define SCARD_CTL_CODE(code) CTL_CODE(FILE_DEVICE_SMARTCARD, (code), \ - METHOD_BUFFERED, FILE_ANY_ACCESS) + METHOD_BUFFERED, FILE_ANY_ACCESS) #else #define SCARD_CTL_CODE(code) (0x42000000 + (code)) #endif @@ -361,8 +367,7 @@ static int pcsc_vendor_specific_init (int slot); static int pcsc_get_status (int slot, unsigned int *status); static int reset_pcsc_reader (int slot); static int apdu_get_status_internal (int slot, int hang, int no_atr_reset, - unsigned int *status, - unsigned int *changed); + unsigned int *status); static int check_pcsc_pinpad (int slot, int command, pininfo_t *pininfo); static int pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1, pininfo_t *pininfo); @@ -429,35 +434,27 @@ static int new_reader_slot (void) { int i, reader = -1; - int err; for (i=0; i < MAX_READER; i++) - { - if (!reader_table[i].used && reader == -1) + if (!reader_table[i].used) + { reader = i; - } + reader_table[reader].used = 1; + break; + } + if (reader == -1) { log_error ("new_reader_slot: out of slots\n"); return -1; } -#ifdef USE_NPTH - if (!reader_table[reader].lock_initialized) - { - err = npth_mutex_init (&reader_table[reader].lock, NULL); - if (err) - { - log_error ("error initializing mutex: %s\n", strerror (err)); - return -1; - } - reader_table[reader].lock_initialized = 1; - } -#endif /*USE_NPTH*/ + if (lock_slot (reader)) { - log_error ("error locking mutex: %s\n", strerror (errno)); + reader_table[reader].used = 0; return -1; } + reader_table[reader].connect_card = NULL; reader_table[reader].disconnect_card = NULL; reader_table[reader].close_reader = NULL; @@ -470,9 +467,6 @@ new_reader_slot (void) reader_table[reader].pinpad_verify = pcsc_pinpad_verify; reader_table[reader].pinpad_modify = pcsc_pinpad_modify; - reader_table[reader].used = 1; - reader_table[reader].any_status = 0; - reader_table[reader].last_status = 0; reader_table[reader].is_t0 = 1; reader_table[reader].is_spr532 = 0; reader_table[reader].pinpad_varlen_supported = 0; @@ -499,8 +493,7 @@ dump_reader_status (int slot) if (reader_table[slot].dump_status_reader) reader_table[slot].dump_status_reader (slot); - if (reader_table[slot].status != -1 - && reader_table[slot].atrlen) + if (reader_table[slot].atrlen) { log_info ("slot %d: ATR=", slot); log_printhex ("", reader_table[slot].atr, reader_table[slot].atrlen); @@ -590,16 +583,6 @@ ct_error_string (long err) } -static void -ct_dump_reader_status (int slot) -{ - log_info ("reader slot %d: %s\n", slot, - reader_table[slot].status == 1? "Processor ICC present" : - reader_table[slot].status == 0? "Memory ICC present" : - "ICC not present" ); -} - - /* Wait for the card in SLOT and activate it. Return a status word error or 0 on success. */ static int @@ -658,7 +641,6 @@ ct_activate_card (int slot) return SW_HOST_CARD_IO_ERROR; } - reader_table[slot].status = buf[buflen - 1]; memcpy (reader_table[slot].atr, buf, buflen - 2); reader_table[slot].atrlen = buflen - 2; return 0; @@ -669,7 +651,6 @@ static int close_ct_reader (int slot) { CT_close (slot); - reader_table[slot].used = 0; return 0; } @@ -763,7 +744,7 @@ open_ct_reader (int port) reader_table[reader].get_status_reader = ct_get_status; reader_table[reader].send_apdu_reader = ct_send_apdu; reader_table[reader].check_pinpad = NULL; - reader_table[reader].dump_status_reader = ct_dump_reader_status; + reader_table[reader].dump_status_reader = NULL; reader_table[reader].pinpad_verify = NULL; reader_table[reader].pinpad_modify = NULL; @@ -984,7 +965,7 @@ pcsc_get_status_direct (int slot, unsigned int *status) { *status |= APDU_CARD_PRESENT; if ( !(rdrstates[0].event_state & PCSC_STATE_MUTE) ) - *status |= APDU_CARD_ACTIVE; + *status |= APDU_CARD_ACTIVE; } #ifndef HAVE_W32_SYSTEM /* We indicate a useful card if it is not in use by another @@ -1452,9 +1433,6 @@ static int close_pcsc_reader_direct (int slot) { pcsc_release_context (reader_table[slot].pcsc.context); - xfree (reader_table[slot].rdrname); - reader_table[slot].rdrname = NULL; - reader_table[slot].used = 0; return 0; } #endif /*!NEED_PCSC_WRAPPER*/ @@ -1553,7 +1531,6 @@ connect_pcsc_card (int slot) return SW_HOST_ALREADY_CONNECTED; reader_table[slot].atrlen = 0; - reader_table[slot].last_status = 0; reader_table[slot].is_t0 = 0; err = pcsc_connect (reader_table[slot].pcsc.context, @@ -1591,11 +1568,6 @@ connect_pcsc_card (int slot) if (atrlen > DIM (reader_table[0].atr)) log_bug ("ATR returned by pcsc_status is too large\n"); reader_table[slot].atrlen = atrlen; - /* If we got to here we know that a card is present - and usable. Remember this. */ - reader_table[slot].last_status = ( APDU_CARD_USABLE - | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE); reader_table[slot].is_t0 = !!(card_protocol & PCSC_PROTOCOL_T0); } } @@ -1955,7 +1927,7 @@ open_pcsc_reader_direct (const char *portstr) log_error ("error allocating memory for reader list\n"); pcsc_release_context (reader_table[slot].pcsc.context); reader_table[slot].used = 0; - unlock_slot (slot); + unlock_slot (slot); return -1 /*SW_HOST_OUT_OF_CORE*/; } err = pcsc_list_readers (reader_table[slot].pcsc.context, @@ -2006,7 +1978,6 @@ open_pcsc_reader_direct (const char *portstr) reader_table[slot].pcsc.card = 0; reader_table[slot].atrlen = 0; - reader_table[slot].last_status = 0; reader_table[slot].connect_card = connect_pcsc_card; reader_table[slot].disconnect_card = disconnect_pcsc_card; @@ -2188,8 +2159,6 @@ open_pcsc_reader_wrapped (const char *portstr) goto command_failed; } - slotp->last_status = 0; - /* The open request may return a zero for the ATR length to indicate that no card is present. */ n = len; @@ -2201,11 +2170,6 @@ open_pcsc_reader_wrapped (const char *portstr) i? strerror (errno) : "premature EOF"); goto command_failed; } - /* If we got to here we know that a card is present - and usable. Thus remember this. */ - slotp->last_status = ( APDU_CARD_USABLE - | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE); } slotp->atrlen = len; @@ -2353,7 +2317,7 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1, if (DBG_CARD_IO) log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", - class, ins, p0, p1, len, pininfo->maxlen); + class, ins, p0, p1, len, pininfo->maxlen); sw = control_pcsc (slot, reader_table[slot].pcsc.verify_ioctl, pin_verify, len, result, &resultlen); @@ -2439,7 +2403,7 @@ pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1, if (DBG_CARD_IO) log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", - class, ins, p0, p1, len, (int)pininfo->maxlen); + class, ins, p0, p1, len, (int)pininfo->maxlen); sw = control_pcsc (slot, reader_table[slot].pcsc.modify_ioctl, pin_modify, len, result, &resultlen); @@ -2471,8 +2435,6 @@ static int close_ccid_reader (int slot) { ccid_close_reader (reader_table[slot].ccid.handle); - reader_table[slot].rdrname = NULL; - reader_table[slot].used = 0; return 0; } @@ -2573,13 +2535,13 @@ check_ccid_pinpad (int slot, int command, pininfo_t *pininfo) apdu[1] = command; return ccid_transceive_secure (reader_table[slot].ccid.handle, apdu, - sizeof apdu, pininfo, NULL, 0, NULL); + sizeof apdu, pininfo, NULL, 0, NULL); } static int ccid_pinpad_operation (int slot, int class, int ins, int p0, int p1, - pininfo_t *pininfo) + pininfo_t *pininfo) { unsigned char apdu[4]; int err, sw; @@ -2606,7 +2568,7 @@ ccid_pinpad_operation (int slot, int class, int ins, int p0, int p1, /* Open the reader and try to read an ATR. */ static int -open_ccid_reader (const char *portstr) +open_ccid_reader (struct dev_list *dl) { int err; int slot; @@ -2617,8 +2579,8 @@ open_ccid_reader (const char *portstr) return -1; slotp = reader_table + slot; - err = ccid_open_reader (&slotp->ccid.handle, portstr, - (const char **)&slotp->rdrname); + err = ccid_open_reader (dl->portstr, dl->idx, dl->ccid_table, + &slotp->ccid.handle, &slotp->rdrname); if (err) { slotp->used = 0; @@ -2633,14 +2595,6 @@ open_ccid_reader (const char *portstr) slotp->atrlen = 0; err = 0; } - else - { - /* If we got to here we know that a card is present - and usable. Thus remember this. */ - reader_table[slot].last_status = (APDU_CARD_USABLE - | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE); - } reader_table[slot].close_reader = close_ccid_reader; reader_table[slot].reset_reader = reset_ccid_reader; @@ -2659,12 +2613,7 @@ open_ccid_reader (const char *portstr) unlock_slot (slot); return slot; } - - - #endif /* HAVE_LIBUSB */ - - #ifdef USE_G10CODE_RAPDU /* @@ -2711,7 +2660,6 @@ static int close_rapdu_reader (int slot) { rapdu_release (reader_table[slot].rapdu.handle); - reader_table[slot].used = 0; return 0; } @@ -2968,63 +2916,84 @@ open_rapdu_reader (int portno, /* Driver Access */ +gpg_error_t +apdu_dev_list_start (const char *portstr, struct dev_list **l_p) +{ + struct dev_list *dl = xtrymalloc (sizeof (struct dev_list)); + *l_p = NULL; + if (!dl) + return gpg_error_from_syserror (); -/* Open the reader and return an internal slot number or -1 on - error. If PORTSTR is NULL we default to a suitable port (for ctAPI: - the first USB reader. For PC/SC the first listed reader). */ -int -apdu_open_reader (const char *portstr) -{ - static int pcsc_api_loaded, ct_api_loaded; - int slot; + dl->portstr = portstr; + dl->idx = 0; - if (DBG_READER) - log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr); + npth_mutex_lock (&reader_table_lock); #ifdef HAVE_LIBUSB - if (!opt.disable_ccid) + if (opt.disable_ccid) + { + dl->ccid_table = NULL; + dl->idx_max = 1; + } + else { - static int once_available; - int i; - const char *s; + gpg_error_t err; - slot = open_ccid_reader (portstr); - if (slot != -1) - { - once_available = 1; - if (DBG_READER) - log_debug ("leave: apdu_open_reader => slot=%d [ccid]\n", slot); - return slot; /* got one */ - } + err = ccid_dev_scan (&dl->idx_max, &dl->ccid_table); + if (err) + return err; - /* If we ever loaded successfully loaded a CCID reader we never - want to fallback to another driver. This solves a problem - where ccid was used, the card unplugged and then scdaemon - tries to find a new reader and will eventually try PC/SC over - and over again. To reset this flag "gpgconf --kill scdaemon" - can be used. */ - if (once_available) + if (dl->idx_max == 0) { - if (DBG_READER) - log_debug ("leave: apdu_open_reader => slot=-1 (once_avail)\n"); - return -1; - } - - /* If a CCID reader specification has been given, the user does - not want a fallback to other drivers. */ - if (portstr) - for (s=portstr, i=0; *s; s++) - if (*s == ':' && (++i == 3)) + /* If a CCID reader specification has been given, the user does + not want a fallback to other drivers. */ + if (portstr && strlen (portstr) > 5 && portstr[4] == ':') { if (DBG_READER) log_debug ("leave: apdu_open_reader => slot=-1 (no ccid)\n"); - return -1; + + xfree (dl); + npth_mutex_unlock (&reader_table_lock); + return gpg_error (GPG_ERR_ENODEV); } + else + dl->idx_max = 1; + } } - +#else + dl->ccid_table = NULL; + dl->idx_max = 1; #endif /* HAVE_LIBUSB */ + *l_p = dl; + return 0; +} + +void +apdu_dev_list_finish (struct dev_list *dl) +{ +#ifdef HAVE_LIBUSB + if (dl->ccid_table) + ccid_dev_scan_finish (dl->ccid_table, dl->idx_max); +#endif + xfree (dl); + npth_mutex_unlock (&reader_table_lock); +} + + +/* Open the reader and return an internal slot number or -1 on + error. If PORTSTR is NULL we default to a suitable port (for ctAPI: + the first USB reader. For PC/SC the first listed reader). */ +static int +apdu_open_one_reader (const char *portstr) +{ + static int pcsc_api_loaded, ct_api_loaded; + int slot; + + if (DBG_READER) + log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr); + if (opt.ctapi_driver && *opt.ctapi_driver) { int port = portstr? atoi (portstr) : 32768; @@ -3054,7 +3023,6 @@ apdu_open_reader (const char *portstr) return open_ct_reader (port); } - /* No ctAPI configured, so lets try the PC/SC API */ if (!pcsc_api_loaded) { @@ -3148,6 +3116,98 @@ apdu_open_reader (const char *portstr) return slot; } +int +apdu_open_reader (struct dev_list *dl) +{ + int slot; + +#ifdef HAVE_LIBUSB + if (dl->ccid_table) + { /* CCID readers. */ + int readerno; + + /* See whether we want to use the reader ID string or a reader + number. A readerno of -1 indicates that the reader ID string is + to be used. */ + if (dl->portstr && strchr (dl->portstr, ':')) + readerno = -1; /* We want to use the readerid. */ + else if (dl->portstr) + { + readerno = atoi (dl->portstr); + if (readerno < 0) + { + return -1; + } + } + else + readerno = 0; /* Default. */ + + if (readerno > 0) + { /* Use single, the specific reader. */ + if (readerno >= dl->idx_max) + return -1; + + dl->idx = readerno; + dl->portstr = NULL; + slot = open_ccid_reader (dl); + dl->idx = dl->idx_max; + if (slot >= 0) + return slot; + else + return -1; + } + + while (dl->idx < dl->idx_max) + { + unsigned int bai = ccid_get_BAI (dl->idx, dl->ccid_table); + + if (DBG_READER) + log_debug ("apdu_open_reader: BAI=%x\n", bai); + + /* Check identity by BAI against already opened HANDLEs. */ + for (slot = 0; slot < MAX_READER; slot++) + if (reader_table[slot].used + && ccid_compare_BAI (reader_table[slot].ccid.handle, bai)) + break; + + if (slot == MAX_READER) + { /* Found a new device. */ + if (DBG_READER) + log_debug ("apdu_open_reader: new device=%x\n", bai); + + slot = open_ccid_reader (dl); + + dl->idx++; + if (slot >= 0) + return slot; + else + { + /* Skip this reader. */ + log_error ("ccid open error: skip\n"); + continue; + } + } + else + dl->idx++; + } + + slot = -1; + } + else +#endif + { /* PC/SC readers. */ + if (dl->idx == 0) + { + dl->idx++; + slot = apdu_open_one_reader (dl->portstr); + } + else + slot = -1; + } + + return slot; +} + /* Open an remote reader and return an internal slot number or -1 on error. This function is an alternative to apdu_open_reader and used @@ -3221,10 +3281,14 @@ apdu_close_reader (int slot) if (reader_table[slot].close_reader) { sw = reader_table[slot].close_reader (slot); + reader_table[slot].used = 0; if (DBG_READER) log_debug ("leave: apdu_close_reader => 0x%x (close_reader)\n", sw); return sw; } + xfree (reader_table[slot].rdrname); + reader_table[slot].rdrname = NULL; + reader_table[slot].used = 0; if (DBG_READER) log_debug ("leave: apdu_close_reader => SW_HOST_NOT_SUPPORTED\n"); return SW_HOST_NOT_SUPPORTED; @@ -3244,14 +3308,18 @@ apdu_prepare_exit (void) if (!sentinel) { sentinel = 1; + npth_mutex_lock (&reader_table_lock); for (slot = 0; slot < MAX_READER; slot++) if (reader_table[slot].used) { apdu_disconnect (slot); if (reader_table[slot].close_reader) reader_table[slot].close_reader (slot); + xfree (reader_table[slot].rdrname); + reader_table[slot].rdrname = NULL; reader_table[slot].used = 0; } + npth_mutex_unlock (&reader_table_lock); sentinel = 0; } } @@ -3309,7 +3377,7 @@ apdu_connect (int slot) Without that we would force a reset of the card with the next call to apdu_get_status. */ if (!sw) - sw = apdu_get_status_internal (slot, 1, 1, &status, NULL); + sw = apdu_get_status_internal (slot, 1, 1, &status); if (sw) ; @@ -3406,19 +3474,9 @@ apdu_reset (int slot) return sw; } - reader_table[slot].last_status = 0; if (reader_table[slot].reset_reader) sw = reader_table[slot].reset_reader (slot); - if (!sw) - { - /* If we got to here we know that a card is present - and usable. Thus remember this. */ - reader_table[slot].last_status = (APDU_CARD_USABLE - | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE); - } - unlock_slot (slot); if (DBG_READER) log_debug ("leave: apdu_reset => sw=0x%x\n", sw); @@ -3476,14 +3534,10 @@ apdu_get_atr (int slot, size_t *atrlen) (bit 3) = card access locked [not yet implemented] For must applications, testing bit 0 is sufficient. - - CHANGED will receive the value of the counter tracking the number - of card insertions. This value may be used to detect a card - change. */ static int apdu_get_status_internal (int slot, int hang, int no_atr_reset, - unsigned int *status, unsigned int *changed) + unsigned int *status) { int sw; unsigned int s; @@ -3501,52 +3555,31 @@ apdu_get_status_internal (int slot, int hang, int no_atr_reset, if (sw) { - reader_table[slot].last_status = 0; - return sw; - } - - /* Keep track of changes. */ - if (s != reader_table[slot].last_status - || !reader_table[slot].any_status ) - { - reader_table[slot].change_counter++; - /* Make sure that the ATR is invalid so that a reset will be - triggered by apdu_activate. */ if (!no_atr_reset) reader_table[slot].atrlen = 0; + s = 0; } - reader_table[slot].any_status = 1; - reader_table[slot].last_status = s; if (status) *status = s; - if (changed) - *changed = reader_table[slot].change_counter; - return 0; + return sw; } /* See above for a description. */ int -apdu_get_status (int slot, int hang, - unsigned int *status, unsigned int *changed) +apdu_get_status (int slot, int hang, unsigned int *status) { int sw; if (DBG_READER) log_debug ("enter: apdu_get_status: slot=%d hang=%d\n", slot, hang); - sw = apdu_get_status_internal (slot, hang, 0, status, changed); + sw = apdu_get_status_internal (slot, hang, 0, status); if (DBG_READER) { - if (status && changed) - log_debug ("leave: apdu_get_status => sw=0x%x status=%u changecnt=%u\n", - sw, *status, *changed); - else if (status) + if (status) log_debug ("leave: apdu_get_status => sw=0x%x status=%u\n", sw, *status); - else if (changed) - log_debug ("leave: apdu_get_status => sw=0x%x changed=%u\n", - sw, *changed); else log_debug ("leave: apdu_get_status => sw=0x%x\n", sw); } @@ -3584,7 +3617,7 @@ apdu_check_pinpad (int slot, int command, pininfo_t *pininfo) int apdu_pinpad_verify (int slot, int class, int ins, int p0, int p1, - pininfo_t *pininfo) + pininfo_t *pininfo) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -3597,7 +3630,7 @@ apdu_pinpad_verify (int slot, int class, int ins, int p0, int p1, return sw; sw = reader_table[slot].pinpad_verify (slot, class, ins, p0, p1, - pininfo); + pininfo); unlock_slot (slot); return sw; } @@ -3608,7 +3641,7 @@ apdu_pinpad_verify (int slot, int class, int ins, int p0, int p1, int apdu_pinpad_modify (int slot, int class, int ins, int p0, int p1, - pininfo_t *pininfo) + pininfo_t *pininfo) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -4298,3 +4331,28 @@ apdu_get_reader_name (int slot) { return reader_table[slot].rdrname; } + +gpg_error_t +apdu_init (void) +{ +#ifdef USE_NPTH + gpg_error_t err; + int i; + + if (npth_mutex_init (&reader_table_lock, NULL)) + goto leave; + + for (i = 0; i < MAX_READER; i++) + if (npth_mutex_init (&reader_table[i].lock, NULL)) + goto leave; + + /* All done well. */ + return 0; + + leave: + err = gpg_error_from_syserror (); + log_error ("apdu: error initializing mutex: %s\n", gpg_strerror (err)); + return err; +#endif /*USE_NPTH*/ + return 0; +} @@ -74,6 +74,7 @@ enum { SW_HOST_ALREADY_CONNECTED = 0x1000f }; +struct dev_list; #define SW_EXACT_LENGTH_P(a) (((a)&~0xff) == SW_EXACT_LENGTH) @@ -84,8 +85,13 @@ enum { #define APDU_CARD_ACTIVE (4) /* Card is active. */ +gpg_error_t apdu_init (void); + +gpg_error_t apdu_dev_list_start (const char *portstr, struct dev_list **l_p); +void apdu_dev_list_finish (struct dev_list *l); + /* Note, that apdu_open_reader returns no status word but -1 on error. */ -int apdu_open_reader (const char *portstr); +int apdu_open_reader (struct dev_list *l); int apdu_open_remote_reader (const char *portstr, const unsigned char *cookie, size_t length, int (*readfnc) (void *opaque, @@ -112,13 +118,12 @@ int apdu_disconnect (int slot); int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg); int apdu_reset (int slot); -int apdu_get_status (int slot, int hang, - unsigned int *status, unsigned int *changed); +int apdu_get_status (int slot, int hang, unsigned int *status); int apdu_check_pinpad (int slot, int command, pininfo_t *pininfo); int apdu_pinpad_verify (int slot, int class, int ins, int p0, int p1, - pininfo_t *pininfo); + pininfo_t *pininfo); int apdu_pinpad_modify (int slot, int class, int ins, int p0, int p1, - pininfo_t *pininfo); + pininfo_t *pininfo); int apdu_send_simple (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data); diff --git a/scd/app-common.h b/scd/app-common.h index e12b4fb..b979f54 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -22,13 +22,8 @@ #ifndef GNUPG_SCD_APP_COMMON_H #define GNUPG_SCD_APP_COMMON_H -#if GNUPG_MAJOR_VERSION == 1 -# ifdef ENABLE_AGENT_SUPPORT -# include "assuan.h" -# endif -#else -# include <ksba.h> -#endif +#include <npth.h> +#include <ksba.h> #define APP_CHANGE_FLAG_RESET 1 @@ -41,6 +36,10 @@ struct app_local_s; /* Defined by all app-*.c. */ struct app_ctx_s { + struct app_ctx_s *next; + + npth_mutex_t lock; + /* Number of connections currently using this application context. If this is not 0 the application has been initialized and the function pointers may be used. Note that for unsupported @@ -50,18 +49,12 @@ struct app_ctx_s { /* Used reader slot. */ int slot; - /* If this is used by GnuPG 1.4 we need to know the assuan context - in case we need to divert the operation to an already running - agent. This if ASSUAN_CTX is not NULL we take this as indication - that all operations are diverted to gpg-agent. */ -#if GNUPG_MAJOR_VERSION == 1 - assuan_context_t assuan_ctx; -#endif /*GNUPG_MAJOR_VERSION == 1*/ - unsigned char *serialno; /* Serialnumber in raw form, allocated. */ size_t serialnolen; /* Length in octets of serialnumber. */ const char *apptype; unsigned int card_version; + unsigned int card_status; + unsigned int require_get_status:1; unsigned int did_chv1:1; unsigned int force_chv1:1; /* True if the card does not cache CHV1. */ unsigned int did_chv2:1; @@ -119,20 +112,8 @@ struct app_ctx_s { gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); } fnc; - }; -#if GNUPG_MAJOR_VERSION == 1 -gpg_error_t app_select_openpgp (app_t app); -gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp); -gpg_error_t app_openpgp_storekey (app_t app, int keyno, - unsigned char *template, size_t template_len, - time_t created_at, - const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, - gpg_error_t (*pincb)(void*, const char *, char **), - void *pincb_arg); -#else /*-- app-help.c --*/ unsigned int app_help_count_bits (const unsigned char *a, size_t len); gpg_error_t app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip); @@ -140,38 +121,43 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff); /*-- app.c --*/ +app_t app_list_start (void); +void app_list_finish (void); +void app_send_card_list (ctrl_t ctrl); +char *app_get_serialno (app_t app); + void app_dump_state (void); void application_notify_card_reset (int slot); -gpg_error_t check_application_conflict (ctrl_t ctrl, int slot, - const char *name); -gpg_error_t select_application (ctrl_t ctrl, int slot, const char *name, - app_t *r_app); +gpg_error_t check_application_conflict (const char *name, app_t app); +gpg_error_t app_reset (app_t app, ctrl_t ctrl, int send_reset); +gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app, + int scan, const unsigned char *serialno_bin, + size_t serialno_bin_len); char *get_supported_applications (void); void release_application (app_t app); gpg_error_t app_munge_serialno (app_t app); -gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp); gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags); -gpg_error_t app_readcert (app_t app, const char *certid, +gpg_error_t app_readcert (app_t app, ctrl_t ctrl, const char *certid, unsigned char **cert, size_t *certlen); -gpg_error_t app_readkey (app_t app, int advanced, const char *keyid, - unsigned char **pk, size_t *pklen); +gpg_error_t app_readkey (app_t app, ctrl_t ctrl, int advanced, + const char *keyid, unsigned char **pk, size_t *pklen); gpg_error_t app_getattr (app_t app, ctrl_t ctrl, const char *name); -gpg_error_t app_setattr (app_t app, const char *name, +gpg_error_t app_setattr (app_t app, ctrl_t ctrl, const char *name, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const unsigned char *value, size_t valuelen); -gpg_error_t app_sign (app_t app, const char *keyidstr, int hashalgo, +gpg_error_t app_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *indata, size_t indatalen, unsigned char **outdata, size_t *outdatalen ); -gpg_error_t app_auth (app_t app, const char *keyidstr, +gpg_error_t app_auth (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *indata, size_t indatalen, unsigned char **outdata, size_t *outdatalen); -gpg_error_t app_decipher (app_t app, const char *keyidstr, +gpg_error_t app_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *indata, size_t indatalen, @@ -192,13 +178,13 @@ gpg_error_t app_genkey (app_t app, ctrl_t ctrl, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); -gpg_error_t app_get_challenge (app_t app, size_t nbytes, +gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer); gpg_error_t app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); -gpg_error_t app_check_pin (app_t app, const char *keyidstr, +gpg_error_t app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); @@ -222,8 +208,4 @@ gpg_error_t app_select_geldkarte (app_t app); gpg_error_t app_select_sc_hsm (app_t app); -#endif - - - #endif /*GNUPG_SCD_APP_COMMON_H*/ diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 5fa4fd2..71c9e1b 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -978,21 +978,13 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) if (table[idx].special == -1) { /* The serial number is very special. We could have used the - AID DO to retrieve it, but we have it already in the app - context and the stamp argument is required anyway which we - can't by other means. The AID DO is available anyway but not - hex formatted. */ - char *serial; - time_t stamp; - char tmp[50]; - - if (!app_get_serial_and_stamp (app, &serial, &stamp)) + AID DO to retrieve it. The AID DO is available anyway but + not hex formatted. */ + char *serial = app_get_serialno (app); + + if (serial) { - sprintf (tmp, "%lu", (unsigned long)stamp); - send_status_info (ctrl, "SERIALNO", - serial, strlen (serial), - tmp, strlen (tmp), - NULL, 0); + send_status_direct (ctrl, "SERIALNO", serial); xfree (serial); } return 0; @@ -1029,10 +1021,9 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) } if (table[idx].special == -4) { - char *serial; - time_t stamp; + char *serial = app_get_serialno (app); - if (!app_get_serial_and_stamp (app, &serial, &stamp)) + if (serial) { if (strlen (serial) > 16+12) { @@ -3580,11 +3571,23 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), { if (app->app_local->extcap.algo_attr_change) { - unsigned char keyattr[oid_len]; + unsigned char *keyattr; + if (!oid_len) + { + err = gpg_error (GPG_ERR_INTERNAL); + goto leave; + } + keyattr = xtrymalloc (oid_len); + if (!keyattr) + { + err = gpg_error_from_syserror (); + goto leave; + } keyattr[0] = algo; memcpy (keyattr+1, oidbuf+1, oid_len-1); err = change_keyattr (app, keyno, keyattr, oid_len, pincb, pincb_arg); + xfree (keyattr); if (err) goto leave; } diff --git a/scd/app-p15.c b/scd/app-p15.c index 505073e..3def55b 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -2463,7 +2463,7 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo) p = stpcpy (buf, "P15"); if (app->app_local->home_df) { - snprintf (p, 6, "-%04hX", + snprintf (p, 6, "-%04X", (unsigned int)(app->app_local->home_df & 0xffff)); p += 5; } @@ -2689,7 +2689,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) p = stpcpy (buf, "P15"); if (app->app_local->home_df) { - snprintf (p, 6, "-%04hX", + snprintf (p, 6, "-%04X", (unsigned int)(app->app_local->home_df & 0xffff)); p += 5; } @@ -1,5 +1,5 @@ /* app.c - Application selection. - * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -25,27 +25,14 @@ #include <npth.h> #include "scdaemon.h" +#include "exechelp.h" #include "app-common.h" #include "iso7816.h" #include "apdu.h" #include "tlv.h" -/* This table is used to keep track of locks on a per reader base. - The index into the table is the slot number of the reader. The - mutex will be initialized on demand (one of the advantages of a - userland threading system). */ -static struct -{ - int initialized; - npth_mutex_t lock; - app_t app; /* Application context in use or NULL. */ -} lock_table[10]; - - - -static void deallocate_app (app_t app); - - +static npth_mutex_t app_list_lock; +static app_t app_top; static void print_progress_line (void *opaque, const char *what, int pc, int cur, int tot) @@ -69,54 +56,33 @@ print_progress_line (void *opaque, const char *what, int pc, int cur, int tot) success; only then the unlock_reader function must be called after returning from the handler. */ static gpg_error_t -lock_reader (int slot, ctrl_t ctrl) +lock_app (app_t app, ctrl_t ctrl) { - int res; - - if (slot < 0 || slot >= DIM (lock_table)) - return gpg_error (slot<0? GPG_ERR_INV_VALUE : GPG_ERR_RESOURCE_LIMIT); - - if (!lock_table[slot].initialized) + if (npth_mutex_lock (&app->lock)) { - res = npth_mutex_init (&lock_table[slot].lock, NULL); - if (res) - { - log_error ("error initializing mutex: %s\n", strerror (res)); - return gpg_error_from_errno (res); - } - lock_table[slot].initialized = 1; - lock_table[slot].app = NULL; - } - - res = npth_mutex_lock (&lock_table[slot].lock); - if (res) - { - log_error ("failed to acquire APP lock for slot %d: %s\n", - slot, strerror (res)); - return gpg_error_from_errno (res); + gpg_error_t err = gpg_error_from_syserror (); + log_error ("failed to acquire APP lock for %p: %s\n", + app, gpg_strerror (err)); + return err; } - apdu_set_progress_cb (slot, print_progress_line, ctrl); + apdu_set_progress_cb (app->slot, print_progress_line, ctrl); return 0; } /* Release a lock on the reader. See lock_reader(). */ static void -unlock_reader (int slot) +unlock_app (app_t app) { - int res; + apdu_set_progress_cb (app->slot, NULL, NULL); - if (slot < 0 || slot >= DIM (lock_table) - || !lock_table[slot].initialized) - log_bug ("unlock_reader called for invalid slot %d\n", slot); - - apdu_set_progress_cb (slot, NULL, NULL); - - res = npth_mutex_unlock (&lock_table[slot].lock); - if (res) - log_error ("failed to release APP lock for slot %d: %s\n", - slot, strerror (res)); + if (npth_mutex_unlock (&app->lock)) + { + gpg_error_t err = gpg_error_from_syserror (); + log_error ("failed to release APP lock for %p: %s\n", + app, gpg_strerror (err)); + } } @@ -125,20 +91,12 @@ unlock_reader (int slot) void app_dump_state (void) { - int slot; + app_t a; - for (slot=0; slot < DIM (lock_table); slot++) - if (lock_table[slot].initialized) - { - log_info ("app_dump_state: slot=%d", slot); - if (lock_table[slot].app) - { - log_printf (" app=%p", lock_table[slot].app); - if (lock_table[slot].app->apptype) - log_printf (" type='%s'", lock_table[slot].app->apptype); - } - log_printf ("\n"); - } + npth_mutex_lock (&app_list_lock); + for (a = app_top; a; a = a->next) + log_info ("app_dump_state: app=%p type='%s'\n", a, a->apptype); + npth_mutex_unlock (&app_list_lock); } /* Check wether the application NAME is allowed. This does not mean @@ -155,54 +113,16 @@ is_app_allowed (const char *name) } -/* This may be called to tell this module about a removed or resetted card. */ -void -application_notify_card_reset (int slot) -{ - if (slot < 0 || slot >= DIM (lock_table)) - return; - - /* FIXME: We are ignoring any error value here. */ - lock_reader (slot, NULL); - - /* Release the APP, as it's not reusable any more. */ - if (lock_table[slot].app) - { - if (lock_table[slot].app->ref_count) - log_bug ("trying to release active context\n"); - - deallocate_app (lock_table[slot].app); - lock_table[slot].app = NULL; - log_debug ("application has been released\n"); - } - - unlock_reader (slot); -} - - -/* - * This function is called with lock held. - */ static gpg_error_t -check_conflict (int slot, const char *name) +check_conflict (app_t app, const char *name) { - app_t app = lock_table[slot].app; - if (!app || !name || (app->apptype && !ascii_strcasecmp (app->apptype, name))) return 0; - if (!app->ref_count) - { - lock_table[slot].app = NULL; - deallocate_app (app); - return 0; - } - else - { - log_info ("application '%s' in use by reader %d - can't switch\n", - app->apptype? app->apptype : "<null>", slot); - return gpg_error (GPG_ERR_CONFLICT); - } + log_info ("application '%s' in use - can't switch\n", + app->apptype? app->apptype : "<null>"); + + return gpg_error (GPG_ERR_CONFLICT); } /* This function is used by the serialno command to check for an @@ -210,85 +130,85 @@ check_conflict (int slot, const char *name) used to request a specific application and the connection has already done a select_application. */ gpg_error_t -check_application_conflict (ctrl_t ctrl, int slot, const char *name) +check_application_conflict (const char *name, app_t app) { - gpg_error_t err; + return check_conflict (app, name); +} - if (slot < 0 || slot >= DIM (lock_table)) - return gpg_error (GPG_ERR_INV_VALUE); - err = lock_reader (slot, ctrl); - if (err) - return err; +static void +release_application_internal (app_t app) +{ + if (!app->ref_count) + log_bug ("trying to release an already released context\n"); - err = check_conflict (slot, name); - unlock_reader (slot); - return err; + --app->ref_count; } - -/* If called with NAME as NULL, select the best fitting application - and return a context; otherwise select the application with NAME - and return a context. SLOT identifies the reader device. Returns - an error code and stores NULL at R_APP if no application was found - or no card is present. */ gpg_error_t -select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) +app_reset (app_t app, ctrl_t ctrl, int send_reset) { gpg_error_t err; - app_t app = NULL; - unsigned char *result = NULL; - size_t resultlen; - int want_undefined; - - (void)ctrl; - *r_app = NULL; - - want_undefined = (name && !strcmp (name, "undefined")); - - err = lock_reader (slot, ctrl); + err = lock_app (app, ctrl); if (err) return err; - /* First check whether we already have an application to share. */ - err = check_conflict (slot, name); - if (err) + if (send_reset) { - unlock_reader (slot); - return err; - } - - app = lock_table[slot].app; + int sw = apdu_reset (app->slot); + if (sw) + err = gpg_error (GPG_ERR_CARD_RESET); - /* If we can reuse an application, bump the reference count and - return it. */ - if (app) + /* Release the same application which is used by other sessions. */ + send_client_notifications (app, 1); + } + else { - if (app->slot != slot) - log_bug ("slot mismatch %d/%d\n", app->slot, slot); - app->slot = slot; - - app->ref_count++; - *r_app = app; - unlock_reader (slot); - return 0; /* Okay: We share that one. */ + ctrl->app_ctx = NULL; + release_application_internal (app); } + unlock_app (app); + return err; +} + +static gpg_error_t +app_new_register (int slot, ctrl_t ctrl, const char *name) +{ + gpg_error_t err = 0; + app_t app = NULL; + unsigned char *result = NULL; + size_t resultlen; + int want_undefined; + /* Need to allocate a new one. */ app = xtrycalloc (1, sizeof *app); if (!app) { err = gpg_error_from_syserror (); log_info ("error allocating context: %s\n", gpg_strerror (err)); - unlock_reader (slot); return err; } + app->slot = slot; + if (npth_mutex_init (&app->lock, NULL)) + { + err = gpg_error_from_syserror (); + log_error ("error initializing mutex: %s\n", gpg_strerror (err)); + xfree (app); + return err; + } + + err = lock_app (app, ctrl); + if (err) + { + xfree (app); + return err; + } - /* Fixme: We should now first check whether a card is at all - present. */ + want_undefined = (name && !strcmp (name, "undefined")); /* Try to read the GDO file first to get a default serial number. We skip this if the undefined application has been requested. */ @@ -377,19 +297,110 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) else log_info ("no supported card application found: %s\n", gpg_strerror (err)); + unlock_app (app); xfree (app); - unlock_reader (slot); return err; } - app->ref_count = 1; + app->require_get_status = 1; /* For token, this can be 0. */ - lock_table[slot].app = app; - *r_app = app; - unlock_reader (slot); + npth_mutex_lock (&app_list_lock); + app->next = app_top; + app_top = app; + npth_mutex_unlock (&app_list_lock); + unlock_app (app); return 0; } +/* If called with NAME as NULL, select the best fitting application + and return a context; otherwise select the application with NAME + and return a context. Returns an error code and stores NULL at + R_APP if no application was found or no card is present. */ +gpg_error_t +select_application (ctrl_t ctrl, const char *name, app_t *r_app, + int scan, const unsigned char *serialno_bin, + size_t serialno_bin_len) +{ + gpg_error_t err = 0; + app_t a; + + *r_app = NULL; + + if (scan || !app_top) + { + struct dev_list *l; + + err = apdu_dev_list_start (opt.reader_port, &l); + if (err) + return err; + + while (1) + { + int slot; + int sw; + + slot = apdu_open_reader (l); + if (slot < 0) + break; + + err = 0; + sw = apdu_connect (slot); + + if (sw == SW_HOST_CARD_INACTIVE) + { + /* Try again. */ + sw = apdu_reset (slot); + } + + if (!sw || sw == SW_HOST_ALREADY_CONNECTED) + err = 0; + else if (sw == SW_HOST_NO_CARD) + err = gpg_error (GPG_ERR_CARD_NOT_PRESENT); + else + err = gpg_error (GPG_ERR_ENODEV); + + if (!err) + err = app_new_register (slot, ctrl, name); + else + { + /* We close a reader with no card. */ + apdu_close_reader (slot); + } + } + + apdu_dev_list_finish (l); + } + + npth_mutex_lock (&app_list_lock); + for (a = app_top; a; a = a->next) + { + lock_app (a, ctrl); + if (serialno_bin == NULL) + break; + if (a->serialnolen == serialno_bin_len + && !memcmp (a->serialno, serialno_bin, a->serialnolen)) + break; + unlock_app (a); + } + + if (a) + { + err = check_conflict (a, name); + if (!err) + { + a->ref_count++; + *r_app = a; + } + unlock_app (a); + } + else + err = gpg_error (GPG_ERR_ENODEV); + + npth_mutex_unlock (&app_list_lock); + + return err; +} + char * get_supported_applications (void) @@ -425,10 +436,27 @@ get_supported_applications (void) } -/* Deallocate the application. */ +/* Deallocate the application. */ static void deallocate_app (app_t app) { + app_t a, a_prev = NULL; + + for (a = app_top; a; a = a->next) + if (a == app) + { + if (a_prev == NULL) + app_top = a->next; + else + a_prev->next = a->next; + break; + } + else + a_prev = a; + + if (app->ref_count) + log_error ("trying to release context used yet (%d)\n", app->ref_count); + if (app->fnc.deinit) { app->fnc.deinit (app); @@ -447,33 +475,17 @@ deallocate_app (app_t app) void release_application (app_t app) { - int slot; - if (!app) return; - if (!app->ref_count) - log_bug ("trying to release an already released context\n"); - if (--app->ref_count) - return; - - /* Move the reference to the application in the lock table. */ - slot = app->slot; - /* FIXME: We are ignoring any error value. */ - lock_reader (slot, NULL); - if (lock_table[slot].app != app) - { - unlock_reader (slot); - log_bug ("app mismatch %p/%p\n", app, lock_table[slot].app); - deallocate_app (app); - return; - } - /* We don't deallocate app here. Instead, we keep it. This is useful so that a card does not get reset even if only one session is using the card - this way the PIN cache and other cached data are preserved. */ - unlock_reader (slot); + + lock_app (app, NULL); + release_application_internal (app); + unlock_app (app); } @@ -522,33 +534,23 @@ app_munge_serialno (app_t app) -/* Retrieve the serial number and the time of the last update of the - card. The serial number is returned as a malloced string (hex - encoded) in SERIAL and the time of update is returned in STAMP. If - no update time is available the returned value is 0. Caller must - free SERIAL unless the function returns an error. If STAMP is not - of interest, NULL may be passed. */ -gpg_error_t -app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp) +/* Retrieve the serial number of the card. The serial number is + returned as a malloced string (hex encoded) in SERIAL. Caller must + free SERIAL unless the function returns an error. */ +char * +app_get_serialno (app_t app) { - char *buf; + char *serial; - if (!app || !serial) - return gpg_error (GPG_ERR_INV_VALUE); - - *serial = NULL; - if (stamp) - *stamp = 0; /* not available */ + if (!app) + return NULL; if (!app->serialnolen) - buf = xtrystrdup ("FF7F00"); + serial = xtrystrdup ("FF7F00"); else - buf = bin2hex (app->serialno, app->serialnolen, NULL); - if (!buf) - return gpg_error_from_syserror (); + serial = bin2hex (app->serialno, app->serialnolen, NULL); - *serial = buf; - return 0; + return serial; } @@ -561,20 +563,17 @@ app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags) if (!app) return gpg_error (GPG_ERR_INV_VALUE); - if (!app->ref_count) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.learn_status) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); /* We do not send APPTYPE if only keypairinfo is requested. */ if (app->apptype && !(flags & 1)) - send_status_info (ctrl, "APPTYPE", - app->apptype, strlen (app->apptype), NULL, 0); - err = lock_reader (app->slot, ctrl); + send_status_direct (ctrl, "APPTYPE", app->apptype); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.learn_status (app, ctrl, flags); - unlock_reader (app->slot); + unlock_app (app); return err; } @@ -584,7 +583,7 @@ app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags) buffer put into CERT and the length of the certificate put into CERTLEN. */ gpg_error_t -app_readcert (app_t app, const char *certid, +app_readcert (app_t app, ctrl_t ctrl, const char *certid, unsigned char **cert, size_t *certlen) { gpg_error_t err; @@ -595,11 +594,11 @@ app_readcert (app_t app, const char *certid, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.readcert) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, NULL/* FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.readcert (app, certid, cert, certlen); - unlock_reader (app->slot); + unlock_app (app); return err; } @@ -612,7 +611,7 @@ app_readcert (app_t app, const char *certid, This function might not be supported by all applications. */ gpg_error_t -app_readkey (app_t app, int advanced, const char *keyid, +app_readkey (app_t app, ctrl_t ctrl, int advanced, const char *keyid, unsigned char **pk, size_t *pklen) { gpg_error_t err; @@ -628,11 +627,11 @@ app_readkey (app_t app, int advanced, const char *keyid, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.readkey) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, NULL /*FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err= app->fnc.readkey (app, advanced, keyid, pk, pklen); - unlock_reader (app->slot); + unlock_app (app); return err; } @@ -650,37 +649,35 @@ app_getattr (app_t app, ctrl_t ctrl, const char *name) if (app->apptype && name && !strcmp (name, "APPTYPE")) { - send_status_info (ctrl, "APPTYPE", - app->apptype, strlen (app->apptype), NULL, 0); + send_status_direct (ctrl, "APPTYPE", app->apptype); return 0; } if (name && !strcmp (name, "SERIALNO")) { char *serial; - time_t stamp; - int rc; - rc = app_get_serial_and_stamp (app, &serial, &stamp); - if (rc) - return rc; - send_status_info (ctrl, "SERIALNO", serial, strlen (serial), NULL, 0); + serial = app_get_serialno (app); + if (!serial) + return gpg_error (GPG_ERR_INV_VALUE); + + send_status_direct (ctrl, "SERIALNO", serial); xfree (serial); return 0; } if (!app->fnc.getattr) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, ctrl); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.getattr (app, ctrl, name); - unlock_reader (app->slot); + unlock_app (app); return err; } /* Perform a SETATTR operation. */ gpg_error_t -app_setattr (app_t app, const char *name, +app_setattr (app_t app, ctrl_t ctrl, const char *name, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const unsigned char *value, size_t valuelen) @@ -693,11 +690,11 @@ app_setattr (app_t app, const char *name, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.setattr) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, NULL /*FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen); - unlock_reader (app->slot); + unlock_app (app); return err; } @@ -705,7 +702,7 @@ app_setattr (app_t app, const char *name, If a PIN is required the PINCB will be used to ask for the PIN; it should return the PIN in an allocated buffer and put it into PIN. */ gpg_error_t -app_sign (app_t app, const char *keyidstr, int hashalgo, +app_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *indata, size_t indatalen, @@ -719,14 +716,14 @@ app_sign (app_t app, const char *keyidstr, int hashalgo, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.sign) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, NULL /*FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.sign (app, keyidstr, hashalgo, pincb, pincb_arg, indata, indatalen, outdata, outdatalen); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation sign result: %s\n", gpg_strerror (err)); return err; @@ -737,7 +734,7 @@ app_sign (app_t app, const char *keyidstr, int hashalgo, PINCB will be used to ask for the PIN; it should return the PIN in an allocated buffer and put it into PIN. */ gpg_error_t -app_auth (app_t app, const char *keyidstr, +app_auth (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *indata, size_t indatalen, @@ -751,14 +748,14 @@ app_auth (app_t app, const char *keyidstr, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.auth) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, NULL /*FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.auth (app, keyidstr, pincb, pincb_arg, indata, indatalen, outdata, outdatalen); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation auth result: %s\n", gpg_strerror (err)); return err; @@ -769,7 +766,7 @@ app_auth (app_t app, const char *keyidstr, If a PIN is required the PINCB will be used to ask for the PIN; it should return the PIN in an allocated buffer and put it into PIN. */ gpg_error_t -app_decipher (app_t app, const char *keyidstr, +app_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *indata, size_t indatalen, @@ -786,7 +783,7 @@ app_decipher (app_t app, const char *keyidstr, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.decipher) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, NULL /*FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.decipher (app, keyidstr, @@ -794,7 +791,7 @@ app_decipher (app_t app, const char *keyidstr, indata, indatalen, outdata, outdatalen, r_info); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation decipher result: %s\n", gpg_strerror (err)); return err; @@ -817,12 +814,12 @@ app_writecert (app_t app, ctrl_t ctrl, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.writecert) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, ctrl); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.writecert (app, ctrl, certidstr, pincb, pincb_arg, data, datalen); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation writecert result: %s\n", gpg_strerror (err)); return err; @@ -845,12 +842,12 @@ app_writekey (app_t app, ctrl_t ctrl, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.writekey) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, ctrl); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.writekey (app, ctrl, keyidstr, flags, pincb, pincb_arg, keydata, keydatalen); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation writekey result: %s\n", gpg_strerror (err)); return err; @@ -872,12 +869,12 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.genkey) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, ctrl); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.genkey (app, ctrl, keynostr, flags, createtime, pincb, pincb_arg); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation genkey result: %s\n", gpg_strerror (err)); return err; @@ -888,7 +885,7 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, directly accesses the card without any application specific wrapper. */ gpg_error_t -app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer) +app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer) { gpg_error_t err; @@ -896,11 +893,11 @@ app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer) return gpg_error (GPG_ERR_INV_VALUE); if (!app->ref_count) return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - err = lock_reader (app->slot, NULL /*FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err = iso7816_get_challenge (app->slot, nbytes, buffer); - unlock_reader (app->slot); + unlock_app (app); return err; } @@ -920,12 +917,12 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.change_pin) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, ctrl); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, pincb, pincb_arg); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation change_pin result: %s\n", gpg_strerror (err)); return err; @@ -936,7 +933,7 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, be used to initialze a the PIN cache for long lasting other operations. Its use is highly application dependent. */ gpg_error_t -app_check_pin (app_t app, const char *keyidstr, +app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { @@ -948,12 +945,166 @@ app_check_pin (app_t app, const char *keyidstr, return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.check_pin) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot, NULL /*FIXME*/); + err = lock_app (app, ctrl); if (err) return err; err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg); - unlock_reader (app->slot); + unlock_app (app); if (opt.verbose) log_info ("operation check_pin result: %s\n", gpg_strerror (err)); return err; } + +static void +report_change (int slot, int old_status, int cur_status) +{ + char *homestr, *envstr; + char *fname; + char templ[50]; + FILE *fp; + + snprintf (templ, sizeof templ, "reader_%d.status", slot); + fname = make_filename (gnupg_homedir (), templ, NULL ); + fp = fopen (fname, "w"); + if (fp) + { + fprintf (fp, "%s\n", + (cur_status & 1)? "USABLE": + (cur_status & 4)? "ACTIVE": + (cur_status & 2)? "PRESENT": "NOCARD"); + fclose (fp); + } + xfree (fname); + + homestr = make_filename (gnupg_homedir (), NULL); + if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0) + log_error ("out of core while building environment\n"); + else + { + gpg_error_t err; + const char *args[9], *envs[2]; + char numbuf1[30], numbuf2[30], numbuf3[30]; + + envs[0] = envstr; + envs[1] = NULL; + + sprintf (numbuf1, "%d", slot); + sprintf (numbuf2, "0x%04X", old_status); + sprintf (numbuf3, "0x%04X", cur_status); + args[0] = "--reader-port"; + args[1] = numbuf1; + args[2] = "--old-code"; + args[3] = numbuf2; + args[4] = "--new-code"; + args[5] = numbuf3; + args[6] = "--status"; + args[7] = ((cur_status & 1)? "USABLE": + (cur_status & 4)? "ACTIVE": + (cur_status & 2)? "PRESENT": "NOCARD"); + args[8] = NULL; + + fname = make_filename (gnupg_homedir (), "scd-event", NULL); + err = gnupg_spawn_process_detached (fname, args, envs); + if (err && gpg_err_code (err) != GPG_ERR_ENOENT) + log_error ("failed to run event handler '%s': %s\n", + fname, gpg_strerror (err)); + xfree (fname); + xfree (envstr); + } + xfree (homestr); +} + +void +scd_update_reader_status_file (void) +{ + app_t a, app_next; + + npth_mutex_lock (&app_list_lock); + for (a = app_top; a; a = app_next) + { + app_next = a->next; + if (a->require_get_status) + { + int sw; + unsigned int status; + sw = apdu_get_status (a->slot, 0, &status); + + if (sw == SW_HOST_NO_READER) + { + /* Most likely the _reader_ has been unplugged. */ + status = 0; + } + else if (sw) + { + /* Get status failed. Ignore that. */ + continue; + } + + if (a->card_status != status) + { + report_change (a->slot, a->card_status, status); + send_client_notifications (a, status == 0); + + if (status == 0) + { + log_debug ("Removal of a card: %d\n", a->slot); + apdu_close_reader (a->slot); + deallocate_app (a); + } + else + a->card_status = status; + } + } + } + npth_mutex_unlock (&app_list_lock); +} + +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +gpg_error_t +initialize_module_command (void) +{ + gpg_error_t err; + + if (npth_mutex_init (&app_list_lock, NULL)) + { + err = gpg_error_from_syserror (); + log_error ("app: error initializing mutex: %s\n", gpg_strerror (err)); + return err; + } + + return apdu_init (); +} + +app_t +app_list_start (void) +{ + npth_mutex_lock (&app_list_lock); + return app_top; +} + +void +app_list_finish (void) +{ + npth_mutex_unlock (&app_list_lock); +} + +void +app_send_card_list (ctrl_t ctrl) +{ + app_t a; + char buf[65]; + + npth_mutex_lock (&app_list_lock); + for (a = app_top; a; a = a->next) + { + if (DIM (buf) < 2 * a->serialnolen + 1) + continue; + + bin2hex (a->serialno, a->serialnolen, buf); + send_status_direct (ctrl, "SERIALNO", buf); + } + npth_mutex_unlock (&app_list_lock); +} diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 0917105..b7f97ed 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -239,12 +239,11 @@ static struct struct ccid_driver_s { libusb_device_handle *idev; - char *rid; int dev_fd; /* -1 for USB transport or file descriptor of the transport device. */ + unsigned int bai; unsigned short id_vendor; unsigned short id_product; - unsigned short bcd_device; int ifc_no; int ep_bulk_out; int ep_bulk_in; @@ -744,14 +743,13 @@ prepare_special_transport (ccid_driver_t handle) Note, that this code is based on the one in lsusb.c of the usb-utils package, I wrote on 2003-09-01. -wk. */ static int -parse_ccid_descriptor (ccid_driver_t handle, +parse_ccid_descriptor (ccid_driver_t handle, unsigned short bcd_device, const unsigned char *buf, size_t buflen) { unsigned int i; unsigned int us; int have_t1 = 0, have_tpdu=0; - handle->nonnull_nad = 0; handle->auto_ifsd = 0; handle->max_ifsd = 32; @@ -761,7 +759,7 @@ parse_ccid_descriptor (ccid_driver_t handle, handle->auto_param = 0; handle->auto_pps = 0; DEBUGOUT_3 ("idVendor: %04X idProduct: %04X bcdDevice: %04X\n", - handle->id_vendor, handle->id_product, handle->bcd_device); + handle->id_vendor, handle->id_product, bcd_device); if (buflen < 54 || buf[0] < 54) { DEBUGOUT ("CCID device descriptor is too short\n"); @@ -952,10 +950,10 @@ parse_ccid_descriptor (ccid_driver_t handle, lower than that: 64 - 10 CCID header - 4 T1frame - 2 reserved = 48 Product Ids: - 0xe001 - SCR 331 - 0x5111 - SCR 331-DI - 0x5115 - SCR 335 - 0xe003 - SPR 532 + 0xe001 - SCR 331 + 0x5111 - SCR 331-DI + 0x5115 - SCR 335 + 0xe003 - SPR 532 The 0x5117 - SCR 3320 USB ID-000 reader seems to be very slow but enabling this workaround boosts the @@ -964,11 +962,11 @@ parse_ccid_descriptor (ccid_driver_t handle, */ if (handle->id_vendor == VENDOR_SCM && handle->max_ifsd > 48 - && ( (handle->id_product == SCM_SCR331 && handle->bcd_device < 0x0516) - ||(handle->id_product == SCM_SCR331DI && handle->bcd_device < 0x0620) - ||(handle->id_product == SCM_SCR335 && handle->bcd_device < 0x0514) - ||(handle->id_product == SCM_SPR532 && handle->bcd_device < 0x0504) - ||(handle->id_product == SCM_SCR3320 && handle->bcd_device < 0x0522) + && ( (handle->id_product == SCM_SCR331 && bcd_device < 0x0516) + ||(handle->id_product == SCM_SCR331DI && bcd_device < 0x0620) + ||(handle->id_product == SCM_SCR335 && bcd_device < 0x0514) + ||(handle->id_product == SCM_SPR532 && bcd_device < 0x0504) + ||(handle->id_product == SCM_SCR3320 && bcd_device < 0x0522) )) { DEBUGOUT ("enabling workaround for buggy SCM readers\n"); @@ -1102,8 +1100,9 @@ find_endpoint (const struct libusb_interface_descriptor *ifcdesc, int mode) == LIBUSB_TRANSFER_TYPE_INTERRUPT) && (ep->bEndpointAddress & 0x80)) return ep->bEndpointAddress; - else if (((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) - == LIBUSB_TRANSFER_TYPE_BULK) + else if ((mode == 0 || mode == 1) + && ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) + == LIBUSB_TRANSFER_TYPE_BULK) && (ep->bEndpointAddress & 0x80) == want_bulk_in) return ep->bEndpointAddress; } @@ -1117,7 +1116,7 @@ find_endpoint (const struct libusb_interface_descriptor *ifcdesc, int mode) for other reasons. */ static int scan_or_find_usb_device (int scan_mode, - int *readerno, int *count, char **rid_list, + int readerno, int *count, char **rid_list, const char *readerid, struct libusb_device *dev, char **r_rid, @@ -1125,165 +1124,150 @@ scan_or_find_usb_device (int scan_mode, libusb_device_handle **r_idev, unsigned char **ifcdesc_extra, size_t *ifcdesc_extra_len, - int *interface_number, + int *interface_number, int *setting_number, int *ep_bulk_out, int *ep_bulk_in, int *ep_intr) { - int cfg_no; int ifc_no; int set_no; const struct libusb_interface_descriptor *ifcdesc; char *rid; - libusb_device_handle *idev; + libusb_device_handle *idev = NULL; int err; + struct libusb_config_descriptor *config; err = libusb_get_device_descriptor (dev, desc); - if (err < 0) - return err; + if (err) + return 0; *r_idev = NULL; - for (cfg_no=0; cfg_no < desc->bNumConfigurations; cfg_no++) - { - struct libusb_config_descriptor *config; + err = libusb_get_active_config_descriptor (dev, &config); + if (err) + return 0; - err = libusb_get_config_descriptor (dev, cfg_no, &config); - if (err < 0) - { - if (err == LIBUSB_ERROR_NO_MEM) - return err; - continue; - } + for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) + for (set_no=0; set_no < config->interface[ifc_no].num_altsetting; set_no++) + { + ifcdesc = (config->interface[ifc_no].altsetting + set_no); + /* The second condition is for older SCM SPR 532 who did + not know about the assigned CCID class. The third + condition does the same for a Cherry SmartTerminal + ST-2000. Instead of trying to interpret the strings + we simply check the product ID. */ + if (ifcdesc && ifcdesc->extra + && ((ifcdesc->bInterfaceClass == 11 + && ifcdesc->bInterfaceSubClass == 0 + && ifcdesc->bInterfaceProtocol == 0) + || (ifcdesc->bInterfaceClass == 255 + && desc->idVendor == VENDOR_SCM + && desc->idProduct == SCM_SPR532) + || (ifcdesc->bInterfaceClass == 255 + && desc->idVendor == VENDOR_CHERRY + && desc->idProduct == CHERRY_ST2000))) + { + ++*count; + if (!scan_mode && ((readerno > 0 && readerno != *count - 1))) + continue; - for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) - { - for (set_no=0; set_no < config->interface[ifc_no].num_altsetting; - set_no++) - { - ifcdesc = (config->interface[ifc_no].altsetting + set_no); - /* The second condition is for older SCM SPR 532 who did - not know about the assigned CCID class. The third - condition does the same for a Cherry SmartTerminal - ST-2000. Instead of trying to interpret the strings - we simply check the product ID. */ - if (ifcdesc && ifcdesc->extra - && ((ifcdesc->bInterfaceClass == 11 - && ifcdesc->bInterfaceSubClass == 0 - && ifcdesc->bInterfaceProtocol == 0) - || (ifcdesc->bInterfaceClass == 255 - && desc->idVendor == VENDOR_SCM - && desc->idProduct == SCM_SPR532) - || (ifcdesc->bInterfaceClass == 255 - && desc->idVendor == VENDOR_CHERRY - && desc->idProduct == CHERRY_ST2000))) - { - err = libusb_open (dev, &idev); - if (err < 0) - { - DEBUGOUT_1 ("usb_open failed: %s\n", - libusb_error_name (err)); - continue; /* with next setting. */ - } - - rid = make_reader_id (idev, - desc->idVendor, - desc->idProduct, - desc->iSerialNumber); - if (rid) - { - if (scan_mode) - { - char *p; - - /* We are collecting infos about all - available CCID readers. Store them and - continue. */ - DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n", - *count, rid ); - p = malloc ((*rid_list? strlen (*rid_list):0) + 1 - + strlen (rid) + 1); - if (p) - { - *p = 0; - if (*rid_list) - { - strcat (p, *rid_list); - free (*rid_list); - } - strcat (p, rid); - strcat (p, "\n"); - *rid_list = p; - } - else /* Out of memory. */ - free (rid); - - rid = NULL; - ++*count; - } - else if (!*readerno - || (*readerno < 0 - && readerid - && !strcmp (readerid, rid))) - { - /* We found the requested reader. */ - if (ifcdesc_extra && ifcdesc_extra_len) - { - *ifcdesc_extra = malloc (ifcdesc - ->extra_length); - if (!*ifcdesc_extra) - { - libusb_close (idev); - free (rid); - libusb_free_config_descriptor (config); - return 1; /* Out of core. */ - } - memcpy (*ifcdesc_extra, ifcdesc->extra, - ifcdesc->extra_length); - *ifcdesc_extra_len = ifcdesc->extra_length; - } - - if (interface_number) - *interface_number = (ifcdesc->bInterfaceNumber); - - if (ep_bulk_out) - *ep_bulk_out = find_endpoint (ifcdesc, 0); - if (ep_bulk_in) - *ep_bulk_in = find_endpoint (ifcdesc, 1); - if (ep_intr) - *ep_intr = find_endpoint (ifcdesc, 2); - - if (r_rid) - { - *r_rid = rid; - rid = NULL; - } - else - free (rid); - - *r_idev = idev; - libusb_free_config_descriptor (config); - return 1; /* Found requested device. */ - } - else - { - /* This is not yet the reader we want. - fixme: We should avoid the extra usb_open - in this case. */ - if (*readerno >= 0) - --*readerno; - } - free (rid); - } - - libusb_close (idev); - idev = NULL; - libusb_free_config_descriptor (config); - return 0; - } - } - } + err = libusb_open (dev, &idev); + if (err) + { + DEBUGOUT_1 ("usb_open failed: %s\n", libusb_error_name (err)); + continue; /* with next setting. */ + } + + rid = make_reader_id (idev, desc->idVendor, desc->idProduct, + desc->iSerialNumber); + if (!rid) + { + libusb_free_config_descriptor (config); + return 0; + } + + if (!scan_mode && readerno == -1 && readerid + && strncmp (rid, readerid, strlen (readerid))) + continue; - libusb_free_config_descriptor (config); - } + if (scan_mode) + { + char *p; + + /* We are collecting infos about all + available CCID readers. Store them and + continue. */ + DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n", *count, rid); + p = malloc ((*rid_list? strlen (*rid_list):0) + 1 + + strlen (rid) + 1); + if (p) + { + *p = 0; + if (*rid_list) + { + strcat (p, *rid_list); + free (*rid_list); + } + strcat (p, rid); + strcat (p, "\n"); + *rid_list = p; + } + else /* Out of memory. */ + { + libusb_free_config_descriptor (config); + free (rid); + return 0; + } + } + else + { + /* We found the requested reader. */ + if (ifcdesc_extra && ifcdesc_extra_len) + { + *ifcdesc_extra = malloc (ifcdesc->extra_length); + if (!*ifcdesc_extra) + { + libusb_close (idev); + free (rid); + libusb_free_config_descriptor (config); + return 1; /* Out of core. */ + } + memcpy (*ifcdesc_extra, ifcdesc->extra, + ifcdesc->extra_length); + *ifcdesc_extra_len = ifcdesc->extra_length; + } + + if (interface_number) + *interface_number = ifc_no; + + if (setting_number) + *setting_number = set_no; + + if (ep_bulk_out) + *ep_bulk_out = find_endpoint (ifcdesc, 0); + if (ep_bulk_in) + *ep_bulk_in = find_endpoint (ifcdesc, 1); + if (ep_intr) + *ep_intr = find_endpoint (ifcdesc, 2); + + if (r_rid) + { + *r_rid = rid; + rid = NULL; + } + else + free (rid); + + *r_idev = idev; + libusb_free_config_descriptor (config); + return 1; /* Found requested device. */ + } + + free (rid); + libusb_close (idev); + idev = NULL; + } + } + + libusb_free_config_descriptor (config); return 0; } @@ -1331,7 +1315,7 @@ scan_or_find_devices (int readerno, const char *readerid, struct libusb_device_descriptor *r_desc, unsigned char **ifcdesc_extra, size_t *ifcdesc_extra_len, - int *interface_number, + int *interface_number, int *setting_number, int *ep_bulk_out, int *ep_bulk_in, int *ep_intr, libusb_device_handle **r_idev, int *r_fd) @@ -1355,6 +1339,8 @@ scan_or_find_devices (int readerno, const char *readerid, *ifcdesc_extra_len = 0; if (interface_number) *interface_number = 0; + if (setting_number) + *setting_number = 0; if (r_idev) *r_idev = NULL; if (r_fd) @@ -1371,7 +1357,7 @@ scan_or_find_devices (int readerno, const char *readerid, for (i = 0; i < n; i++) { dev = dev_list[i]; - if (scan_or_find_usb_device (scan_mode, &readerno, &count, &rid_list, + if (scan_or_find_usb_device (scan_mode, readerno, &count, &rid_list, readerid, dev, r_rid, @@ -1379,7 +1365,7 @@ scan_or_find_devices (int readerno, const char *readerid, &idev, ifcdesc_extra, ifcdesc_extra_len, - interface_number, + interface_number, setting_number, ep_bulk_out, ep_bulk_in, ep_intr)) { libusb_free_device_list (dev_list, 1); @@ -1514,7 +1500,7 @@ ccid_get_reader_list (void) } if (scan_or_find_devices (-1, NULL, &reader_list, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL)) + NULL, NULL, NULL, NULL, NULL, NULL)) return NULL; /* Error. */ return reader_list; } @@ -1547,23 +1533,33 @@ ccid_vendor_specific_init (ccid_driver_t handle) } -/* Open the reader with the internal number READERNO and return a - pointer to be used as handle in HANDLE. Returns 0 on success. */ -int -ccid_open_reader (ccid_driver_t *handle, const char *readerid, - const char **rdrname_p) -{ - int rc = 0; - libusb_device_handle *idev = NULL; - int dev_fd = -1; - char *rid = NULL; - unsigned char *ifcdesc_extra = NULL; +#define MAX_DEVICE 4 /* See MAX_READER in apdu.c. */ + +struct ccid_dev_table { + int n; /* Index to ccid_usb_dev_list */ + int transport; + int interface_number; + int setting_number; + unsigned char *ifcdesc_extra; + int ep_bulk_out; + int ep_bulk_in; + int ep_intr; size_t ifcdesc_extra_len; - int readerno; - int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr; - struct libusb_device_descriptor desc; +}; + +static libusb_device **ccid_usb_dev_list; +static struct ccid_dev_table ccid_dev_table[MAX_DEVICE]; - *handle = NULL; +gpg_error_t +ccid_dev_scan (int *idx_max_p, struct ccid_dev_table **t_p) +{ + ssize_t n; + libusb_device *dev; + int i; + int ifc_no; + int set_no; + int idx = 0; + int err = 0; if (!initialized_usb) { @@ -1571,86 +1567,281 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid, initialized_usb = 1; } - /* See whether we want to use the reader ID string or a reader - number. A readerno of -1 indicates that the reader ID string is - to be used. */ - if (readerid && strchr (readerid, ':')) - readerno = -1; /* We want to use the readerid. */ - else if (readerid) + n = libusb_get_device_list (NULL, &ccid_usb_dev_list); + for (i = 0; i < n; i++) + { + struct libusb_config_descriptor *config; + struct libusb_device_descriptor desc; + + dev = ccid_usb_dev_list[i]; + + if (libusb_get_device_descriptor (dev, &desc)) + continue; + + if (libusb_get_active_config_descriptor (dev, &config)) + continue; + + for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) + for (set_no=0; set_no < config->interface[ifc_no].num_altsetting; + set_no++) + { + const struct libusb_interface_descriptor *ifcdesc; + + ifcdesc = &config->interface[ifc_no].altsetting[set_no]; + /* The second condition is for older SCM SPR 532 who did + not know about the assigned CCID class. The third + condition does the same for a Cherry SmartTerminal + ST-2000. Instead of trying to interpret the strings + we simply check the product ID. */ + if (ifcdesc && ifcdesc->extra + && ((ifcdesc->bInterfaceClass == 11 + && ifcdesc->bInterfaceSubClass == 0 + && ifcdesc->bInterfaceProtocol == 0) + || (ifcdesc->bInterfaceClass == 255 + && desc.idVendor == VENDOR_SCM + && desc.idProduct == SCM_SPR532) + || (ifcdesc->bInterfaceClass == 255 + && desc.idVendor == VENDOR_CHERRY + && desc.idProduct == CHERRY_ST2000))) + { + /* Found a reader. */ + unsigned char *ifcdesc_extra; + + ifcdesc_extra = malloc (ifcdesc->extra_length); + if (!ifcdesc_extra) + { + err = gpg_error_from_syserror (); + libusb_free_config_descriptor (config); + goto scan_finish; + } + memcpy (ifcdesc_extra, ifcdesc->extra, ifcdesc->extra_length); + + ccid_dev_table[idx].transport = TRANSPORT_USB; + ccid_dev_table[idx].n = i; + ccid_dev_table[idx].interface_number = ifc_no; + ccid_dev_table[idx].setting_number = set_no; + ccid_dev_table[idx].ifcdesc_extra = ifcdesc_extra; + ccid_dev_table[idx].ifcdesc_extra_len = ifcdesc->extra_length; + ccid_dev_table[idx].ep_bulk_out = find_endpoint (ifcdesc, 0); + ccid_dev_table[idx].ep_bulk_in = find_endpoint (ifcdesc, 1); + ccid_dev_table[idx].ep_intr = find_endpoint (ifcdesc, 2); + + idx++; + if (idx >= MAX_DEVICE) + { + libusb_free_config_descriptor (config); + err = 0; + goto scan_finish; + } + } + } + + libusb_free_config_descriptor (config); + } + + /* Now check whether there are any devices with special transport types. */ + for (i=0; transports[i].name; i++) { - readerno = atoi (readerid); - if (readerno < 0) + if (access (transports[i].name, (R_OK|W_OK)) == 0) { - DEBUGOUT ("no CCID readers found\n"); - rc = CCID_DRIVER_ERR_NO_READER; - goto leave; + /* Found a device. */ + DEBUGOUT_1 ("Found CCID reader %d\n", idx); + + ccid_dev_table[idx].transport = TRANSPORT_CM4040; + ccid_dev_table[idx].n = i; + ccid_dev_table[idx].interface_number = 0; + ccid_dev_table[idx].setting_number = 0; + ccid_dev_table[idx].ifcdesc_extra = NULL; + ccid_dev_table[idx].ifcdesc_extra_len = 0; + ccid_dev_table[idx].ep_bulk_out = 0; + ccid_dev_table[idx].ep_bulk_in = 0; + ccid_dev_table[idx].ep_intr = 0; + + idx++; + if (idx >= MAX_DEVICE) + goto scan_finish; } } - else - readerno = 0; /* Default. */ - if (scan_or_find_devices (readerno, readerid, &rid, &desc, - &ifcdesc_extra, &ifcdesc_extra_len, - &ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr, - &idev, &dev_fd) ) + scan_finish: + + if (err) + { + *idx_max_p = 0; + *t_p = NULL; + for (i = 0; i < idx; i++) + { + free (ccid_dev_table[idx].ifcdesc_extra); + ccid_dev_table[idx].transport = 0; + ccid_dev_table[idx].n = 0; + ccid_dev_table[idx].interface_number = 0; + ccid_dev_table[idx].setting_number = 0; + ccid_dev_table[idx].ifcdesc_extra = NULL; + ccid_dev_table[idx].ifcdesc_extra_len = 0; + ccid_dev_table[idx].ep_bulk_out = 0; + ccid_dev_table[idx].ep_bulk_in = 0; + ccid_dev_table[idx].ep_intr = 0; + } + libusb_free_device_list (ccid_usb_dev_list, 1); + ccid_usb_dev_list = NULL; + } + else { - if (readerno == -1) - DEBUGOUT_1 ("no CCID reader with ID %s\n", readerid ); + *idx_max_p = idx; + if (idx) + *t_p = ccid_dev_table; else - DEBUGOUT_1 ("no CCID reader with number %d\n", readerno ); - rc = CCID_DRIVER_ERR_NO_READER; - goto leave; + *t_p = NULL; } - /* Okay, this is a CCID reader. */ - *handle = calloc (1, sizeof **handle); - if (!*handle) + return err; +} + +void +ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max) +{ + int i; + + for (i = 0; i < max; i++) { - DEBUGOUT ("out of memory\n"); - rc = CCID_DRIVER_ERR_OUT_OF_CORE; - goto leave; + free (tbl[i].ifcdesc_extra); + tbl[i].transport = 0; + tbl[i].n = 0; + tbl[i].interface_number = 0; + tbl[i].setting_number = 0; + tbl[i].ifcdesc_extra = NULL; + tbl[i].ifcdesc_extra_len = 0; + tbl[i].ep_bulk_out = 0; + tbl[i].ep_bulk_in = 0; + tbl[i].ep_intr = 0; } - (*handle)->rid = rid; - if (idev) /* Regular USB transport. */ + libusb_free_device_list (ccid_usb_dev_list, 1); + ccid_usb_dev_list = NULL; +} + +unsigned int +ccid_get_BAI (int idx, struct ccid_dev_table *tbl) +{ + int n; + int bus, addr, intf; + unsigned int bai; + + if (tbl[idx].transport == TRANSPORT_USB) { - (*handle)->idev = idev; - (*handle)->dev_fd = -1; - (*handle)->id_vendor = desc.idVendor; - (*handle)->id_product = desc.idProduct; - (*handle)->bcd_device = desc.bcdDevice; - (*handle)->ifc_no = ifc_no; - (*handle)->ep_bulk_out = ep_bulk_out; - (*handle)->ep_bulk_in = ep_bulk_in; - (*handle)->ep_intr = ep_intr; + libusb_device *dev; + + n = tbl[idx].n; + dev = ccid_usb_dev_list[n]; + + bus = libusb_get_bus_number (dev); + addr = libusb_get_device_address (dev); + intf = tbl[idx].interface_number; + bai = (bus << 16) | (addr << 8) | intf; } - else if (dev_fd != -1) /* Device transport. */ + else { - (*handle)->idev = NULL; - (*handle)->dev_fd = dev_fd; - (*handle)->id_vendor = 0; /* Magic vendor for special transport. */ - (*handle)->id_product = ifc_no; /* Transport type */ - prepare_special_transport (*handle); + n = tbl[idx].n; + bai = 0xFFFF0000 | n; } - else + + return bai; +} + +int +ccid_compare_BAI (ccid_driver_t handle, unsigned int bai) +{ + return handle->bai == bai; +} + +static int +ccid_open_usb_reader (const char *spec_reader_name, + int idx, struct ccid_dev_table *ccid_table, + ccid_driver_t *handle, char **rdrname_p) +{ + libusb_device *dev; + libusb_device_handle *idev = NULL; + char *rid; + int rc = 0; + int ifc_no, set_no; + struct libusb_device_descriptor desc; + int n; + int bus, addr; + unsigned int bai; + + n = ccid_table[idx].n; + ifc_no = ccid_table[idx].interface_number; + set_no = ccid_table[idx].setting_number; + + dev = ccid_usb_dev_list[n]; + bus = libusb_get_bus_number (dev); + addr = libusb_get_device_address (dev); + bai = (bus << 16) | (addr << 8) | ifc_no; + + rc = libusb_open (dev, &idev); + if (rc) { - assert (!"no transport"); /* Bug. */ + DEBUGOUT_1 ("usb_open failed: %s\n", libusb_error_name (rc)); + free (*handle); + *handle = NULL; + return rc; + } + + rc = libusb_get_device_descriptor (dev, &desc); + if (rc) + { + libusb_close (idev); + free (*handle); + *handle = NULL; + return rc; } - DEBUGOUT_2 ("using CCID reader %d (ID=%s)\n", readerno, rid ); + rid = make_reader_id (idev, desc.idVendor, desc.idProduct, + desc.iSerialNumber); - if (idev) + /* Check to see if reader name matches the spec. */ + if (spec_reader_name + && strncmp (rid, spec_reader_name, strlen (spec_reader_name))) { - if (parse_ccid_descriptor (*handle, ifcdesc_extra, ifcdesc_extra_len)) - { - DEBUGOUT ("device not supported\n"); - rc = CCID_DRIVER_ERR_NO_READER; - goto leave; - } + DEBUGOUT ("device not matched\n"); + rc = CCID_DRIVER_ERR_NO_READER; + goto leave; + } - rc = libusb_claim_interface (idev, ifc_no); - if (rc < 0) + (*handle)->id_vendor = desc.idVendor; + (*handle)->id_product = desc.idProduct; + (*handle)->idev = idev; + (*handle)->dev_fd = -1; + (*handle)->bai = bai; + (*handle)->ifc_no = ifc_no; + (*handle)->ep_bulk_out = ccid_table[idx].ep_bulk_out; + (*handle)->ep_bulk_in = ccid_table[idx].ep_bulk_in; + (*handle)->ep_intr = ccid_table[idx].ep_intr; + + DEBUGOUT_2 ("using CCID reader %d (ID=%s)\n", idx, rid); + + if (parse_ccid_descriptor (*handle, desc.bcdDevice, + ccid_table[idx].ifcdesc_extra, + ccid_table[idx].ifcdesc_extra_len)) + { + DEBUGOUT ("device not supported\n"); + rc = CCID_DRIVER_ERR_NO_READER; + goto leave; + } + + rc = libusb_claim_interface (idev, ifc_no); + if (rc) + { + DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); + rc = CCID_DRIVER_ERR_CARD_IO_ERROR; + goto leave; + } + + if (set_no != 0) + { + rc = libusb_set_interface_alt_setting (idev, ifc_no, set_no); + if (rc) { - DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); + DEBUGOUT_1 ("usb_set_interface_alt_setting failed: %d\n", rc); rc = CCID_DRIVER_ERR_CARD_IO_ERROR; goto leave; } @@ -1659,24 +1850,96 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid, rc = ccid_vendor_specific_init (*handle); leave: - free (ifcdesc_extra); if (rc) { free (rid); - if (idev) - libusb_close (idev); - if (dev_fd != -1) - close (dev_fd); + libusb_close (idev); free (*handle); *handle = NULL; } else - if (rdrname_p) - *rdrname_p = (*handle)->rid; + { + if (rdrname_p) + *rdrname_p = rid; + else + free (rid); + } return rc; } +/* Open the reader with the internal number READERNO and return a + pointer to be used as handle in HANDLE. Returns 0 on success. */ +int +ccid_open_reader (const char *spec_reader_name, + int idx, struct ccid_dev_table *ccid_table, + ccid_driver_t *handle, char **rdrname_p) +{ + int n; + int fd; + char *rid; + + *handle = calloc (1, sizeof **handle); + if (!*handle) + { + DEBUGOUT ("out of memory\n"); + return CCID_DRIVER_ERR_OUT_OF_CORE; + } + + if (ccid_table[idx].transport == TRANSPORT_USB) + return ccid_open_usb_reader (spec_reader_name, idx, ccid_table, + handle, rdrname_p); + + /* Special transport support. */ + + n = ccid_table[idx].n; + fd = open (transports[n].name, O_RDWR); + if (fd < 0) + { + DEBUGOUT_2 ("failed to open '%s': %s\n", + transports[n].name, strerror (errno)); + free (*handle); + *handle = NULL; + return -1; + } + + rid = malloc (strlen (transports[n].name) + 30 + 10); + if (!rid) + { + close (fd); + free (*handle); + *handle = NULL; + return -1; /* Error. */ + } + + sprintf (rid, "0000:%04X:%s:0", transports[n].type, transports[n].name); + + /* Check to see if reader name matches the spec. */ + if (spec_reader_name + && strncmp (rid, spec_reader_name, strlen (spec_reader_name))) + { + DEBUGOUT ("device not matched\n"); + free (rid); + close (fd); + free (*handle); + *handle = NULL; + return -1; + } + + (*handle)->id_vendor = 0; + (*handle)->id_product = transports[n].type; + (*handle)->idev = NULL; + (*handle)->dev_fd = fd; + (*handle)->bai = 0xFFFF0000 | n; + prepare_special_transport (*handle); + if (rdrname_p) + *rdrname_p = rid; + else + free (rid); + + return 0; +} + static void do_close_reader (ccid_driver_t handle) @@ -1722,7 +1985,7 @@ ccid_set_progress_cb (ccid_driver_t handle, void (*cb)(void *, const char *, int, int, int), void *cb_arg) { - if (!handle || !handle->rid) + if (!handle) return CCID_DRIVER_ERR_INV_VALUE; handle->progress_cb = cb; @@ -1739,7 +2002,6 @@ ccid_close_reader (ccid_driver_t handle) return 0; do_close_reader (handle); - free (handle->rid); free (handle); return 0; } @@ -1802,19 +2064,19 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen, case PC_to_RDR_IccPowerOff: print_p2r_iccpoweroff (msg, msglen); break; - case PC_to_RDR_GetSlotStatus: + case PC_to_RDR_GetSlotStatus: print_p2r_getslotstatus (msg, msglen); break; case PC_to_RDR_XfrBlock: print_p2r_xfrblock (msg, msglen); break; - case PC_to_RDR_GetParameters: + case PC_to_RDR_GetParameters: print_p2r_getparameters (msg, msglen); break; case PC_to_RDR_ResetParameters: print_p2r_resetparameters (msg, msglen); break; - case PC_to_RDR_SetParameters: + case PC_to_RDR_SetParameters: print_p2r_setparameters (msg, msglen); break; case PC_to_RDR_Escape: @@ -1823,7 +2085,7 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen, case PC_to_RDR_IccClock: print_p2r_iccclock (msg, msglen); break; - case PC_to_RDR_T0APDU: + case PC_to_RDR_T0APDU: print_p2r_to0apdu (msg, msglen); break; case PC_to_RDR_Secure: @@ -1854,7 +2116,7 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen, if (rc == 0 && transferred == msglen) return 0; - if (rc < 0) + if (rc) { DEBUGOUT_1 ("usb_bulk_write error: %s\n", libusb_error_name (rc)); if (rc == LIBUSB_ERROR_NO_DEVICE) @@ -1901,7 +2163,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, { rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in, (char*)buffer, length, &msglen, timeout); - if (rc < 0) + if (rc) { DEBUGOUT_1 ("usb_bulk_read error: %s\n", libusb_error_name (rc)); if (rc == LIBUSB_ERROR_NO_DEVICE) @@ -2043,7 +2305,7 @@ abort_cmd (ccid_driver_t handle, int seqno) handle->ifc_no, dummybuf, 0, 1000 /* ms timeout */); - if (rc < 0) + if (rc) { DEBUGOUT_1 ("usb_control_msg error: %s\n", libusb_error_name (rc)); return CCID_DRIVER_ERR_CARD_IO_ERROR; @@ -2072,7 +2334,7 @@ abort_cmd (ccid_driver_t handle, int seqno) 5000 /* ms timeout */); if (rc == 0 && transferred == msglen) rc = 0; - else if (rc < 0) + else if (rc) DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n", libusb_error_name (rc)); @@ -2082,7 +2344,7 @@ abort_cmd (ccid_driver_t handle, int seqno) rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in, (char*)msg, sizeof msg, &msglen, 5000 /*ms timeout*/); - if (rc < 0) + if (rc) { DEBUGOUT_1 ("usb_bulk_read error in abort_cmd: %s\n", libusb_error_name (rc)); @@ -2198,16 +2460,16 @@ ccid_poll (ccid_driver_t handle) if (handle->idev) { - rc = libusb_bulk_transfer (handle->idev, handle->ep_intr, - (char*)msg, sizeof msg, &msglen, - 0 /* ms timeout */ ); + rc = libusb_interrupt_transfer (handle->idev, handle->ep_intr, + (char*)msg, sizeof msg, &msglen, + 0 /* ms timeout */ ); if (rc == LIBUSB_ERROR_TIMEOUT) return 0; } else return 0; - if (rc < 0) + if (rc) { DEBUGOUT_1 ("usb_intr_read error: %s\n", libusb_error_name (rc)); return CCID_DRIVER_ERR_CARD_IO_ERROR; diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index e3aed9f..9e71f5e 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -1,5 +1,5 @@ -/* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003 Free Software Foundation, Inc. +/* ccid-driver.h - USB ChipCardInterfaceDevices driver + * Copyright (C) 2003 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -109,10 +109,18 @@ enum { struct ccid_driver_s; typedef struct ccid_driver_s *ccid_driver_t; +struct ccid_dev_table; + int ccid_set_debug_level (int level); char *ccid_get_reader_list (void); -int ccid_open_reader (ccid_driver_t *handle, const char *readerid, - const char **rdrname_p); + +gpg_error_t ccid_dev_scan (int *idx_max, struct ccid_dev_table **t_p); +void ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max); +unsigned int ccid_get_BAI (int, struct ccid_dev_table *tbl); +int ccid_compare_BAI (ccid_driver_t handle, unsigned int); +int ccid_open_reader (const char *spec_reader_name, + int idx, struct ccid_dev_table *ccid_table, + ccid_driver_t *handle, char **rdrname_p); int ccid_set_progress_cb (ccid_driver_t handle, void (*cb)(void *, const char *, int, int, int), void *cb_arg); @@ -126,7 +134,7 @@ int ccid_transceive (ccid_driver_t handle, unsigned char *resp, size_t maxresplen, size_t *nresp); int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu, size_t apdulen, - pininfo_t *pininfo, + pininfo_t *pininfo, unsigned char *resp, size_t maxresplen, size_t *nresp); int ccid_transceive_escape (ccid_driver_t handle, const unsigned char *data, size_t datalen, diff --git a/scd/command.c b/scd/command.c index e771a74..8c7ca20 100644 --- a/scd/command.c +++ b/scd/command.c @@ -37,7 +37,6 @@ #include "iso7816.h" #include "apdu.h" /* Required for apdu_*_reader (). */ #include "atr.h" -#include "exechelp.h" #ifdef HAVE_LIBUSB #include "ccid-driver.h" #endif @@ -59,44 +58,7 @@ #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) - -/* Macro to flag a removed card. ENODEV is also tested to catch the - case of a removed reader. */ -#define TEST_CARD_REMOVAL(c,r) \ - do { \ - int _r = (r); \ - if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \ - || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \ - || gpg_err_code (_r) == GPG_ERR_CARD_RESET \ - || gpg_err_code (_r) == GPG_ERR_ENODEV ) \ - update_card_removed ((c)->server_local->vreader_idx, 1); \ - } while (0) - -#define IS_LOCKED(c) \ - (locked_session \ - && locked_session != (c)->server_local \ - && (c)->server_local->vreader_idx != -1 \ - && locked_session->ctrl_backlink \ - && ((c)->server_local->vreader_idx \ - == locked_session->ctrl_backlink->server_local->vreader_idx)) - - -/* This structure is used to keep track of user readers. To - eventually accommodate this structure for RFID cards, where more - than one card is used per reader, we name it virtual reader. */ -struct vreader_s -{ - int valid; /* True if the other objects are valid. */ - int slot; /* APDU slot number of the reader or -1 if not open. */ - - int reset_failed; /* A reset failed. */ - - int any; /* Flag indicating whether any status check has been - done. This is set once to indicate that the status - tracking for the slot has been initialized. */ - unsigned int status; /* Last status of the reader. */ - unsigned int changed; /* Last change counter of the reader. */ -}; +#define IS_LOCKED(c) (locked_session && locked_session != (c)->server_local) /* Data used to associate an Assuan context with local server data. @@ -122,16 +84,10 @@ struct server_local_s int event_signal; /* Or 0 if not used. */ #endif - /* Index into the vreader table (command.c) or -1 if not open. */ - int vreader_idx; - /* True if the card has been removed and a reset is required to continue operation. */ int card_removed; - /* A disconnect command has been sent. */ - int disconnect_allowed; - /* If set to true we will be terminate ourself at the end of the this session. */ int stopme; @@ -139,10 +95,6 @@ struct server_local_s }; -/* The table with information on all used virtual readers. */ -static struct vreader_s vreader_table[10]; - - /* To keep track of all running sessions, we link all active server contexts and the anchor in this variable. */ static struct server_local_s *session_list; @@ -151,88 +103,7 @@ static struct server_local_s *session_list; in this variable. */ static struct server_local_s *locked_session; -/* While doing a reset we need to make sure that the ticker does not - call scd_update_reader_status_file while we are using it. */ -static npth_mutex_t status_file_update_lock; - -/*-- Local prototypes --*/ -static void update_reader_status_file (int set_card_removed_flag); - - - - -/* This function must be called once to initialize this module. This - has to be done before a second thread is spawned. We can't do the - static initialization because Pth emulation code might not be able - to do a static init; in particular, it is not possible for W32. */ -void -initialize_module_command (void) -{ - static int initialized; - int err; - - if (!initialized) - { - err = npth_mutex_init (&status_file_update_lock, NULL); - if (!err) - initialized = 1; - } -} - - -/* Helper to return the slot number for a given virtual reader index - VRDR. In case on an error -1 is returned. */ -static int -vreader_slot (int vrdr) -{ - if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table))) - return -1; - if (!vreader_table [vrdr].valid) - return -1; - return vreader_table[vrdr].slot; -} - - -/* Update the CARD_REMOVED element of all sessions using the virtual - reader given by VRDR to VALUE. */ -static void -update_card_removed (int vrdr, int value) -{ - struct server_local_s *sl; - - if (vrdr == -1) - return; - - for (sl=session_list; sl; sl = sl->next_session) - { - ctrl_t ctrl = sl->ctrl_backlink; - - if (ctrl && ctrl->server_local->vreader_idx == vrdr) - { - sl->card_removed = value; - if (value) - { - struct app_ctx_s *app = ctrl->app_ctx; - ctrl->app_ctx = NULL; - release_application (app); - } - } - } - - /* Let the card application layer know about the removal. */ - if (value) - { - int slot = vreader_slot (vrdr); - - log_debug ("Removal of a card: %d\n", vrdr); - apdu_close_reader (slot); - application_notify_card_reset (slot); - vreader_table[vrdr].slot = -1; - } -} - - /* Convert the STRING into a newly allocated buffer while translating the hex numbers. Stops at the first invalid character. Blanks and colons are allowed to separate the hex digits. Returns NULL on @@ -271,61 +142,10 @@ hex_to_buffer (const char *string, size_t *r_length) static void do_reset (ctrl_t ctrl, int send_reset) { - int vrdr = ctrl->server_local->vreader_idx; - int slot; - int err; - struct app_ctx_s *app = ctrl->app_ctx; + app_t app = ctrl->app_ctx; - if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table)))) - BUG (); - - /* If there is an active application, release it. */ if (app) - { - ctrl->app_ctx = NULL; - release_application (app); - } - - /* Release the same application which is used by other sessions. */ - if (send_reset) - { - struct server_local_s *sl; - - for (sl=session_list; sl; sl = sl->next_session) - { - ctrl_t c = sl->ctrl_backlink; - - if (c && c != ctrl && c->server_local->vreader_idx == vrdr) - { - struct app_ctx_s *app0 = c->app_ctx; - if (app0) - { - c->app_ctx = NULL; - release_application (app0); - } - } - } - } - - /* If we want a real reset for the card, send the reset APDU and - tell the application layer about it. */ - slot = vreader_slot (vrdr); - if (slot != -1 && send_reset && !IS_LOCKED (ctrl) ) - { - application_notify_card_reset (slot); - switch (apdu_reset (slot)) - { - case 0: - break; - case SW_HOST_NO_CARD: - case SW_HOST_CARD_INACTIVE: - break; - default: - apdu_close_reader (slot); - vreader_table[vrdr].slot = -1; - break; - } - } + app_reset (app, ctrl, IS_LOCKED (ctrl)? 0: send_reset); /* If we hold a lock, unlock now. */ if (locked_session && ctrl->server_local == locked_session) @@ -333,30 +153,7 @@ do_reset (ctrl_t ctrl, int send_reset) locked_session = NULL; log_info ("implicitly unlocking due to RESET\n"); } - - /* Reset the card removed flag for the current reader. We need to - take the lock here so that the ticker thread won't concurrently - try to update the file. Calling update_reader_status_file is - required to get hold of the new status of the card in the vreader - table. */ - err = npth_mutex_lock (&status_file_update_lock); - if (err) - { - log_error ("failed to acquire status_file_update lock\n"); - ctrl->server_local->vreader_idx = -1; - return; - } - update_reader_status_file (0); /* Update slot status table. */ - update_card_removed (vrdr, 0); /* Clear card_removed flag. */ - err = npth_mutex_unlock (&status_file_update_lock); - if (err) - log_error ("failed to release status_file_update lock: %s\n", - strerror (err)); - - /* Do this last, so that the update_card_removed above does its job. */ - ctrl->server_local->vreader_idx = -1; } - static gpg_error_t reset_notify (assuan_context_t ctx, char *line) @@ -394,51 +191,10 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) } -/* Return the index of the current reader or open the reader if no - other sessions are using that reader. If it is not possible to - open the reader -1 is returned. Note, that we currently support - only one reader but most of the code (except for this function) - should be able to cope with several readers. */ -static int -get_current_reader (void) -{ - struct vreader_s *vr; - - /* We only support one reader for now. */ - vr = &vreader_table[0]; - - /* Initialize the vreader item if not yet done. */ - if (!vr->valid) - { - vr->slot = -1; - vr->valid = 1; - } - - /* Try to open the reader. */ - if (vr->slot == -1) - { - vr->slot = apdu_open_reader (opt.reader_port); - - /* If we still don't have a slot, we have no readers. - Invalidate for now until a reader is attached. */ - if (vr->slot == -1) - { - vr->valid = 0; - } - } - - /* Return the vreader index or -1. */ - return vr->valid ? 0 : -1; -} - - /* If the card has not yet been opened, do it. */ static gpg_error_t -open_card (ctrl_t ctrl, const char *apptype) +open_card (ctrl_t ctrl) { - gpg_error_t err; - int vrdr; - /* If we ever got a card not present error code, return that. Only the SERIALNO command and a reset are able to clear from that state. */ @@ -448,56 +204,46 @@ open_card (ctrl_t ctrl, const char *apptype) if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); + if (ctrl->app_ctx) + return 0; + + return select_application (ctrl, NULL, &ctrl->app_ctx, 0, NULL, 0); +} + +/* Explicitly open a card for a specific use of APPTYPE or SERIALNO. */ +static gpg_error_t +open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno) +{ + gpg_error_t err; + unsigned char *serialno_bin = NULL; + size_t serialno_bin_len = 0; + /* If we are already initialized for one specific application we need to check that the client didn't requested a specific application different from the one in use before we continue. */ - if (ctrl->app_ctx) - { - return check_application_conflict - (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype); - } + if (apptype && ctrl->app_ctx) + return check_application_conflict (apptype, ctrl->app_ctx); - /* Setup the vreader and select the application. */ - if (ctrl->server_local->vreader_idx != -1) - vrdr = ctrl->server_local->vreader_idx; - else - vrdr = get_current_reader (); - ctrl->server_local->vreader_idx = vrdr; - if (vrdr == -1) - err = gpg_error (GPG_ERR_CARD); - else - { - /* Fixme: We should move the apdu_connect call to - select_application. */ - int sw; - int slot = vreader_slot (vrdr); - - ctrl->server_local->disconnect_allowed = 0; - sw = apdu_connect (slot); - if (sw && sw != SW_HOST_ALREADY_CONNECTED) - { - if (sw == SW_HOST_NO_CARD) - err = gpg_error (GPG_ERR_CARD_NOT_PRESENT); - else if (sw == SW_HOST_CARD_INACTIVE) - err = gpg_error (GPG_ERR_CARD_RESET); - else - err = gpg_error (GPG_ERR_ENODEV); - } - else - err = select_application (ctrl, slot, apptype, &ctrl->app_ctx); - } + if (serialno) + serialno_bin = hex_to_buffer (serialno, &serialno_bin_len); + + err = select_application (ctrl, apptype, &ctrl->app_ctx, 1, + serialno_bin, serialno_bin_len); + xfree (serialno_bin); - TEST_CARD_REMOVAL (ctrl, err); return err; } static const char hlp_serialno[] = - "SERIALNO [<apptype>]\n" + "SERIALNO [--demand=<serialno>] [<apptype>]\n" "\n" "Return the serial number of the card using a status response. This\n" "function should be used to check for the presence of a card.\n" "\n" + "If --demand is given, an application on the card with SERIALNO is\n" + "selected and an error is returned if no such card available.\n" + "\n" "If APPTYPE is given, an application of that type is selected and an\n" "error is returned if the application is not supported or available.\n" "The default is to auto-select the application using a hardwired\n" @@ -515,34 +261,51 @@ static gpg_error_t cmd_serialno (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); + struct server_local_s *sl; int rc = 0; char *serial; - time_t stamp; - int retries = 0; + const char *demand; + + if ( IS_LOCKED (ctrl) ) + return gpg_error (GPG_ERR_LOCKED); + + if ((demand = has_option_name (line, "--demand"))) + { + if (*demand != '=') + return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option"); + line = (char *)++demand; + for (; *line && !spacep (line); line++) + ; + if (*line) + *line++ = 0; + } + else + demand = NULL; /* Clear the remove flag so that the open_card is able to reread it. */ - retry: if (ctrl->server_local->card_removed) + ctrl->server_local->card_removed = 0; + + if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand))) { - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - do_reset (ctrl, 1); + ctrl->server_local->card_removed = 1; + return rc; } - if ((rc = open_card (ctrl, *line? line:NULL))) + /* Success, clear the card_removed flag for all sessions. */ + for (sl=session_list; sl; sl = sl->next_session) { - /* In case of an inactive card, retry once. */ - if (gpg_err_code (rc) == GPG_ERR_CARD_RESET && retries++ < 1) - goto retry; - return rc; + ctrl_t c = sl->ctrl_backlink; + + if (c != ctrl) + c->server_local->card_removed = 0; } - rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); - if (rc) - return rc; + serial = app_get_serialno (ctrl->app_ctx); + if (!serial) + return gpg_error (GPG_ERR_INV_VALUE); - rc = print_assuan_status (ctx, "SERIALNO", "%s %lu", - serial, (unsigned long)stamp); + rc = assuan_write_status (ctx, "SERIALNO", serial); xfree (serial); return rc; } @@ -555,7 +318,7 @@ static const char hlp_learn[] = "used without the force options, the command might do an INQUIRE\n" "like this:\n" "\n" - " INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>\n" + " INQUIRE KNOWNCARDP <hexstring_with_serialNumber>\n" "\n" "The client should just send an \"END\" if the processing should go on\n" "or a \"CANCEL\" to force the function to terminate with a Cancel\n" @@ -624,7 +387,7 @@ cmd_learn (assuan_context_t ctx, char *line) int rc = 0; int only_keypairinfo = has_option (line, "--keypairinfo"); - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; /* Unless the force option is used we try a shortcut by identifying @@ -633,24 +396,24 @@ cmd_learn (assuan_context_t ctx, char *line) knows about this card */ if (!only_keypairinfo) { - int slot; const char *reader; char *serial; - time_t stamp; + app_t app = ctrl->app_ctx; - slot = vreader_slot (ctrl->server_local->vreader_idx); - reader = apdu_get_reader_name (slot); + if (!app) + return gpg_error (GPG_ERR_CARD_NOT_PRESENT); + + reader = apdu_get_reader_name (app->slot); if (!reader) return out_of_core (); send_status_direct (ctrl, "READER", reader); /* No need to free the string of READER. */ - rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); - if (rc) - return rc; + serial = app_get_serialno (ctrl->app_ctx); + if (!serial) + return gpg_error (GPG_ERR_INV_VALUE); - rc = print_assuan_status (ctx, "SERIALNO", "%s %lu", - serial, (unsigned long)stamp); + rc = assuan_write_status (ctx, "SERIALNO", serial); if (rc < 0) { xfree (serial); @@ -661,8 +424,7 @@ cmd_learn (assuan_context_t ctx, char *line) { char *command; - rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu", - serial, (unsigned long)stamp); + rc = gpgrt_asprintf (&command, "KNOWNCARDP %s", serial); if (rc < 0) { xfree (serial); @@ -688,7 +450,6 @@ cmd_learn (assuan_context_t ctx, char *line) if (!rc) rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -706,11 +467,11 @@ cmd_readcert (assuan_context_t ctx, char *line) unsigned char *cert; size_t ncert; - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; line = xstrdup (line); /* Need a copy of the line. */ - rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert); + rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert); if (rc) log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); xfree (line); @@ -723,7 +484,6 @@ cmd_readcert (assuan_context_t ctx, char *line) return rc; } - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -749,7 +509,7 @@ cmd_readkey (assuan_context_t ctx, char *line) unsigned char *pk; size_t pklen; - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (has_option (line, "--advanced")) @@ -761,7 +521,7 @@ cmd_readkey (assuan_context_t ctx, char *line) /* If the application supports the READKEY function we use that. Otherwise we use the old way by extracting it from the certificate. */ - rc = app_readkey (ctrl->app_ctx, advanced, line, &pk, &pklen); + rc = app_readkey (ctrl->app_ctx, ctrl, advanced, line, &pk, &pklen); if (!rc) { /* Yeah, got that key - send it back. */ rc = assuan_send_data (ctx, pk, pklen); @@ -775,7 +535,7 @@ cmd_readkey (assuan_context_t ctx, char *line) log_error ("app_readkey failed: %s\n", gpg_strerror (rc)); else { - rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert); + rc = app_readcert (ctrl->app_ctx, ctrl, line, &cert, &ncert); if (rc) log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); } @@ -810,7 +570,6 @@ cmd_readkey (assuan_context_t ctx, char *line) leave: ksba_cert_release (kc); xfree (cert); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -972,10 +731,7 @@ cmd_pksign (assuan_context_t ctx, char *line) line = skip_options (line); - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; /* We have to use a copy of the key ID because the function may use @@ -985,7 +741,7 @@ cmd_pksign (assuan_context_t ctx, char *line) if (!keyidstr) return out_of_core (); - rc = app_sign (ctrl->app_ctx, + rc = app_sign (ctrl->app_ctx, ctrl, keyidstr, hash_algo, pin_cb, ctx, ctrl->in_data.value, ctrl->in_data.valuelen, @@ -1004,7 +760,6 @@ cmd_pksign (assuan_context_t ctx, char *line) return rc; /* that is already an assuan error code */ } - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1020,10 +775,7 @@ cmd_pkauth (assuan_context_t ctx, char *line) size_t outdatalen; char *keyidstr; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (!ctrl->app_ctx) @@ -1036,9 +788,7 @@ cmd_pkauth (assuan_context_t ctx, char *line) if (!keyidstr) return out_of_core (); - rc = app_auth (ctrl->app_ctx, - keyidstr, - pin_cb, ctx, + rc = app_auth (ctrl->app_ctx, ctrl, keyidstr, pin_cb, ctx, ctrl->in_data.value, ctrl->in_data.valuelen, &outdata, &outdatalen); xfree (keyidstr); @@ -1054,7 +804,6 @@ cmd_pkauth (assuan_context_t ctx, char *line) return rc; /* that is already an assuan error code */ } - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1071,18 +820,13 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) char *keyidstr; unsigned int infoflags; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; keyidstr = xtrystrdup (line); if (!keyidstr) return out_of_core (); - rc = app_decipher (ctrl->app_ctx, - keyidstr, - pin_cb, ctx, + rc = app_decipher (ctrl->app_ctx, ctrl, keyidstr, pin_cb, ctx, ctrl->in_data.value, ctrl->in_data.valuelen, &outdata, &outdatalen, &infoflags); @@ -1106,7 +850,6 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) return rc; /* that is already an assuan error code */ } - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1130,7 +873,7 @@ cmd_getattr (assuan_context_t ctx, char *line) int rc; const char *keyword; - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; keyword = line; @@ -1145,7 +888,6 @@ cmd_getattr (assuan_context_t ctx, char *line) is locked. */ rc = app_getattr (ctrl->app_ctx, ctrl, keyword); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1173,10 +915,7 @@ cmd_setattr (assuan_context_t ctx, char *orig_line) size_t nbytes; char *line, *linebuf; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; /* We need to use a copy of LINE, because PIN_CB uses the same @@ -1194,11 +933,10 @@ cmd_setattr (assuan_context_t ctx, char *orig_line) line++; nbytes = percent_plus_unescape_inplace (line, 0); - rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, + rc = app_setattr (ctrl->app_ctx, ctrl, keyword, pin_cb, ctx, (const unsigned char*)line, nbytes); xfree (linebuf); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1223,9 +961,6 @@ cmd_writecert (assuan_context_t ctx, char *line) unsigned char *certdata; size_t certdatalen; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - line = skip_options (line); if (!*line) @@ -1235,7 +970,7 @@ cmd_writecert (assuan_context_t ctx, char *line) line++; *line = 0; - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (!ctrl->app_ctx) @@ -1260,7 +995,6 @@ cmd_writecert (assuan_context_t ctx, char *line) xfree (certid); xfree (certdata); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1289,9 +1023,6 @@ cmd_writekey (assuan_context_t ctx, char *line) unsigned char *keydata; size_t keydatalen; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - line = skip_options (line); if (!*line) @@ -1301,7 +1032,7 @@ cmd_writekey (assuan_context_t ctx, char *line) line++; *line = 0; - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (!ctrl->app_ctx) @@ -1327,7 +1058,6 @@ cmd_writekey (assuan_context_t ctx, char *line) xfree (keyid); xfree (keydata); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1367,9 +1097,6 @@ cmd_genkey (assuan_context_t ctx, char *line) const char *s; time_t timestamp; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - force = has_option (line, "--force"); if ((s=has_option_name (line, "--timestamp"))) @@ -1392,7 +1119,7 @@ cmd_genkey (assuan_context_t ctx, char *line) line++; *line = 0; - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (!ctrl->app_ctx) @@ -1405,7 +1132,6 @@ cmd_genkey (assuan_context_t ctx, char *line) timestamp, pin_cb, ctx); xfree (keyno); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1431,7 +1157,7 @@ cmd_random (assuan_context_t ctx, char *line) "number of requested bytes missing"); nbytes = strtoul (line, NULL, 0); - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (!ctrl->app_ctx) @@ -1441,7 +1167,7 @@ cmd_random (assuan_context_t ctx, char *line) if (!buffer) return out_of_core (); - rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer); + rc = app_get_challenge (ctrl->app_ctx, ctrl, nbytes, buffer); if (!rc) { rc = assuan_send_data (ctx, buffer, nbytes); @@ -1450,7 +1176,6 @@ cmd_random (assuan_context_t ctx, char *line) } xfree (buffer); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1476,9 +1201,6 @@ cmd_passwd (assuan_context_t ctx, char *line) if (has_option (line, "--nullpin")) flags |= APP_CHANGE_FLAG_NULLPIN; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - line = skip_options (line); if (!*line) @@ -1488,7 +1210,7 @@ cmd_passwd (assuan_context_t ctx, char *line) line++; *line = 0; - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (!ctrl->app_ctx) @@ -1502,7 +1224,6 @@ cmd_passwd (assuan_context_t ctx, char *line) log_error ("command passwd failed: %s\n", gpg_strerror (rc)); xfree (chvnostr); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1546,10 +1267,7 @@ cmd_checkpin (assuan_context_t ctx, char *line) int rc; char *idstr; - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; if (!ctrl->app_ctx) @@ -1562,12 +1280,11 @@ cmd_checkpin (assuan_context_t ctx, char *line) if (!idstr) return out_of_core (); - rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx); + rc = app_check_pin (ctrl->app_ctx, ctrl, idstr, pin_cb, ctx); xfree (idstr); if (rc) log_error ("app_check_pin failed: %s\n", gpg_strerror (rc)); - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -1602,8 +1319,8 @@ cmd_lock (assuan_context_t ctx, char *line) { rc = 0; npth_sleep (1); /* Better implement an event mechanism. However, - for card operations this should be - sufficient. */ + for card operations this should be + sufficient. */ /* FIXME: Need to check that the connection is still alive. This can be done by issuing status messages. */ goto retry; @@ -1670,7 +1387,10 @@ static const char hlp_getinfo[] = "\n" "app_list - Return a list of supported applications. One\n" " application per line, fields delimited by colons,\n" - " first field is the name."; + " first field is the name.\n" + "\n" + "card_list - Return a list of serial numbers of active cards,\n" + " using a status response."; static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) { @@ -1700,20 +1420,13 @@ cmd_getinfo (assuan_context_t ctx, char *line) else if (!strcmp (line, "status")) { ctrl_t ctrl = assuan_get_pointer (ctx); - int vrdr = ctrl->server_local->vreader_idx; - char flag = 'r'; + char flag; - if (!ctrl->server_local->card_removed && vrdr != -1) - { - struct vreader_s *vr; - - if (!(vrdr >= 0 && vrdr < DIM(vreader_table))) - BUG (); + if (open_card (ctrl)) + flag = 'r'; + else + flag = 'u'; - vr = &vreader_table[vrdr]; - if (vr->valid && vr->any && (vr->status & 1)) - flag = 'u'; - } rc = assuan_send_data (ctx, &flag, 1); } else if (!strcmp (line, "reader_list")) @@ -1741,6 +1454,12 @@ cmd_getinfo (assuan_context_t ctx, char *line) rc = 0; xfree (s); } + else if (!strcmp (line, "card_list")) + { + ctrl_t ctrl = assuan_get_pointer (ctx); + + app_send_card_list (ctrl); + } else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); return rc; @@ -1761,7 +1480,7 @@ static gpg_error_t cmd_restart (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - struct app_ctx_s *app = ctrl->app_ctx; + app_t app = ctrl->app_ctx; (void)line; @@ -1782,8 +1501,7 @@ cmd_restart (assuan_context_t ctx, char *line) static const char hlp_disconnect[] = "DISCONNECT\n" "\n" - "Disconnect the card if it is not any longer used by other\n" - "connections and the backend supports a disconnect operation."; + "Disconnect the card if the backend supports a disconnect operation."; static gpg_error_t cmd_disconnect (assuan_context_t ctx, char *line) { @@ -1791,7 +1509,10 @@ cmd_disconnect (assuan_context_t ctx, char *line) (void)line; - ctrl->server_local->disconnect_allowed = 1; + if (!ctrl->app_ctx) + return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + + apdu_disconnect (ctrl->app_ctx->slot); return 0; } @@ -1820,6 +1541,7 @@ static gpg_error_t cmd_apdu (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); + app_t app; int rc; unsigned char *apdu; size_t apdulen; @@ -1827,7 +1549,6 @@ cmd_apdu (assuan_context_t ctx, char *line) int handle_more; const char *s; size_t exlen; - int slot; if (has_option (line, "--dump-atr")) with_atr = 2; @@ -1847,13 +1568,12 @@ cmd_apdu (assuan_context_t ctx, char *line) line = skip_options (line); - if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_LOCKED); - - if ((rc = open_card (ctrl, NULL))) + if ((rc = open_card (ctrl))) return rc; - slot = vreader_slot (ctrl->server_local->vreader_idx); + app = ctrl->app_ctx; + if (!app) + return gpg_error (GPG_ERR_CARD_NOT_PRESENT); if (with_atr) { @@ -1861,7 +1581,7 @@ cmd_apdu (assuan_context_t ctx, char *line) size_t atrlen; char hexbuf[400]; - atr = apdu_get_atr (slot, &atrlen); + atr = apdu_get_atr (app->slot, &atrlen); if (!atr || atrlen > sizeof hexbuf - 2 ) { rc = gpg_error (GPG_ERR_INV_CARD); @@ -1906,7 +1626,7 @@ cmd_apdu (assuan_context_t ctx, char *line) unsigned char *result = NULL; size_t resultlen; - rc = apdu_send_direct (slot, exlen, + rc = apdu_send_direct (app->slot, exlen, apdu, apdulen, handle_more, &result, &resultlen); if (rc) @@ -1920,7 +1640,6 @@ cmd_apdu (assuan_context_t ctx, char *line) xfree (apdu); leave: - TEST_CARD_REMOVAL (ctrl, rc); return rc; } @@ -2025,7 +1744,7 @@ scd_command_handler (ctrl_t ctrl, int fd) else { rc = assuan_init_socket_server (ctx, INT2FD(fd), - ASSUAN_SOCKET_SERVER_ACCEPTED); + ASSUAN_SOCKET_SERVER_ACCEPTED); } if (rc) { @@ -2050,10 +1769,6 @@ scd_command_handler (ctrl_t ctrl, int fd) ctrl->server_local->ctrl_backlink = ctrl; ctrl->server_local->assuan_ctx = ctx; - /* We open the reader right at startup so that the ticker is able to - update the status file. */ - ctrl->server_local->vreader_idx = get_current_reader (); - /* Command processing loop. */ for (;;) { @@ -2170,8 +1885,8 @@ send_status_direct (ctrl_t ctrl, const char *keyword, const char *args) /* Helper to send the clients a status change notification. */ -static void -send_client_notifications (void) +void +send_client_notifications (app_t app, int removal) { struct { pid_t pid; @@ -2186,211 +1901,75 @@ send_client_notifications (void) struct server_local_s *sl; for (sl=session_list; sl; sl = sl->next_session) - { - if (sl->event_signal && sl->assuan_ctx) - { - pid_t pid = assuan_get_pid (sl->assuan_ctx); + if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app) + { + pid_t pid; #ifdef HAVE_W32_SYSTEM - HANDLE handle = (void *)sl->event_signal; - - for (kidx=0; kidx < killidx; kidx++) - if (killed[kidx].pid == pid - && killed[kidx].handle == handle) - break; - if (kidx < killidx) - log_info ("event %lx (%p) already triggered for client %d\n", - sl->event_signal, handle, (int)pid); - else - { - log_info ("triggering event %lx (%p) for client %d\n", - sl->event_signal, handle, (int)pid); - if (!SetEvent (handle)) - log_error ("SetEvent(%lx) failed: %s\n", - sl->event_signal, w32_strerror (-1)); - if (killidx < DIM (killed)) - { - killed[killidx].pid = pid; - killed[killidx].handle = handle; - killidx++; - } - } -#else /*!HAVE_W32_SYSTEM*/ - int signo = sl->event_signal; - - if (pid != (pid_t)(-1) && pid && signo > 0) - { - for (kidx=0; kidx < killidx; kidx++) - if (killed[kidx].pid == pid - && killed[kidx].signo == signo) - break; - if (kidx < killidx) - log_info ("signal %d already sent to client %d\n", - signo, (int)pid); - else - { - log_info ("sending signal %d to client %d\n", - signo, (int)pid); - kill (pid, signo); - if (killidx < DIM (killed)) - { - killed[killidx].pid = pid; - killed[killidx].signo = signo; - killidx++; - } - } - } -#endif /*!HAVE_W32_SYSTEM*/ - } - } -} - - - -/* This is the core of scd_update_reader_status_file but the caller - needs to take care of the locking. */ -static void -update_reader_status_file (int set_card_removed_flag) -{ - int idx; - unsigned int status, changed; - - /* Note, that we only try to get the status, because it does not - make sense to wait here for a operation to complete. If we are - busy working with a card, delays in the status file update should - be acceptable. */ - for (idx=0; idx < DIM(vreader_table); idx++) - { - struct vreader_s *vr = vreader_table + idx; - struct server_local_s *sl; - int sw_apdu; + HANDLE handle; +#else + int signo; +#endif - if (!vr->valid || vr->slot == -1) - continue; /* Not valid or reader not yet open. */ + if (removal) + { + sl->ctrl_backlink->app_ctx = NULL; + sl->card_removed = 1; + release_application (app); + } - sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed); - if (sw_apdu == SW_HOST_NO_READER) - { - /* Most likely the _reader_ has been unplugged. */ - apdu_close_reader (vr->slot); - status = 0; - changed = vr->changed; - } - else if (sw_apdu) - { - /* Get status failed. Ignore that. */ + if (!sl->event_signal || !sl->assuan_ctx) continue; - } - if (!vr->any || vr->status != status || vr->changed != changed ) - { - char *fname; - char templ[50]; - FILE *fp; - - log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n", - idx, vr->slot, vr->status, status, vr->changed, changed); - vr->status = status; - vr->changed = changed; - - /* FIXME: Should this be IDX instead of vr->slot? This - depends on how client sessions will associate the reader - status with their session. */ - snprintf (templ, sizeof templ, "reader_%d.status", vr->slot); - fname = make_filename (gnupg_homedir (), templ, NULL ); - fp = fopen (fname, "w"); - if (fp) - { - fprintf (fp, "%s\n", - (status & 1)? "USABLE": - (status & 4)? "ACTIVE": - (status & 2)? "PRESENT": "NOCARD"); - fclose (fp); - } - xfree (fname); + pid = assuan_get_pid (sl->assuan_ctx); - /* If a status script is executable, run it. */ +#ifdef HAVE_W32_SYSTEM + handle = (void *)sl->event_signal; + for (kidx=0; kidx < killidx; kidx++) + if (killed[kidx].pid == pid + && killed[kidx].handle == handle) + break; + if (kidx < killidx) + log_info ("event %lx (%p) already triggered for client %d\n", + sl->event_signal, handle, (int)pid); + else { - const char *args[9], *envs[2]; - char numbuf1[30], numbuf2[30], numbuf3[30]; - char *homestr, *envstr; - gpg_error_t err; - - homestr = make_filename (gnupg_homedir (), NULL); - if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0) - log_error ("out of core while building environment\n"); - else + log_info ("triggering event %lx (%p) for client %d\n", + sl->event_signal, handle, (int)pid); + if (!SetEvent (handle)) + log_error ("SetEvent(%lx) failed: %s\n", + sl->event_signal, w32_strerror (-1)); + if (killidx < DIM (killed)) { - envs[0] = envstr; - envs[1] = NULL; - - sprintf (numbuf1, "%d", vr->slot); - sprintf (numbuf2, "0x%04X", vr->status); - sprintf (numbuf3, "0x%04X", status); - args[0] = "--reader-port"; - args[1] = numbuf1; - args[2] = "--old-code"; - args[3] = numbuf2; - args[4] = "--new-code"; - args[5] = numbuf3; - args[6] = "--status"; - args[7] = ((status & 1)? "USABLE": - (status & 4)? "ACTIVE": - (status & 2)? "PRESENT": "NOCARD"); - args[8] = NULL; - - fname = make_filename (gnupg_homedir (), "scd-event", NULL); - err = gnupg_spawn_process_detached (fname, args, envs); - if (err && gpg_err_code (err) != GPG_ERR_ENOENT) - log_error ("failed to run event handler '%s': %s\n", - fname, gpg_strerror (err)); - xfree (fname); - xfree (envstr); + killed[killidx].pid = pid; + killed[killidx].handle = handle; + killidx++; } - xfree (homestr); } +#else /*!HAVE_W32_SYSTEM*/ + signo = sl->event_signal; - /* Set the card removed flag for all current sessions. */ - if (vr->any && vr->status == 0 && set_card_removed_flag) - update_card_removed (idx, 1); - - vr->any = 1; - - /* Send a signal to all clients who applied for it. */ - send_client_notifications (); - } - - /* Check whether a disconnect is pending. */ - if (opt.card_timeout) - { - for (sl=session_list; sl; sl = sl->next_session) - if (!sl->disconnect_allowed) - break; - if (session_list && !sl) - { - /* FIXME: Use a real timeout. */ - /* At least one connection and all allow a disconnect. */ - log_info ("disconnecting card in reader %d (%d)\n", - idx, vr->slot); - apdu_disconnect (vr->slot); - } - } - - } -} - -/* This function is called by the ticker thread to check for changes - of the reader stati. It updates the reader status files and if - requested by the caller also send a signal to the caller. */ -void -scd_update_reader_status_file (void) -{ - int err; - err = npth_mutex_lock (&status_file_update_lock); - if (err) - return; /* locked - give up. */ - update_reader_status_file (1); - err = npth_mutex_unlock (&status_file_update_lock); - if (err) - log_error ("failed to release status_file_update lock: %s\n", - strerror (err)); + if (pid != (pid_t)(-1) && pid && signo > 0) + { + for (kidx=0; kidx < killidx; kidx++) + if (killed[kidx].pid == pid + && killed[kidx].signo == signo) + break; + if (kidx < killidx) + log_info ("signal %d already sent to client %d\n", + signo, (int)pid); + else + { + log_info ("sending signal %d to client %d\n", + signo, (int)pid); + kill (pid, signo); + if (killidx < DIM (killed)) + { + killed[killidx].pid = pid; + killed[killidx].signo = signo; + killidx++; + } + } + } +#endif /*!HAVE_W32_SYSTEM*/ + } } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 38e3c40..74fed44 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -640,7 +640,12 @@ main (int argc, char **argv ) set_debug (debug_level); - initialize_module_command (); + if (initialize_module_command ()) + { + log_error ("initialization failed\n"); + cleanup (); + exit (1); + } if (gpgconf_list == 2) scd_exit (0); diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 38aa490..d0bc98e 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -118,12 +118,13 @@ void scd_exit (int rc); const char *scd_get_socket_name (void); /*-- command.c --*/ -void initialize_module_command (void); +gpg_error_t initialize_module_command (void); int scd_command_handler (ctrl_t, int); void send_status_info (ctrl_t ctrl, const char *keyword, ...) GPGRT_ATTR_SENTINEL(1); void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args); void scd_update_reader_status_file (void); +void send_client_notifications (app_t app, int removal); #endif /*SCDAEMON_H*/ diff --git a/tests/Makefile.am b/tests/Makefile.am index c022e2a..bb75c97 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -18,7 +18,7 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = gpgscm openpgp migrations gpgme pkits . +SUBDIRS = gpgscm openpgp migrations gpgsm gpgme pkits . GPGSM = ../sm/gpgsm diff --git a/tests/gpgme/gpgme-defs.scm b/tests/gpgme/gpgme-defs.scm index 2490666..6e35285 100644 --- a/tests/gpgme/gpgme-defs.scm +++ b/tests/gpgme/gpgme-defs.scm @@ -83,31 +83,6 @@ (start-agent)) (apply create-gpgme-gpghome path))) -;; Command line flag handling. Returns the elements following KEY in -;; ARGUMENTS up to the next argument, or #f if KEY is not in -;; ARGUMENTS. -(define (flag key arguments) - (cond - ((null? arguments) - #f) - ((string=? key (car arguments)) - (let loop ((acc '()) - (args (cdr arguments))) - (if (or (null? args) (string-prefix? (car args) "--")) - (reverse acc) - (loop (cons (car args) acc) (cdr args))))) - ((string=? "--" (car arguments)) - #f) - (else - (flag key (cdr arguments))))) -(assert (equal? (flag "--xxx" '("--yyy")) #f)) -(assert (equal? (flag "--xxx" '("--xxx")) '())) -(assert (equal? (flag "--xxx" '("--xxx" "yyy")) '("yyy"))) -(assert (equal? (flag "--xxx" '("--xxx" "yyy" "zzz")) '("yyy" "zzz"))) -(assert (equal? (flag "--xxx" '("--xxx" "yyy" "zzz" "--")) '("yyy" "zzz"))) -(assert (equal? (flag "--xxx" '("--xxx" "yyy" "--" "zzz")) '("yyy"))) -(assert (equal? (flag "--" '("--" "xxx" "yyy" "--" "zzz")) '("xxx" "yyy"))) - (define (parse-makefile port key) (define (is-continuation? tokens) (string=? (last tokens) "\\")) diff --git a/tests/gpgscm/init.scm b/tests/gpgscm/init.scm index 106afd5..83261b0 100644 --- a/tests/gpgscm/init.scm +++ b/tests/gpgscm/init.scm @@ -569,6 +569,16 @@ ; the thrown exception is bound to *error*. Errors can be rethrown ; using (rethrow *error*). ; +; Finalization can be expressed using "finally": +; +; (finally (finalize-something called-purely-for side-effects) +; (whether-or-not something goes-wrong) +; (with-these calls)) +; +; The final expression is executed purely for its side-effects, +; both when the function exits successfully, and when an exception +; is thrown. +; ; Exceptions are thrown with: ; ; (throw "message") @@ -622,6 +632,13 @@ (pop-handler) ,label))))) +(define-macro (finally final-expression . expressions) + (let ((result (gensym))) + `(let ((,result (catch (begin ,final-expression (rethrow *error*)) + ,@expressions))) + ,final-expression + ,result))) + ;; Make the vm use throw'. (define *error-hook* throw') diff --git a/tests/gpgscm/scheme-private.h b/tests/gpgscm/scheme-private.h index 7f19a6e..aba2319 100644 --- a/tests/gpgscm/scheme-private.h +++ b/tests/gpgscm/scheme-private.h @@ -28,8 +28,8 @@ typedef struct port { FILE *file; int closeit; #if SHOW_ERROR_LINE - int curr_line; - char *filename; + pointer curr_line; + pointer filename; #endif } stdio; struct { diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c index a5b7691..c4725db 100644 --- a/tests/gpgscm/scheme.c +++ b/tests/gpgscm/scheme.c @@ -377,7 +377,7 @@ static int is_ascii_name(const char *name, int *pc) { #endif -static int file_push(scheme *sc, const char *fname); +static int file_push(scheme *sc, pointer fname); static void file_pop(scheme *sc); static int file_interactive(scheme *sc); static INLINE int is_one_of(char *s, int c); @@ -1552,6 +1552,15 @@ E2: setmark(p); mark(p+1+i); } } +#if SHOW_ERROR_LINE + else if (is_port(p)) { + port *pt = p->_object._port; + if (pt->kind & port_file) { + mark(pt->rep.stdio.curr_line); + mark(pt->rep.stdio.filename); + } + } +#endif /* Mark tag if p has one. */ if (has_tag(p)) mark(p + 1); @@ -1617,6 +1626,13 @@ static void gc(scheme *sc, pointer a, pointer b) { mark(sc->save_inport); mark(sc->outport); mark(sc->loadport); + for (i = 0; i <= sc->file_i; i++) { + if (! (sc->load_stack[i].kind & port_file)) + continue; + + mark(sc->load_stack[i].rep.stdio.filename); + mark(sc->load_stack[i].rep.stdio.curr_line); + } /* Mark recent objects the interpreter doesn't know about yet. */ mark(car(sc->sink)); @@ -1678,14 +1694,39 @@ static void finalize_cell(scheme *sc, pointer a) { } } +#if SHOW_ERROR_LINE +static void +port_clear_location (scheme *sc, port *p) +{ + assert(p->kind & port_file); + p->rep.stdio.curr_line = sc->NIL; + p->rep.stdio.filename = sc->NIL; +} + +static void +port_reset_current_line (scheme *sc, port *p) +{ + assert(p->kind & port_file); + p->rep.stdio.curr_line = mk_integer(sc, 0); +} + +static void +port_increment_current_line (scheme *sc, port *p, long delta) +{ + assert(p->kind & port_file); + p->rep.stdio.curr_line = + mk_integer(sc, ivalue_unchecked(p->rep.stdio.curr_line) + delta); +} +#endif + /* ========== Routines for Reading ========== */ -static int file_push(scheme *sc, const char *fname) { +static int file_push(scheme *sc, pointer fname) { FILE *fin = NULL; if (sc->file_i == MAXFIL-1) return 0; - fin=fopen(fname,"r"); + fin = fopen(string_value(fname), "r"); if(fin!=0) { sc->file_i++; sc->load_stack[sc->file_i].kind=port_file|port_input; @@ -1695,9 +1736,8 @@ static int file_push(scheme *sc, const char *fname) { sc->loadport->_object._port=sc->load_stack+sc->file_i; #if SHOW_ERROR_LINE - sc->load_stack[sc->file_i].rep.stdio.curr_line = 0; - if(fname) - sc->load_stack[sc->file_i].rep.stdio.filename = store_string(sc, strlen(fname), fname, 0); + port_reset_current_line(sc, &sc->load_stack[sc->file_i]); + sc->load_stack[sc->file_i].rep.stdio.filename = fname; #endif } return fin!=0; @@ -1707,6 +1747,10 @@ static void file_pop(scheme *sc) { if(sc->file_i != 0) { sc->nesting=sc->nesting_stack[sc->file_i]; port_close(sc,sc->loadport,port_input); +#if SHOW_ERROR_LINE + if (sc->load_stack[sc->file_i].kind & port_file) + port_clear_location(sc, &sc->load_stack[sc->file_i]); +#endif sc->file_i--; sc->loadport->_object._port=sc->load_stack+sc->file_i; } @@ -1736,10 +1780,12 @@ static port *port_rep_from_filename(scheme *sc, const char *fn, int prop) { pt->rep.stdio.closeit=1; #if SHOW_ERROR_LINE - if(fn) - pt->rep.stdio.filename = store_string(sc, strlen(fn), fn, 0); + if (fn) + pt->rep.stdio.filename = mk_string(sc, fn); + else + pt->rep.stdio.filename = mk_string(sc, "<unknown>"); - pt->rep.stdio.curr_line = 0; + port_reset_current_line(sc, pt); #endif return pt; } @@ -1764,6 +1810,10 @@ static port *port_rep_from_file(scheme *sc, FILE *f, int prop) pt->kind = port_file | prop; pt->rep.stdio.file = f; pt->rep.stdio.closeit = 0; +#if SHOW_ERROR_LINE + pt->rep.stdio.filename = mk_string(sc, "<unknown>"); + port_reset_current_line(sc, pt); +#endif return pt; } @@ -1837,10 +1887,7 @@ static void port_close(scheme *sc, pointer p, int flag) { #if SHOW_ERROR_LINE /* Cleanup is here so (close-*-port) functions could work too */ - pt->rep.stdio.curr_line = 0; - - if(pt->rep.stdio.filename) - sc->free(pt->rep.stdio.filename); + port_clear_location(sc, pt); #endif fclose(pt->rep.stdio.file); @@ -2119,8 +2166,11 @@ static INLINE int skipspace(scheme *sc) { /* record it */ #if SHOW_ERROR_LINE - if (sc->load_stack[sc->file_i].kind & port_file) - sc->load_stack[sc->file_i].rep.stdio.curr_line += curr_line; + { + port *p = &sc->load_stack[sc->file_i]; + if (p->kind & port_file) + port_increment_current_line(sc, p, curr_line); + } #endif if(c!=EOF) { @@ -2160,7 +2210,7 @@ static int token(scheme *sc) { #if SHOW_ERROR_LINE if(c == '\n' && sc->load_stack[sc->file_i].kind & port_file) - sc->load_stack[sc->file_i].rep.stdio.curr_line++; + port_increment_current_line(sc, &sc->load_stack[sc->file_i], 1); #endif if(c == EOF) @@ -2188,7 +2238,7 @@ static int token(scheme *sc) { #if SHOW_ERROR_LINE if(c == '\n' && sc->load_stack[sc->file_i].kind & port_file) - sc->load_stack[sc->file_i].rep.stdio.curr_line++; + port_increment_current_line(sc, &sc->load_stack[sc->file_i], 1); #endif if(c == EOF) @@ -2691,8 +2741,8 @@ static pointer _Error_1(scheme *sc, const char *s, pointer a) { fname = string_value(car(tag)); ln = ivalue_unchecked(cdr(tag)); } else { - fname = sc->load_stack[sc->file_i].rep.stdio.filename; - ln = sc->load_stack[sc->file_i].rep.stdio.curr_line; + fname = string_value(sc->load_stack[sc->file_i].rep.stdio.filename); + ln = ivalue_unchecked(sc->load_stack[sc->file_i].rep.stdio.curr_line); } /* should never happen */ @@ -3105,7 +3155,7 @@ static pointer opexe_0(scheme *sc, enum scheme_opcodes op) { fprintf(sc->outport->_object._port->rep.stdio.file, "Loading %s\n", strvalue(car(sc->args))); } - if (!file_push(sc,strvalue(car(sc->args)))) { + if (!file_push(sc, car(sc->args))) { Error_1(sc,"unable to open", car(sc->args)); } else @@ -3314,11 +3364,9 @@ static pointer opexe_0(scheme *sc, enum scheme_opcodes op) { } } if (x == sc->NIL) { - /*-- - * if (y != sc->NIL) { - * Error_0(sc,"too many arguments"); - * } - */ + if (y != sc->NIL) { + Error_0(sc, "too many arguments"); + } } else if (is_symbol(x)) new_slot_in_env(sc, x, y); else { @@ -4838,15 +4886,14 @@ static pointer opexe_5(scheme *sc, enum scheme_opcodes op) { } else { sc->nesting_stack[sc->file_i]++; #if USE_TAGS && SHOW_ERROR_LINE - { - const char *filename = + if (sc->load_stack[sc->file_i].kind & port_file) { + pointer filename = sc->load_stack[sc->file_i].rep.stdio.filename; - int lineno = + pointer lineno = sc->load_stack[sc->file_i].rep.stdio.curr_line; s_save(sc, OP_TAG_VALUE, - cons(sc, mk_string(sc, filename), - cons(sc, mk_integer(sc, lineno), sc->NIL)), + cons(sc, filename, cons(sc, lineno, sc->NIL)), sc->NIL); } #endif @@ -4917,7 +4964,8 @@ static pointer opexe_5(scheme *sc, enum scheme_opcodes op) { backchar(sc,c); #if SHOW_ERROR_LINE else if (sc->load_stack[sc->file_i].kind & port_file) - sc->load_stack[sc->file_i].rep.stdio.curr_line++; + port_increment_current_line(sc, + &sc->load_stack[sc->file_i], 1); #endif sc->nesting_stack[sc->file_i]--; s_return(sc,reverse_in_place(sc, sc->NIL, sc->args)); @@ -5583,10 +5631,6 @@ void scheme_set_external_data(scheme *sc, void *p) { void scheme_deinit(scheme *sc) { int i; -#if SHOW_ERROR_LINE - char *fname; -#endif - sc->oblist=sc->NIL; sc->global_env=sc->NIL; dump_stack_free(sc); @@ -5608,6 +5652,14 @@ void scheme_deinit(scheme *sc) { typeflag(sc->loadport) = T_ATOM; } sc->loadport=sc->NIL; + +#if SHOW_ERROR_LINE + for(i=0; i<=sc->file_i; i++) { + if (sc->load_stack[i].kind & port_file) + port_clear_location(sc, &sc->load_stack[i]); + } +#endif + sc->gc_verbose=0; gc(sc,sc->NIL,sc->NIL); @@ -5619,16 +5671,6 @@ void scheme_deinit(scheme *sc) { sc->free(sc->alloc_seg[i]); } sc->free(sc->strbuff); - -#if SHOW_ERROR_LINE - for(i=0; i<=sc->file_i; i++) { - if (sc->load_stack[i].kind & port_file) { - fname = sc->load_stack[i].rep.stdio.filename; - if(fname) - sc->free(fname); - } - } -#endif } void scheme_load_file(scheme *sc, FILE *fin) @@ -5647,11 +5689,11 @@ void scheme_load_named_file(scheme *sc, FILE *fin, const char *filename) { } #if SHOW_ERROR_LINE - sc->load_stack[0].rep.stdio.curr_line = 0; + port_reset_current_line(sc, &sc->load_stack[0]); if(fin!=stdin && filename) - sc->load_stack[0].rep.stdio.filename = store_string(sc, strlen(filename), filename, 0); + sc->load_stack[0].rep.stdio.filename = mk_string(sc, filename); else - sc->load_stack[0].rep.stdio.filename = NULL; + sc->load_stack[0].rep.stdio.filename = mk_string(sc, "<unknown>"); #endif sc->inport=sc->loadport; @@ -5663,8 +5705,7 @@ void scheme_load_named_file(scheme *sc, FILE *fin, const char *filename) { } #if SHOW_ERROR_LINE - sc->free(sc->load_stack[0].rep.stdio.filename); - sc->load_stack[0].rep.stdio.filename = NULL; + port_clear_location(sc, &sc->load_stack[0]); #endif } diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm index 7b8d489..e5858d9 100644 --- a/tests/gpgscm/tests.scm +++ b/tests/gpgscm/tests.scm @@ -244,27 +244,26 @@ ;; ;; Bind all variables given in <bindings> and initialize each of them ;; to the given initial value, and close them after evaluting <body>. -(macro (letfd form) - (let ((result-sym (gensym))) - `((lambda (,(caaadr form)) - (let ((,result-sym - ,(if (= 1 (length (cadr form))) - `(catch (begin (close ,(caaadr form)) - (rethrow *error*)) - ,@(cddr form)) - `(letfd ,(cdadr form) ,@(cddr form))))) - (close ,(caaadr form)) - ,result-sym)) ,@(cdaadr form)))) - -(macro (with-working-directory form) - (let ((result-sym (gensym)) (cwd-sym (gensym))) - `(let* ((,cwd-sym (getcwd)) - (_ (if ,(cadr form) (chdir ,(cadr form)))) - (,result-sym (catch (begin (chdir ,cwd-sym) - (rethrow *error*)) - ,@(cddr form)))) - (chdir ,cwd-sym) - ,result-sym))) +(define-macro (letfd bindings . body) + (let bind ((bindings' bindings)) + (if (null? bindings') + `(begin ,@body) + (let* ((binding (car bindings')) + (name (car binding)) + (initializer (cadr binding))) + `(let ((,name ,initializer)) + (finally (close ,name) + ,(bind (cdr bindings')))))))) + +(define-macro (with-working-directory new-directory . expressions) + (let ((new-dir (gensym)) + (old-dir (gensym))) + `(let* ((,new-dir ,new-directory) + (,old-dir (getcwd))) + (dynamic-wind + (lambda () (if ,new-dir (chdir ,new-dir))) + (lambda () ,@expressions) + (lambda () (chdir ,old-dir)))))) ;; Make a temporary directory. If arguments are given, they are ;; joined using path-join, and must end in a component ending in @@ -278,18 +277,12 @@ "-XXXXXX")) (apply path-join components)))) -(macro (with-temporary-working-directory form) - (let ((result-sym (gensym)) (cwd-sym (gensym)) (tmp-sym (gensym))) - `(let* ((,cwd-sym (getcwd)) - (,tmp-sym (mkdtemp)) - (_ (chdir ,tmp-sym)) - (,result-sym (catch (begin (chdir ,cwd-sym) - (unlink-recursively ,tmp-sym) - (rethrow *error*)) - ,@(cdr form)))) - (chdir ,cwd-sym) - (unlink-recursively ,tmp-sym) - ,result-sym))) +(define-macro (with-temporary-working-directory . expressions) + (let ((tmp-sym (gensym))) + `(let* ((,tmp-sym (mkdtemp))) + (finally (unlink-recursively ,tmp-sym) + (with-working-directory ,tmp-sym + ,@expressions))))) (define (make-temporary-file . args) (canonical-path (path-join @@ -310,17 +303,15 @@ ;; Bind all variables given in <bindings>, initialize each of them to ;; a string representing an unique path in the filesystem, and delete ;; them after evaluting <body>. -(macro (lettmp form) - (let ((result-sym (gensym))) - `((lambda (,(caadr form)) - (let ((,result-sym - ,(if (= 1 (length (cadr form))) - `(catch (begin (remove-temporary-file ,(caadr form)) - (rethrow *error*)) - ,@(cddr form)) - `(lettmp ,(cdadr form) ,@(cddr form))))) - (remove-temporary-file ,(caadr form)) - ,result-sym)) (make-temporary-file ,(symbol->string (caadr form)))))) +(define-macro (lettmp bindings . body) + (let bind ((bindings' bindings)) + (if (null? bindings') + `(begin ,@body) + (let ((name (car bindings')) + (rest (cdr bindings'))) + `(let ((,name (make-temporary-file ,(symbol->string name)))) + (finally (remove-temporary-file ,name) + ,(bind rest))))))) (define (check-execution source transformer) (lettmp (sink) @@ -619,7 +610,7 @@ (seek logfd 0 SEEK_SET) (splice logfd STDERR_FILENO) (close logfd)) - (echo (string-append (status retcode) ":") name)))))) + (echo (string-append (status) ":") name)))))) ;; Run the setup target to create an environment, then run all given ;; tests in parallel. @@ -658,3 +649,28 @@ (test' (test::set-directory wd))) (loop (pool::add (test'::run-sync '--unpack-tarball gpghome-tar)) (cdr tests'))))))) + +;; Command line flag handling. Returns the elements following KEY in +;; ARGUMENTS up to the next argument, or #f if KEY is not in +;; ARGUMENTS. +(define (flag key arguments) + (cond + ((null? arguments) + #f) + ((string=? key (car arguments)) + (let loop ((acc '()) + (args (cdr arguments))) + (if (or (null? args) (string-prefix? (car args) "--")) + (reverse acc) + (loop (cons (car args) acc) (cdr args))))) + ((string=? "--" (car arguments)) + #f) + (else + (flag key (cdr arguments))))) +(assert (equal? (flag "--xxx" '("--yyy")) #f)) +(assert (equal? (flag "--xxx" '("--xxx")) '())) +(assert (equal? (flag "--xxx" '("--xxx" "yyy")) '("yyy"))) +(assert (equal? (flag "--xxx" '("--xxx" "yyy" "zzz")) '("yyy" "zzz"))) +(assert (equal? (flag "--xxx" '("--xxx" "yyy" "zzz" "--")) '("yyy" "zzz"))) +(assert (equal? (flag "--xxx" '("--xxx" "yyy" "--" "zzz")) '("yyy"))) +(assert (equal? (flag "--" '("--" "xxx" "yyy" "--" "zzz")) '("xxx" "yyy"))) diff --git a/tests/gpgsm/32100C27173EF6E9C4E9A25D3D69F86D37A4F939 b/tests/gpgsm/32100C27173EF6E9C4E9A25D3D69F86D37A4F939 new file mode 100644 index 0000000..7aa9bfd --- /dev/null +++ b/tests/gpgsm/32100C27173EF6E9C4E9A25D3D69F86D37A4F939 @@ -0,0 +1,10 @@ +(private-key + (oid.1.2.840.113549.1.1.1 + (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#) + (e #010001#) + (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B117D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BDC543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#) + (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#) + (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f935a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#) + (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891eebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#) + ) +) diff --git a/tests/gpgsm/Makefile.am b/tests/gpgsm/Makefile.am new file mode 100644 index 0000000..aad328b --- /dev/null +++ b/tests/gpgsm/Makefile.am @@ -0,0 +1,78 @@ +# Makefile.am - For tests/gpgme +# Copyright (C) 2016 g10 Code GmbH +# +# 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 <https://www.gnu.org/licenses/>. +# Process this file with automake to create Makefile.in + + +# Programs required before we can run these tests. +required_pgms = ../../g10/gpg$(EXEEXT) ../../agent/gpg-agent$(EXEEXT) \ + ../../tools/gpg-connect-agent$(EXEEXT) \ + ../gpgscm/gpgscm$(EXEEXT) + +AM_CPPFLAGS = -I$(top_srcdir)/common +include $(top_srcdir)/am/cmacros.am + +AM_CFLAGS = + +TMP ?= /tmp + +TESTS_ENVIRONMENT = LC_ALL=C \ + EXEEXT=$(EXEEXT) \ + PATH=../gpgscm:$(PATH) \ + TMP=$(TMP) \ + srcdir=$(abs_srcdir) \ + objdir=$(abs_top_builddir) \ + GPGSCM_PATH=$(abs_top_srcdir)/tests/gpgscm:$(abs_top_srcdir)/tests/openpgp:$(abs_top_srcdir)/tests/gpgsm + +XTESTS = \ + import.scm \ + encrypt.scm \ + verify.scm \ + decrypt.scm \ + sign.scm \ + export.scm + +# XXX: Currently, one cannot override automake's 'check' target. As a +# workaround, we avoid defining 'TESTS', thus automake will not emit +# the 'check' target. For extra robustness, we merely define a +# dependency on 'xcheck', so this hack should also work even if +# automake would emit the 'check' target, as adding dependencies to +# targets is okay. +check: xcheck + +.PHONY: xcheck +xcheck: + $(TESTS_ENVIRONMENT) $(abs_top_builddir)/tests/gpgscm/gpgscm \ + $(abs_srcdir)/run-tests.scm $(TESTFLAGS) $(XTESTS) + +KEYS = 32100C27173EF6E9C4E9A25D3D69F86D37A4F939 +CERTS = cert_g10code_test1.der \ + cert_dfn_pca01.der \ + cert_dfn_pca15.der +TEST_FILES = plain-1.cms.asc \ + plain-2.cms.asc \ + plain-3.cms.asc \ + plain-large.cms.asc + +EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ + gpgsm-defs.scm run-tests.scm setup.scm + +CLEANFILES = *.log + +# We need to depend on a couple of programs so that the tests don't +# start before all programs are built. +all-local: $(required_pgms) diff --git a/tests/gpgsm/cert_dfn_pca01.der b/tests/gpgsm/cert_dfn_pca01.der Binary files differnew file mode 100644 index 0000000..4c8593c --- /dev/null +++ b/tests/gpgsm/cert_dfn_pca01.der diff --git a/tests/gpgsm/cert_dfn_pca15.der b/tests/gpgsm/cert_dfn_pca15.der Binary files differnew file mode 100644 index 0000000..c28f137 --- /dev/null +++ b/tests/gpgsm/cert_dfn_pca15.der diff --git a/tests/gpgsm/cert_g10code_test1.der b/tests/gpgsm/cert_g10code_test1.der Binary files differnew file mode 100644 index 0000000..67c7db6 --- /dev/null +++ b/tests/gpgsm/cert_g10code_test1.der diff --git a/tests/gpgsm/decrypt.scm b/tests/gpgsm/decrypt.scm new file mode 100644 index 0000000..e7f3baa --- /dev/null +++ b/tests/gpgsm/decrypt.scm @@ -0,0 +1,30 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) +(setup-gpgsm-environment) + +(for-each-p + "Checking decryption of supplied files." + (lambda (name) + (tr:do + (tr:open (in-srcdir (string-append name ".cms.asc"))) + (tr:gpgsm "" '(--decrypt)) + (tr:assert-identity name))) + plain-files) diff --git a/tests/gpgsm/encrypt.scm b/tests/gpgsm/encrypt.scm new file mode 100644 index 0000000..fd23ac5 --- /dev/null +++ b/tests/gpgsm/encrypt.scm @@ -0,0 +1,39 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) +(setup-gpgsm-environment) + +(for-each-p + "Checking encryption" + (lambda (source) + (for-each-p + "with arguments..." + (lambda (args) + (tr:do + (tr:open source) + (tr:gpgsm "" `(--encrypt --recipient ,certs::test-1::uid::CN + ,@args)) + (tr:gpgsm "" `(--decrypt ,@(if (member '--base64 args) + '(--assume-base64) '()))) + (tr:assert-identity source))) + `(() + (--armor --cipher-algo ,(cadr (force all-cipher-algos))) + (--base64 --digest-algo ,(car (force all-hash-algos)))))) + all-files) diff --git a/tests/gpgsm/export.scm b/tests/gpgsm/export.scm new file mode 100644 index 0000000..1ee91e4 --- /dev/null +++ b/tests/gpgsm/export.scm @@ -0,0 +1,32 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) +(setup-gpgsm-environment) + +(for-each-p' + "Checking certificate export." + (lambda (cert) + (lettmp (exported) + (call-check `(,@gpgsm --output ,exported --export ,cert::uid::CN)) + (with-ephemeral-home-directory + (call-check `(,@gpgsm --import ,exported)) + (assert (sm-have-public-key? cert))))) + (lambda (cert) cert::uid::CN) + all-certs) diff --git a/tests/gpgsm/gpgsm-defs.scm b/tests/gpgsm/gpgsm-defs.scm new file mode 100644 index 0000000..aa5af3d --- /dev/null +++ b/tests/gpgsm/gpgsm-defs.scm @@ -0,0 +1,103 @@ +;; Common definitions for the GPGSM test scripts. +;; +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "defs.scm")) + +;; This is the list of certificates that we install in the test +;; environment. +(define certs + (package + (define (new fpr issuer-fpr uid) + (package)) + (define (new-uid CN OU O L C) + (package)) + (define test-1 (new "3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E" + "3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E" + (new-uid "test cert 1" + "Aegypten Project" + "g10 Code GmbH" + "Düsseldorf" + "DE"))))) +(define all-certs (list certs::test-1)) + +(define gpgsm `(,(tool 'gpgsm) --yes)) ;; more/less options + +(define (tr:gpgsm input args) + (tr:spawn input `(,@gpgsm --output **out** ,@args **in**))) + +(define (pipe:gpgsm args) + (pipe:spawn `(,@gpgsm --output - ,@args -))) + +(define (gpgsm-with-colons args) + (let ((s (call-popen `(,@gpgsm --with-colons ,@args) ""))) + (map (lambda (line) (string-split line #\:)) + (string-split-newlines s)))) + +(define (sm-have-public-key? key) + (catch #f + (pair? (filter (lambda (l) (and (equal? 'fpr (:type l)) + (equal? key::fpr (:fpr l)))) + (gpgsm-with-colons `(--list-keys ,key::fpr)))))) + +(define (sm-have-secret-key? key) + (catch #f + (pair? (filter (lambda (l) (and (equal? 'fpr (:type l)) + (equal? key::fpr (:fpr l)))) + (gpgsm-with-colons `(--list-secret-keys ,key::fpr)))))) + +(define (create-file name . lines) + (letfd ((fd (open name (logior O_WRONLY O_CREAT O_BINARY) #o600))) + (let ((port (fdopen fd "wb"))) + (for-each (lambda (line) (display line port) (newline port)) + lines)))) + +(define (create-gpgsmhome) + (create-file "gpgsm.conf" + "disable-crl-checks" + "faked-system-time 1008241200") + (create-file "gpg-agent.conf" + (string-append "pinentry-program " (tool 'pinentry))) + (create-file + "trustlist.txt" + "32100C27173EF6E9C4E9A25D3D69F86D37A4F939" + "# CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE" + "3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E S") + + (log "Storing private keys") + (mkdir "private-keys-v1.d" "-rwx") + (for-each + (lambda (name) + (file-copy (in-srcdir name) + (path-join "private-keys-v1.d" + (string-append name ".key")))) + '("32100C27173EF6E9C4E9A25D3D69F86D37A4F939")) + + (log "Importing public demo and test keys") + (call-check `(,@gpgsm --import ,(in-srcdir "cert_g10code_test1.der"))) + + (create-sample-files) + (stop-agent)) + +;; Initialize the test environment, install appropriate configuration +;; and start the agent, with the keys from the legacy test suite. +(define (setup-gpgsm-environment) + (if (member "--unpack-tarball" *args*) + (call-check `(,(tool 'gpgtar) --extract --directory=. ,(cadr *args*))) + (create-gpgsm-gpghome)) + (start-agent)) diff --git a/tests/gpgsm/import.scm b/tests/gpgsm/import.scm new file mode 100644 index 0000000..85e5107 --- /dev/null +++ b/tests/gpgsm/import.scm @@ -0,0 +1,53 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) +(setup-gpgsm-environment) + +(define certs-for-import + (list (list "cert_dfn_pca01.der" + (certs::new + "DFA56FB5FC41E3A8921F77AD1622EEFD9152A5AD" + "DFA56FB5FC41E3A8921F77AD1622EEFD9152A5AD" + (certs::new-uid "DFN Top Level Certification Authority" + "DFN-PCA" + "Deutsches Forschungsnetz" + "" + "DE"))) + (list "cert_dfn_pca15.der" + (certs::new + "2C8F3C356AB761CB3674835B792CDA52937F9285" + "DFA56FB5FC41E3A8921F77AD1622EEFD9152A5AD" + (certs::new-uid "DFN Server Certification Authority" + "DFN-PCA" + "Deutsches Forschungsnetz" + "" + "DE"))))) + +(define :name car) +(define :cert cadr) + +(for-each-p' + "Checking certificate import." + (lambda (test) + (assert (not (sm-have-public-key? (:cert test)))) + (call-check `(,@gpgsm --import ,(in-srcdir (:name test)))) + (assert (sm-have-public-key? (:cert test)))) + (lambda (test) (:name test)) + certs-for-import) diff --git a/tests/gpgsm/plain-1.cms.asc b/tests/gpgsm/plain-1.cms.asc new file mode 100644 index 0000000..cb1a4db --- /dev/null +++ b/tests/gpgsm/plain-1.cms.asc @@ -0,0 +1,33 @@ +-----BEGIN ENCRYPTED MESSAGE----- +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 +-----END ENCRYPTED MESSAGE----- diff --git a/tests/gpgsm/plain-2.cms.asc b/tests/gpgsm/plain-2.cms.asc new file mode 100644 index 0000000..1ff0a8f --- /dev/null +++ b/tests/gpgsm/plain-2.cms.asc @@ -0,0 +1,43 @@ +-----BEGIN ENCRYPTED MESSAGE----- +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 +AA== +-----END ENCRYPTED MESSAGE----- diff --git a/tests/gpgsm/plain-3.cms.asc b/tests/gpgsm/plain-3.cms.asc new file mode 100644 index 0000000..5c6331c --- /dev/null +++ b/tests/gpgsm/plain-3.cms.asc @@ -0,0 +1,11 @@ +-----BEGIN ENCRYPTED MESSAGE----- +MIAGCSqGSIb3DQEHA6CAMIACAQAxggELMIIBBwIBADBwMGsxCzAJBgNVBAYTAkRF +MRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRkw +FwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNlcnQgMQIB +ADANBgkqhkiG9w0BAQEFAASBgB8adQNvg/lKghatZ/Wy+tMUrarqYmTHB3SDKoDh +B+riZDDxj/j/xR6utjmukvrAz6gz3BzKxU+AjAmXLpNesN1kv+oDS2DmAluFzg5e +j/Ppo+Dudq2uJjZOsMry6xniMIwOhHsLhkLs2cuEb0eB6XAVfMzJvdTawuLaMeLN +fGmVMIAGCSqGSIb3DQEHATAdBglghkgBZQMEAQIEECIzN1lVNsKXkPAEySzCpUWg +gAQgzfoRhxREyicy4Vf6dfDJ+X4kaB4tGwsKGKYVV1uITjEEEFpk2DxEsIIxH66o +pfqG9W4AAAAAAAAAAAAA +-----END ENCRYPTED MESSAGE----- diff --git a/tests/gpgsm/plain-large.cms.asc b/tests/gpgsm/plain-large.cms.asc new file mode 100644 index 0000000..f8fc90f --- /dev/null +++ b/tests/gpgsm/plain-large.cms.asc @@ -0,0 +1,4213 @@ +-----BEGIN ENCRYPTED MESSAGE----- +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 +AAAAAAA= +-----END ENCRYPTED MESSAGE----- diff --git a/tests/gpgsm/run-tests.scm b/tests/gpgsm/run-tests.scm new file mode 100644 index 0000000..dfd5b02 --- /dev/null +++ b/tests/gpgsm/run-tests.scm @@ -0,0 +1,32 @@ +;; Test-suite runner. +;; +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(if (string=? "" (getenv "srcdir")) + (begin + (echo "Environment variable 'srcdir' not set. Please point it to" + "tests/openpgp.") + (exit 2))) + +(let* ((tests (filter (lambda (arg) (not (string-prefix? arg "--"))) *args*)) + (runner (if (and (member "--parallel" *args*) + (> (length tests) 1)) + run-tests-parallel + run-tests-sequential))) + (runner (test::scm "setup.scm" "setup.scm") + (map (lambda (t) (test::scm t t)) tests))) diff --git a/tests/gpgsm/setup.scm b/tests/gpgsm/setup.scm new file mode 100644 index 0000000..91821a0 --- /dev/null +++ b/tests/gpgsm/setup.scm @@ -0,0 +1,30 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) + +(define tarball (flag "--create-tarball" *args*)) +(unless (and tarball (not (null? tarball))) + (error "Usage: setup.scm --create-tarball <file> ...")) + +(with-ephemeral-home-directory + (chdir (getenv "GNUPGHOME")) + (create-gpgsmhome) + (stop-agent) + (call-check `(,(tool 'gpgtar) --create --output ,(car tarball) "."))) diff --git a/tests/gpgsm/shell.scm b/tests/gpgsm/shell.scm new file mode 100644 index 0000000..fe39fec --- /dev/null +++ b/tests/gpgsm/shell.scm @@ -0,0 +1,30 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) +(setup-gpgsm-environment) + +;; This is not a test, but can be used to inspect the test +;; environment. Simply execute +;; +;; make -Ctests/gpgsm check XTESTS=shell.scm +;; +;; to run it. + +(interactive-shell) diff --git a/tests/gpgsm/sign.scm b/tests/gpgsm/sign.scm new file mode 100644 index 0000000..9b4f7fe --- /dev/null +++ b/tests/gpgsm/sign.scm @@ -0,0 +1,35 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) +(setup-gpgsm-environment) + +(for-each-p + "Checking signing." + (lambda (source) + (for-each-p + "with digest..." + (lambda (digest) + (tr:do + (tr:open source) + (tr:gpgsm "" `(--sign --digest-algo ,digest)) + (tr:gpgsm "" '(--verify)) + (tr:assert-identity source))) + (force all-hash-algos))) + all-files) diff --git a/tests/gpgsm/verify.scm b/tests/gpgsm/verify.scm new file mode 100644 index 0000000..894c827 --- /dev/null +++ b/tests/gpgsm/verify.scm @@ -0,0 +1,65 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2016 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "gpgsm-defs.scm")) +(setup-gpgsm-environment) + +;; +;; Two simple tests to check that verify fails for bad input data +;; +(for-each-p + "Checking bogus signature." + (lambda (char) + (lettmp (x) + (call-with-binary-output-file + x + (lambda (port) + (display (make-string 64 (integer->char (string->number char))) + port))) + (assert (not (zero? (call `(,@gpgsm --verify ,x data-500))))))) + '("#x2d" "#xca")) + +(define test-text1 "Hallo Leute!\n") +(define test-text1f "Hallo Leute?\n") +(define test-sig1 " +-----BEGIN CMS OBJECT----- +MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAA +MYIBOTCCATUCAQEwcDBrMQswCQYDVQQGEwJERTETMBEGA1UEBxQKRPxzc2VsZG9y +ZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEZMBcGA1UECxMQQWVneXB0ZW4gUHJv +amVjdDEUMBIGA1UEAxMLdGVzdCBjZXJ0IDECAQAwBwYFKw4DAhqgJTAjBgkqhkiG +9w0BCQQxFgQU7FC/ibH3lC9GE24RJJxa8zqP7wEwCwYJKoZIhvcNAQEBBIGAA3oC +DUmKERmD1eoJYFw38y/qnncS/6ZPjWINDIphZeK8mzAANpvpIaRPf3sNBznb89QF +mRgCXIWcjlHT0DTRLBf192Ve22IyKH00L52CqFsSN3a2sajqRUlXH8RY2D+Al71e +MYdRclgjObCcoilA8fZ13VR4DiMJVFCxJL4qVWI= +-----END CMS OBJECT-----") + +;; +;; Now run the tests. +;; +(info "Checking that a valid signature is verified as such.") +(lettmp (sig body) + (with-output-to-file sig (lambda () (display test-sig1))) + (with-output-to-file body (lambda () (display test-text1))) + (call-check `(,@gpgsm --verify ,sig ,body))) + +(info "Checking that an invalid signature is verified as such.") +(lettmp (sig body) + (with-output-to-file sig (lambda () (display test-sig1))) + (with-output-to-file body (lambda () (display test-text1f))) + (assert (not (zero? (call `(,@gpgsm --verify ,sig ,body)))))) diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 0670531..05341fb 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -50,6 +50,7 @@ XTESTS = \ decrypt.scm \ decrypt-multifile.scm \ decrypt-dsa.scm \ + decrypt-session-key.scm \ sigs.scm \ sigs-dsa.scm \ encrypt.scm \ @@ -96,6 +97,10 @@ XTESTS = \ issue2417.scm \ issue2419.scm +# Fixme: gpgconf.scm does not yet work with make distcheck. +# gpgconf.scm + + # XXX: Currently, one cannot override automake's 'check' target. As a # workaround, we avoid defining 'TESTS', thus automake will not emit # the 'check' target. For extra robustness, we merely define a @@ -111,7 +116,7 @@ xcheck: TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \ plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \ - plain-largeo.asc \ + plain-largeo.asc plain-large.asc \ pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc \ gpg.conf.tmpl gpg-agent.conf.tmpl \ bug537-test.data.asc bug894-test.asc \ diff --git a/tests/openpgp/decrypt-session-key.scm b/tests/openpgp/decrypt-session-key.scm new file mode 100755 index 0000000..771b53d --- /dev/null +++ b/tests/openpgp/decrypt-session-key.scm @@ -0,0 +1,45 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2017 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "defs.scm")) +(setup-legacy-environment) + +(define (get-session-key filename) + (lettmp (sink) + (let* ((status' (call-popen `(,@gpg --status-fd=1 --decrypt + --show-session-key + --output ,sink ,filename) "")) + (status (map (lambda (l) + (assert (string-prefix? l "[GNUPG:] ")) + (string-splitp (substring l 9 (string-length l)) + char-whitespace? -1)) + (string-split-newlines status')))) + (cadr (assoc "SESSION_KEY" status))))) + +(for-each-p + "Checking decryption of supplied files using the session key." + (lambda (name) + (let* ((source (in-srcdir (string-append name ".asc"))) + (key (get-session-key source))) + (with-ephemeral-home-directory + (tr:do + (tr:open source) + (tr:gpg "" `(--yes --decrypt --override-session-key ,key)) + (tr:assert-identity name))))) + plain-files) diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index 7867080..1d8173d 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -1,6 +1,6 @@ ;; Common definitions for the OpenPGP test scripts. ;; -;; Copyright (C) 2016 g10 Code GmbH +;; Copyright (C) 2016, 2017 g10 Code GmbH ;; ;; This file is part of GnuPG. ;; @@ -63,9 +63,10 @@ (define key-file1 "samplekeys/rsa-rsa-sample-1.asc") (define key-file2 "samplekeys/ed25519-cv25519-sample-1.asc") -(define plain-files '("plain-1" "plain-2" "plain-3")) +(define plain-files '("plain-1" "plain-2" "plain-3" "plain-large")) (define data-files '("data-500" "data-9000" "data-32000" "data-80000")) (define exp-files '()) +(define all-files (append plain-files data-files)) (let ((verbose (string->number (getenv "verbose")))) (if (number? verbose) @@ -80,6 +81,36 @@ default value))) +(define (percent-decode s) + (define (decode c) + (if (and (> (length c) 2) (char=? #\% (car c))) + (integer->char (string->number (string #\# #\x (cadr c) (caddr c)))) + #f)) + (let loop ((i 0) (c (string->list s)) (r (make-string (string-length s)))) + (if (null? c) + (substring r 0 i) + (let ((decoded (decode c))) + (string-set! r i (if decoded decoded (car c))) + (loop (+ 1 i) (if decoded (cdddr c) (cdr c)) r))))) +(assert (equal? (percent-decode "") "")) +(assert (equal? (percent-decode "%61") "a")) +(assert (equal? (percent-decode "foob%61r") "foobar")) + +(define (percent-encode s) + (define (encode c) + `(#\% ,@(string->list (number->string (char->integer c) 16)))) + (let loop ((acc '()) (cs (reverse (string->list s)))) + (if (null? cs) + (list->string acc) + (case (car cs) + ((#\: #\%) + (loop (append (encode (car cs)) acc) (cdr cs))) + (else + (loop (cons (car cs) acc) (cdr cs))))))) +(assert (equal? (percent-encode "") "")) +(assert (equal? (percent-encode "%61") "%2561")) +(assert (equal? (percent-encode "foob%61r") "foob%2561r")) + (define tools '((gpgv "GPGV" "g10/gpgv") (gpg-connect-agent "GPG_CONNECT_AGENT" "tools/gpg-connect-agent") @@ -90,25 +121,53 @@ (gpg-zip "GPGZIP" "tools/gpg-zip") (pinentry "PINENTRY" "tests/openpgp/fake-pinentry"))) +(define bin-prefix (getenv "BIN_PREFIX")) +(define installed? (not (string=? "" bin-prefix))) + (define (tool-hardcoded which) - (let ((t (assoc which tools)) - (prefix (getenv "BIN_PREFIX"))) + (let ((t (assoc which tools))) (getenv' (cadr t) - (qualify (if (string=? prefix "") - (string-append (getenv "objdir") "/" (caddr t)) - (string-append prefix "/" (basename (caddr t)))))))) + (qualify (if installed? + (string-append bin-prefix "/" (basename (caddr t))) + (string-append (getenv "objdir") "/" (caddr t))))))) + +;; You can splice VALGRIND into your argument vector to run programs +;; under valgrind. For example, to run valgrind on gpg, you may want +;; to redefine gpg: +;; +;; (set! gpg `(,@valgrind ,@gpg)) +;; +(define valgrind + '("/usr/bin/valgrind" --leak-check=full --error-exitcode=154)) (define (gpg-conf . args) - (let ((s (call-popen `(,(tool-hardcoded 'gpgconf) ,@args) ""))) - (map (lambda (line) (string-split line #\:)) + (gpg-conf' "" args)) +(define (gpg-conf' input args) + (let ((s (call-popen `(,(tool-hardcoded 'gpgconf) ,@args) input))) + (map (lambda (line) (map percent-decode (string-split line #\:))) (string-split-newlines s)))) (define :gc:c:name car) (define :gc:c:description cadr) (define :gc:c:pgmname caddr) -(setenv "GNUPG_BUILDDIR" (getenv "objdir") #t) -(define gpg-components (gpg-conf '--build-prefix (getenv "objdir") - '--list-components)) +(define (gpg-config component key) + (package + (define (value) + (assoc key (gpg-conf '--list-options component))) + (define (update value) + (gpg-conf' (string-append key ":0:" (percent-encode value)) + `(--change-options ,component))) + (define (clear) + (gpg-conf' (string-append key ":16:") + `(--change-options ,component))))) + + +(unless installed? + (setenv "GNUPG_BUILDDIR" (getenv "objdir") #t)) +(define gpg-components (apply gpg-conf + `(,@(if installed? '() + (list '--build-prefix (getenv "objdir"))) + --list-components))) (define (tool which) (case which @@ -194,11 +253,25 @@ (setenv "GPG_AGENT_INFO" "" #t) (setenv "GNUPGHOME" (getcwd) #t) +(define GNUPGHOME (getcwd)) ;; ;; GnuPG helper. ;; +;; Evaluate a sequence of expressions with an ephemeral home +;; directory. +(define-macro (with-ephemeral-home-directory . expressions) + (let ((original-home-directory (gensym)) + (ephemeral-home-directory (gensym))) + `(let ((,original-home-directory (getenv "GNUPGHOME")) + (,ephemeral-home-directory (mkdtemp))) + (finally (unlink-recursively ,ephemeral-home-directory) + (dynamic-wind + (lambda () (setenv "GNUPGHOME" ,ephemeral-home-directory #t)) + (lambda () ,@expressions) + (lambda () (setenv "GNUPGHOME" ,original-home-directory #t))))))) + ;; Call GPG to obtain the hash sums. Either specify an input file in ;; ARGS, or an string in INPUT. Returns a list of (<algo> ;; "<hashsum>") lists. @@ -256,7 +329,7 @@ (create-gpghome) (start-agent)) -(define (create-legacy-gpghome) +(define (create-sample-files) (log "Creating sample data files") (for-each (lambda (size) @@ -267,9 +340,11 @@ (log "Unpacking samples") (for-each (lambda (name) - (dearmor (in-srcdir (string-append name "o.asc")) name)) - '("plain-1" "plain-2" "plain-3" "plain-large")) + (dearmor (in-srcdir ".." "openpgp" (string-append name "o.asc")) name)) + plain-files)) +(define (create-legacy-gpghome) + (create-sample-files) (mkdir "private-keys-v1.d" "-rwx") (log "Storing private keys") diff --git a/tests/openpgp/gpgconf.scm b/tests/openpgp/gpgconf.scm new file mode 100644 index 0000000..b4cc9cb --- /dev/null +++ b/tests/openpgp/gpgconf.scm @@ -0,0 +1,51 @@ +#!/usr/bin/env gpgscm + +;; Copyright (C) 2017 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, see <http://www.gnu.org/licenses/>. + +(load (with-path "defs.scm")) +(setup-environment) + +(for-each-p' + "Checking reading and writing configuration via gpgconf... " + (lambda (name opt make-value) + (call-with-progress + "" + (lambda (progress) + (do ((i 0 (+ 1 i))) ((> i 12) #t) + (let ((value (make-value i))) + (if value + (begin + (opt::update value) + (assert (string=? value (list-ref (opt::value) 9)))) + (begin + (opt::clear) + (let ((v (opt::value))) + (assert (or (< (length v) 10) + (string=? "" (list-ref v 9)))))))) + (progress "."))))) + (lambda (name . rest) name) + (list "keyserver" "verbose" "quiet") + (list (gpg-config 'gpg "keyserver") + (gpg-config 'gpg "verbose") + (gpg-config 'gpg "quiet")) + (list (lambda (i) (if (even? i) "\"hkp://foo.bar" "\"hkps://bar.baz")) + (lambda (i) (number->string + ;; gpgconf: argument for option verbose of type 0 + ;; (none) must be positive + (+ 1 i))) + (lambda (i) (if (even? i) #f "1")))) diff --git a/tests/openpgp/plain-large.asc b/tests/openpgp/plain-large.asc new file mode 100644 index 0000000..d81b331 --- /dev/null +++ b/tests/openpgp/plain-large.asc @@ -0,0 +1,1332 @@ +-----BEGIN PGP MESSAGE----- + +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 +=3L8L +-----END PGP MESSAGE----- diff --git a/tests/openpgp/setup.scm b/tests/openpgp/setup.scm index fc0615f..d13799d 100755 --- a/tests/openpgp/setup.scm +++ b/tests/openpgp/setup.scm @@ -22,8 +22,8 @@ (unless (member "--create-tarball" *args*) (fail "Usage: setup.scm --create-tarball <file>")) -(with-temporary-working-directory - (setenv "GNUPGHOME" (getcwd) #t) +(with-ephemeral-home-directory + (chdir (getenv "GNUPGHOME")) (create-gpghome) (create-legacy-gpghome) (stop-agent) diff --git a/tests/openpgp/ssh-import.scm b/tests/openpgp/ssh-import.scm index e8f12d3..ad5acc5 100755 --- a/tests/openpgp/ssh-import.scm +++ b/tests/openpgp/ssh-import.scm @@ -20,10 +20,6 @@ (load (with-path "defs.scm")) (setup-environment) -(define GNUPGHOME (getenv "GNUPGHOME")) -(if (string=? "" GNUPGHOME) - (fail "GNUPGHOME not set")) - (setenv "SSH_AUTH_SOCK" (call-check `(,(tool 'gpgconf) --null --list-dirs agent-ssh-socket)) #t) @@ -55,7 +51,7 @@ car keys) (info "Checking for issue2316...") -(unlink (string-append GNUPGHOME "/sshcontrol")) +(unlink (path-join GNUPGHOME "sshcontrol")) (pipe:do (pipe:open (path-join (in-srcdir "samplekeys") (string-append "ssh-rsa.key")) diff --git a/tests/openpgp/tofu.scm b/tests/openpgp/tofu.scm index 20c130a..ca5786b 100755 --- a/tests/openpgp/tofu.scm +++ b/tests/openpgp/tofu.scm @@ -29,10 +29,7 @@ (define (days->seconds days) (* days 24 60 60)) ;; Redefine GPG without --always-trust and a fixed time. -(define GPG `(,(tool 'gpg) --no-permission-warning ,(faketime GPGTIME))) -(define GNUPGHOME (getenv "GNUPGHOME")) -(if (string=? "" GNUPGHOME) - (fail "GNUPGHOME not set")) +(define GPG `(,(tool 'gpg) --no-permission-warning ,(faketime 0))) (catch (skip "Tofu not supported") (call-check `(,@GPG --trust-model=tofu --list-config))) @@ -106,7 +103,7 @@ (info "Checking tofu policies and trust...") ;; Carefully remove the TOFU db. -(catch '() (unlink (string-append GNUPGHOME "/tofu.db"))) +(catch '() (unlink (path-join GNUPGHOME "tofu.db"))) ;; Verify a message. There should be no conflict and the trust ;; policy should be set to auto. @@ -205,7 +202,7 @@ )) ;; Carefully remove the TOFU db. -(catch '() (unlink (string-append GNUPGHOME "/tofu.db"))) +(catch '() (unlink (path-join GNUPGHOME "tofu.db"))) (check-counts "1C005AF3" 0 0 0 0) (check-counts "BE04EB2B" 0 0 0 0) @@ -288,7 +285,7 @@ --faked-system-time=1476304861)) ;; Carefully remove the TOFU db. -(catch '() (unlink (string-append GNUPGHOME "/tofu.db"))) +(catch '() (unlink (path-join GNUPGHOME "tofu.db"))) (define DIR "tofu/cross-sigs") ;; The test keys. @@ -380,7 +377,7 @@ --faked-system-time=1476304861)) ;; Carefully remove the TOFU db. -(catch '() (unlink (string-append GNUPGHOME "/tofu.db"))) +(catch '() (unlink (path-join GNUPGHOME "tofu.db"))) (define DIR "tofu/cross-sigs") ;; The test keys. diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 0f90424..5814b40 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -690,7 +690,16 @@ command_send (const char *fingerprint, char *userid) else err = wkd_get_submission_address (addrspec, &submission_to); if (err) - goto leave; + { + char *domain = strchr (addrspec, '@'); + if (domain) + domain = domain + 1; + log_error (_("looking up WKS submission address for %s: %s\n"), + domain ? domain : addrspec, gpg_strerror (err)); + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + log_error (_("this domain probably doesn't support WKS.\n")); + goto leave; + } log_info ("submitting request to '%s'\n", submission_to); /* Get the policy flags. */ @@ -699,12 +708,12 @@ command_send (const char *fingerprint, char *userid) estream_t mbuf; err = wkd_get_policy_flags (addrspec, &mbuf); - if (err) + if (err && gpg_err_code (err) != GPG_ERR_NO_DATA) { log_error ("error reading policy flags for '%s': %s\n", submission_to, gpg_strerror (err)); goto leave; - } + } if (mbuf) { err = wks_parse_policy (&policy, mbuf, 1); diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 925f1cf..a25b513 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1102,6 +1102,35 @@ struct error_line_s + +/* Initialization and finalization. */ + +static void +gc_option_free (gc_option_t *o) +{ + if (o == NULL || o->name == NULL) + return; + + xfree (o->value); + gc_option_free (o + 1); +} + +static void +gc_components_free (void) +{ + int i; + for (i = 0; i < DIM (gc_component); i++) + gc_option_free (gc_component[i].options); +} + +void +gc_components_init (void) +{ + atexit (gc_components_free); +} + + + /* Engine specific support. */ static void gpg_agent_runtime_change (int killflag) @@ -1109,7 +1138,7 @@ gpg_agent_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[5]; - pid_t pid; + pid_t pid = (pid_t)(-1); char *abs_homedir = NULL; int i = 0; @@ -1145,7 +1174,7 @@ scdaemon_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[9]; - pid_t pid; + pid_t pid = (pid_t)(-1); char *abs_homedir = NULL; int i = 0; @@ -1192,7 +1221,7 @@ dirmngr_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[6]; - pid_t pid; + pid_t pid = (pid_t)(-1); char *abs_homedir = NULL; pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT); @@ -1234,6 +1263,14 @@ gc_component_launch (int component) int i; pid_t pid; + if (component < 0) + { + err = gc_component_launch (GC_COMPONENT_GPG_AGENT); + if (!err) + err = gc_component_launch (GC_COMPONENT_DIRMNGR); + return err; + } + if (!(component == GC_COMPONENT_GPG_AGENT || component == GC_COMPONENT_DIRMNGR)) { @@ -1275,7 +1312,16 @@ gc_component_kill (int component) for (backend = 0; backend < GC_BACKEND_NR; backend++) runtime[backend] = 0; - if (component >= 0) + if (component < 0) + { + for (component = 0; component < GC_COMPONENT_NR; component++) + { + option = gc_component[component].options; + for (; option && option->name; option++) + runtime[option->backend] = 1; + } + } + else { assert (component < GC_COMPONENT_NR); option = gc_component[component].options; @@ -1304,7 +1350,7 @@ gc_component_reload (int component) for (backend = 0; backend < GC_BACKEND_NR; backend++) runtime[backend] = 0; - if (component == -1) + if (component < 0) { for (component = 0; component < GC_COMPONENT_NR; component++) { @@ -2183,7 +2229,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) if (!(option->flags & GC_OPT_FLAG_LIST)) { if (option->value) - free (option->value); + xfree (option->value); option->value = opt_value; } else @@ -2192,10 +2238,9 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) option->value = opt_value; else { - char *opt_val = opt_value; - - option->value = xasprintf ("%s,%s", option->value, - opt_val); + char *old = option->value; + option->value = xasprintf ("%s,%s", old, opt_value); + xfree (old); xfree (opt_value); } } @@ -2872,7 +2917,12 @@ change_options_program (gc_component_t component, gc_backend_t backend, res = link (dest_filename, orig_filename); #endif if (res < 0 && errno != ENOENT) - return -1; + { + xfree (dest_filename); + xfree (src_filename); + xfree (orig_filename); + return -1; + } if (res < 0) { xfree (orig_filename); @@ -3365,6 +3415,7 @@ gc_component_change_options (int component, estream_t in, estream_t out, } if (err) break; + xfree (src_filename[i]); src_filename[i] = NULL; } } @@ -3434,10 +3485,17 @@ gc_component_change_options (int component, estream_t in, estream_t out, unlink (backup_filename); #endif /* HAVE_W32_SYSTEM */ rename (orig_filename[backend], backup_filename); + xfree (backup_filename); } leave: xfree (line); + for (backend = 0; backend < GC_BACKEND_NR; backend++) + { + xfree (src_filename[backend]); + xfree (dest_filename[backend]); + xfree (orig_filename[backend]); + } } diff --git a/tools/gpgconf.c b/tools/gpgconf.c index af65424..a5ee188 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -280,7 +280,7 @@ query_swdb (estream_t out, const char *name, const char *current_version) gnupg_isotime_t value_date = {0}; char *value_size = NULL; char *value_sha2 = NULL; - unsigned long value_size_ul; + unsigned long value_size_ul = 0; int status, i; @@ -470,6 +470,7 @@ main (int argc, char **argv) /* Make sure that our subsystems are ready. */ i18n_init(); init_common_subsystems (&argc, &argv); + gc_components_init (); /* Parse the command line. */ pargs.argc = &argc; @@ -588,6 +589,18 @@ main (int argc, char **argv) es_putc ('\n', es_stderr); exit (2); } + else if (!strcmp (fname, "all")) + { + if (cmd == aLaunch) + { + if (gc_component_launch (-1)) + exit (1); + } + else + { + gc_component_kill (-1); + } + } else { /* Launch/Kill a given component. */ @@ -616,7 +629,7 @@ main (int argc, char **argv) break; case aReload: - if (!fname) + if (!fname || !strcmp (fname, "all")) { /* Reload all. */ gc_component_reload (-1); diff --git a/tools/gpgconf.h b/tools/gpgconf.h index 39d34b6..d6d7627 100644 --- a/tools/gpgconf.h +++ b/tools/gpgconf.h @@ -38,6 +38,10 @@ struct /*-- gpgconf-comp.c --*/ + +/* Initialize the components. */ +void gc_components_init (void); + /* Percent-Escape special characters. The string is valid until the next invocation of the function. */ char *gc_percent_escape (const char *src); diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index ef906a5..ffd239f 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -429,7 +429,11 @@ pattern_valid_p (const char *pattern) return 0; if (*pattern == '.' && pattern[1] == '.') return 0; - if (*pattern == '/' || *pattern == DIRSEP_C) + if (*pattern == '/' +#ifdef HAVE_DOSISH_SYSTEM + || *pattern == '\\' +#endif + ) return 0; /* Absolute filenames are not supported. */ #ifdef HAVE_DRIVE_LETTERS if (((*pattern >= 'a' && *pattern <= 'z') diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 44ff43c..f8b6fdc 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -253,9 +253,9 @@ static void print_version (int with_help) { fputs (MYVERSION_LINE "\n" - "Copyright (C) 2010 Free Software Foundation, Inc.\n" + "Copyright (C) 2017 Free Software Foundation, Inc.\n" "License GPLv3+: " - "GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n" + "GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\n" "This is free software: you are free to change and redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n", stdout); |