From cvs at cvs.gnupg.org Fri Jan 1 18:41:28 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 01 Jan 2016 18:41:28 +0100 Subject: [git] gnupg-doc - branch, master, updated. 5dedb55faddf94f16bd44480d339ca755fee4b83 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 5dedb55faddf94f16bd44480d339ca755fee4b83 (commit) via a7699e118e44b3beba9c53963b599606f20efb1e (commit) from fc205344e98cb2d92d3176becdafecbdd8f9f9df (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5dedb55faddf94f16bd44480d339ca755fee4b83 Author: Werner Koch Date: Fri Jan 1 18:27:20 2016 +0100 blog: Add an update to the last blog entry. diff --git a/misc/blog.gnupg.org/20151224-gnupg-in-november-and-december.org b/misc/blog.gnupg.org/20151224-gnupg-in-november-and-december.org index d13d689..e2fcd68 100644 --- a/misc/blog.gnupg.org/20151224-gnupg-in-november-and-december.org +++ b/misc/blog.gnupg.org/20151224-gnupg-in-november-and-december.org @@ -151,6 +151,13 @@ support for 2016 and have donated another USD60,000. Thanks! Unfortunately, [[https://twitter.com/stripe/status/563449352635432960][although Facebook initially announced that they would provide USD50,000 of support per year]], they have since rescinded. +** Update 2016-01-01 + +We have meanwhile received unofficial information that Facebook did +not rescinded their support pledge. We are waiting for an official +comment and will report on that then. + + ** About this news posting We try to write a news posting each month. However, other work may commit a7699e118e44b3beba9c53963b599606f20efb1e Author: Werner Koch Date: Fri Jan 1 18:18:47 2016 +0100 web: Add donation list for 2016 diff --git a/web/donate/kudos-2016.org b/web/donate/kudos-2016.org new file mode 100644 index 0000000..81ec977 --- /dev/null +++ b/web/donate/kudos-2016.org @@ -0,0 +1,13 @@ +#+TITLE: GnuPG - List of Donors - 2016 +#+STARTUP: showall +#+SETUPFILE: "../share/setup.inc" + +* People who donated money to GnuPG in 2016 + +#+HTML:
    +#+HTML: +#+HTML:
  • [please reload in a few minutes while the list is being updated] +#+HTML: +#+HTML:
+ + Thank you. diff --git a/web/donate/kudos.org b/web/donate/kudos.org index 808fb41..8fc5a63 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -16,15 +16,16 @@ *** Previous years -| Year | # | \EUR | net \EUR | -| | | | | -|------+-----+-------+----------| -| 2014 | 801 | 34700 | | -| 2013 | 148 | 5041 | 4145 | -| 2012 | 53 | 5991 | 4963 | -| 2011 | 21 | 553 | 465 | -|------+-----+-------+----------| -| | | 46285 | | +| Year | # | \EUR | net \EUR | +| | | | | +|------+------+--------+----------| +| 2015 | 5844 | 205560 | | +| 2014 | 801 | 34700 | 30305 | +| 2013 | 148 | 5041 | 4145 | +| 2012 | 53 | 5991 | 4963 | +| 2011 | 21 | 553 | 465 | +|------+------+--------+----------| +| | | 251845 | | #+TBLFM: $LR3=vsum(@I.. at II)::$LR4=vsum(@I.. at II) #+HTML:
The "net" column gives the actual value without VAT and credit card @@ -33,7 +34,14 @@ fees.\\ The [[https://gnupg.org/blog/20140512-rewards-sent.html][Goteo crowdfunding]] campaign raised an additional 32641\thinsp\euro (27429 net) in December 2013. +# Goteo transferred that money in March 2014 in 6 chunks: +# 11423, 6000, 5000, 5000, 5218 = 32641 +# Some of the 801 donations from 2014 have been hold back by Stripe +# over the end of the year and thus VAT was only payable in 2015. +# That VAT is not included in the net amount for 2014. The net amount +# received from individual donations in 2014 have been 2525, 919, 541, +# 26320 Euro per quarter. * List of Donors @@ -46,6 +54,7 @@ The [[https://gnupg.org/blog/20140512-rewards-sent.html][Goteo crowdfunding]] ca Thank you. + - All donors to GnuPG in [[file:kudos-2016.org][2016]] - All donors to GnuPG in [[file:kudos-2015.org][2015]] - All donors to GnuPG in [[file:kudos-2014.org][2014]] - All donors to GnuPG in [[file:kudos-2013.org][2013]] ----------------------------------------------------------------------- Summary of changes: .../20151224-gnupg-in-november-and-december.org | 7 ++++++ web/donate/{kudos-2015.org => kudos-2016.org} | 4 ++-- web/donate/kudos.org | 27 ++++++++++++++-------- 3 files changed, 27 insertions(+), 11 deletions(-) copy web/donate/{kudos-2015.org => kudos-2016.org} (73%) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 4 11:17:26 2016 From: cvs at cvs.gnupg.org (by Damien Goutte-Gattat) Date: Mon, 04 Jan 2016 11:17:26 +0100 Subject: [git] Scute - branch, master, updated. scute-1.3.0-49-gbe53b88 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PKCS#11 token on top of gpg-agent". The branch, master has been updated via be53b88aa2b3d9e8952d89251d40bca0059bab40 (commit) from e22c8cfa12849b215f16afb34f7a5dc233dbc70a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be53b88aa2b3d9e8952d89251d40bca0059bab40 Author: Damien Goutte-Gattat Date: Sun Jan 3 15:56:23 2016 +0100 scute: Include sexp-parse.h in source files * src/Makefile.am: Add sexp-parse.h in source files. -- Omitting sexp-parse.h from the list of source files excludes it from the archive generated by `make dist'. Signed-off-by: Damien Goutte-Gattat diff --git a/src/Makefile.am b/src/Makefile.am index 43fa086..9ceef93 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -58,7 +58,7 @@ sources = cryptoki.h pkcs11.h debug.c debug.h settings.h support.h \ p11-signrecover.c p11-signrecoverinit.c p11-signupdate.c \ p11-unwrapkey.c p11-verify.c p11-verifyfinal.c p11-verifyinit.c \ p11-verifyrecover.c p11-verifyrecoverinit.c p11-verifyupdate.c \ - p11-waitforslotevent.c p11-wrapkey.c + p11-waitforslotevent.c p11-wrapkey.c sexp-parse.h if HAVE_LD_VERSION_SCRIPT ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 4 12:46:19 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Mon, 04 Jan 2016 12:46:19 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-75-g575c15a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 575c15a090913d86cf8d75b2bc4471e371f234b9 (commit) via bf694cbc68cc7dfc0ce16bbe389014f8e8ee0d87 (commit) from 79b51bb8727bd3485229ac8ff5987558156d5d83 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 575c15a090913d86cf8d75b2bc4471e371f234b9 Author: Neal H. Walfield Date: Mon Jan 4 12:46:11 2016 +0100 gpg: Fix double free. * g10/getkey.c (get_pubkeys): Fix double free. -- Signed-off-by: Neal H. Walfield Fixes-commit: 7195b943 Note: this error is not a security problem, because this code path is currently never executed. diff --git a/g10/getkey.c b/g10/getkey.c index 52e3d23..86a3c80 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -629,15 +629,7 @@ get_pubkeys (ctrl_t ctrl, out: if (err) - { - while ((r = results)) - { - results = results->next; - pubkey_free (r); - release_kbnode (r->keyblock); - xfree (r); - } - } + pubkeys_free (results); else *r_keys = results; commit bf694cbc68cc7dfc0ce16bbe389014f8e8ee0d87 Author: Neal H. Walfield Date: Mon Jan 4 12:41:21 2016 +0100 Revert commit 4654384fe7a4dcee113dacf27c398b13dea5d0be. -- Signed-off-by: Neal H. Walfield Werner pointed out that a special error message is not needed: the error code (as displayed by gpg_strerror) will indicate what went wrong. diff --git a/g10/getkey.c b/g10/getkey.c index 608b75e..52e3d23 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1452,7 +1452,7 @@ parse_def_secret_key (ctrl_t ctrl) err = classify_user_id (t->d, &desc, 1); if (err) { - log_error (_("error parsing search description \"%s\": %s\n"), + log_error (_("secret key \"%s\" not found: %s\n"), t->d, gpg_strerror (err)); if (!opt.quiet) log_info (_("(check argument of option '%s')\n"), "--default-key"); ----------------------------------------------------------------------- Summary of changes: g10/getkey.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 4 16:25:27 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 04 Jan 2016 16:25:27 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-1.3.0-44-g4aadd33 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 4aadd33407535b83b04c62c0cd79c7ca2f0d2ebd (commit) from c3b6b357bb4636ec76fa5c7b499e1e9f99083c06 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4aadd33407535b83b04c62c0cd79c7ca2f0d2ebd Author: Andre Heinecke Date: Mon Jan 4 16:23:46 2016 +0100 Fix crash when using Exchange Active Sync * src/mapihelp.cpp (get_msgcls_from_pgp_lines): Do not crash when internetcharsetbody_tag is not available. -- In this case the function previously dereferenced the uninitialized stream pointer. diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index d4d5730..1b04af8 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -563,6 +563,12 @@ get_msgcls_from_pgp_lines (LPMESSAGE message) if (!hr) is_binary = 1; } + else + { + log_debug ("%s:%s: Failed to get body tag.", + SRCNAME, __func__); + return NULL; + } if (hr) { tag = PR_BODY; @@ -575,7 +581,7 @@ get_msgcls_from_pgp_lines (LPMESSAGE message) SRCNAME, __func__, tag, hr); return NULL; } - + hr = stream->Stat (&statInfo, STATFLAG_NONAME); if (hr) { ----------------------------------------------------------------------- Summary of changes: src/mapihelp.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 5 02:21:38 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 05 Jan 2016 02:21:38 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-76-gff3b607 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via ff3b607fc879b70665c187500022cc63e2a0cd86 (commit) from 575c15a090913d86cf8d75b2bc4471e371f234b9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ff3b607fc879b70665c187500022cc63e2a0cd86 Author: NIIBE Yutaka Date: Tue Jan 5 10:15:49 2016 +0900 agent: Fix RSA verification for card. * agent/pksign.c (agent_pksign_do): Use S-exp of public key, instead of shadowed key. -- Reported-by: Justus Winter Signed-off-by: NIIBE Yutaka diff --git a/agent/pksign.c b/agent/pksign.c index 7b498d4..9011be2 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -492,21 +492,20 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, * for RSA internally there is no need to do it here again. */ if (check_signature) { + gcry_sexp_t sexp_key = s_pkey? s_pkey: s_skey; + if (s_hash == NULL) { if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1) rc = do_encode_raw_pkcs1 (data, datalen, - gcry_pk_get_nbits (s_skey), - &s_hash); + gcry_pk_get_nbits (sexp_key), &s_hash); else - rc = do_encode_md (data, datalen, - ctrl->digest.algo, - &s_hash, + rc = do_encode_md (data, datalen, ctrl->digest.algo, &s_hash, ctrl->digest.raw_value); } if (! rc) - rc = gcry_pk_verify (s_sig, s_hash, s_pkey? s_pkey: s_skey); + rc = gcry_pk_verify (s_sig, s_hash, sexp_key); if (rc) { ----------------------------------------------------------------------- Summary of changes: agent/pksign.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 5 12:48:00 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 05 Jan 2016 12:48:00 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-2-g954da56 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The standard pinentry collection". The branch, master has been updated via 954da56c2325c3a5ca628cfc2e3086c1e146a390 (commit) from 65fa8d2e2a38ae3c6bf7398ae5feb872f8ce23fe (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 954da56c2325c3a5ca628cfc2e3086c1e146a390 Author: Andre Heinecke Date: Tue Jan 5 12:44:32 2016 +0100 Qt: Fix use after free in quality calculation * qt/pinentrydialog.cpp (PinEntryDialog::updateQuality): Keep UTF8 byte array alive after conversion. -- Same problem pattern as in Bug 2133 / commit f143d216 diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp index c7885d3..81205ee 100644 --- a/qt/pinentrydialog.cpp +++ b/qt/pinentrydialog.cpp @@ -309,7 +309,8 @@ void PinEntryDialog::updateQuality(const QString & txt ) if (!_have_quality_bar || !_pinentry_info) return; - const char* pin = txt.toUtf8().constData(); + const QByteArray utf8_pin = txt.toUtf8 (); + const char* pin = utf8_pin.constData (); length = strlen (pin); percent = length? pinentry_inq_quality (_pinentry_info, pin, length) : 0; if (!length) ----------------------------------------------------------------------- Summary of changes: qt/pinentrydialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 5 14:00:31 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 05 Jan 2016 14:00:31 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-78-ge70f7a5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via e70f7a54f29d727def2cfe9ea5ab9d461b4ce842 (commit) via f2ecbf7454fe1e4b87112b982d7ddcd496ebc1ff (commit) from ff3b607fc879b70665c187500022cc63e2a0cd86 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e70f7a54f29d727def2cfe9ea5ab9d461b4ce842 Author: Werner Koch Date: Tue Jan 5 13:49:06 2016 +0100 gpg: Align notes about minimal keysize with actual checks. * g10/keygen.c (ask_keysize): Use 768 for the minimal value for DSA in export mode. Improve readability. -- GnuPG-bug-id: 2209 Signed-off-by: Werner Koch diff --git a/g10/keygen.c b/g10/keygen.c index 992e572..921e938 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2006,15 +2006,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, static unsigned ask_keysize (int algo, unsigned int primary_keysize) { - unsigned int nbits, min, def = DEFAULT_STD_KEYSIZE, max=4096; + unsigned int nbits; + unsigned int min = 1024; + unsigned int def = DEFAULT_STD_KEYSIZE; + unsigned int max = 4096; int for_subkey = !!primary_keysize; int autocomp = 0; - if(opt.expert) - min=512; - else - min=1024; - if (primary_keysize && !opt.expert) { /* Deduce the subkey size from the primary key size. */ @@ -2029,9 +2027,11 @@ ask_keysize (int algo, unsigned int primary_keysize) goto leave; } + /* Deviations from the standard values. */ switch(algo) { case PUBKEY_ALGO_DSA: + min = opt.expert? 768 : 1024; def=2048; max=3072; break; @@ -2048,10 +2048,6 @@ ask_keysize (int algo, unsigned int primary_keysize) def=255; max=441; break; - - case PUBKEY_ALGO_RSA: - min=1024; - break; } tty_printf(_("%s keys may be between %u and %u bits long.\n"), commit f2ecbf7454fe1e4b87112b982d7ddcd496ebc1ff Author: Werner Koch Date: Wed Dec 30 18:23:14 2015 +0100 agent: Typo fix for help text. -- diff --git a/agent/command.c b/agent/command.c index 718a5e6..a09da60 100644 --- a/agent/command.c +++ b/agent/command.c @@ -2036,7 +2036,7 @@ static const char hlp_import_key[] = "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n" "key data. The unwrapped key must be a canonical S-expression. The\n" "option --unattended tries to import the key as-is without any\n" - "re-encryption. Exisiting key can be overwritten with --force."; + "re-encryption. Existing key can be overwritten with --force."; static gpg_error_t cmd_import_key (assuan_context_t ctx, char *line) { ----------------------------------------------------------------------- Summary of changes: agent/command.c | 2 +- g10/keygen.c | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 6 08:56:19 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jan 2016 08:56:19 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-87-gc7389ae Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via c7389ae90fa4a70766400cc241ff6a45aa750324 (commit) via 85cc7449fb00ac85b0c2eecd22bd38b23f33edf5 (commit) via 09accc0e3d74e6289bed40b5bfc6479981cabfe4 (commit) via 7990586828a252e78d2ecacbaaa152431d7e08c8 (commit) via db82b6131d437bf6ba34db0e08b7dfa9edb11e45 (commit) via 6deafb92abe100ff67e3a0a230a39e8c0ad41900 (commit) via e64317c15e9960f3173d374e589f7c3565a4ad08 (commit) via 1fbfa1bf0a6ad0dc7ed67d12252643c2c6c7370a (commit) via 0a00115ee2049ab2357b7a14a51c7da185ffcabd (commit) from e70f7a54f29d727def2cfe9ea5ab9d461b4ce842 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c7389ae90fa4a70766400cc241ff6a45aa750324 Author: Werner Koch Date: Wed Jan 6 08:49:45 2016 +0100 gpg: Silence some regression tests. * g10/test.c (TEST): Print diagnostics only in verbose mode. Signed-off-by: Werner Koch diff --git a/g10/test.c b/g10/test.c index 59a015c..39d5945 100644 --- a/g10/test.c +++ b/g10/test.c @@ -63,11 +63,12 @@ static int verbose; int expected_result; \ \ tests ++; \ - \ - printf ("%d. Checking %s...", \ - tests, (description) ?: ""); \ - fflush (stdout); \ - \ + if (verbose) \ + { \ + printf ("%d. Checking %s...", \ + tests, (description) ?: ""); \ + fflush (stdout); \ + } \ test_result = (test); \ expected_result = (expected); \ \ commit 85cc7449fb00ac85b0c2eecd22bd38b23f33edf5 Author: Werner Koch Date: Wed Jan 6 08:48:44 2016 +0100 gpg: Avoid using an uninitialized SALT on premature EOF. * g10/parse-packet.c (parse_key): Check for premature end of salt. -- This has no security implications because an arbitrary salt could have also been inset by an attacker. Signed-off-by: Werner Koch diff --git a/g10/parse-packet.c b/g10/parse-packet.c index b0c6ee5..38cd8c9 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -2313,6 +2313,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, case 3: for (i = 0; i < 8 && pktlen; i++, pktlen--) temp[i] = iobuf_get_noeof (inp); + if (i < 8) + { + err = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } memcpy (ski->s2k.salt, temp, 8); break; } commit 09accc0e3d74e6289bed40b5bfc6479981cabfe4 Author: Werner Koch Date: Wed Jan 6 08:45:01 2016 +0100 gpg: Silence warnings found by static analyzer. * g10/keyedit.c (change_passphrase): Remove useless init of ANY. (keyedit_quick_adduid): Remove useless setting of ERR. * g10/parse-packet.c (parse_key): Remove PKTLEN from condition because it has been checked before the loop. (parse_plaintext): Remove useless init of PKTLEN. Signed-off-by: Werner Koch diff --git a/g10/keyedit.c b/g10/keyedit.c index 1c302b7..497fd1b 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1195,7 +1195,7 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock) } /* Change the passphrase for all keys. */ - for (any = 0, node = keyblock; node; node = node->next) + for (node = keyblock; node; node = node->next) { if (node->pkt->pkttype == PKT_PUBLIC_KEY || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) @@ -2391,7 +2391,7 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid) kdbhd = keydb_new (); if (!kdbhd) { - err = gpg_error_from_syserror (); + /* Note that keydb_new has already used log_error. */ goto leave; } diff --git a/g10/parse-packet.c b/g10/parse-packet.c index d552fa6..b0c6ee5 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -2428,7 +2428,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, err = gpg_error (GPG_ERR_INV_PACKET); goto leave; } - for (i = 0; i < ski->ivlen && pktlen; i++, pktlen--) + for (i = 0; i < ski->ivlen; i++, pktlen--) temp[i] = iobuf_get_noeof (inp); if (list_mode) { @@ -2862,7 +2862,6 @@ parse_plaintext (IOBUF inp, int pkttype, unsigned long pktlen, pktlen -= 4; pt->len = pktlen; pt->buf = inp; - pktlen = 0; if (list_mode) { commit 7990586828a252e78d2ecacbaaa152431d7e08c8 Author: Werner Koch Date: Wed Jan 6 08:42:07 2016 +0100 gpg: Comment on false positives by static analyzers. -- diff --git a/g10/encrypt.c b/g10/encrypt.c index bca1123..eca1c27 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -326,6 +326,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) if (!opt.no_literal) { + /* Note that PT has been initialized above in no_literal mode. */ pt->timestamp = make_timestamp(); pt->mode = opt.textmode? 't' : 'b'; pt->len = filesize; diff --git a/g10/keyedit.c b/g10/keyedit.c index a303058..1c302b7 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -363,7 +363,13 @@ check_all_keysigs (KBNODE keyblock, int only_selected, int only_selfsigs) if (only_selfsigs && !(keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1])) - ; /* Not a selfsig but we want only selfsigs - skip. */ + { + /* Not a selfsig but we want only selfsigs - skip. */ + /* Static analyzer note: A claim that KEYID above has + garbage is not correct because KEYID is set from the + public key packet which is always the first packet in + a keyblock and thus parsed before this signature. */ + } else if (print_and_check_one_sig (keyblock, node, &inv_sigs, &no_key, &oth_err, &selfsig, 0, only_selfsigs)) @@ -856,6 +862,14 @@ sign_uids (ctrl_t ctrl, estream_t fp, if (primary_pk->expiredate && !selfsig) { + /* Static analyzer note: A claim that PRIMARY_PK might be + NULL is not correct because it set from the public key + packet which is always the first packet in a keyblock and + parsed in the above loop over the keyblock. In case the + keyblock has no packets at all and thus the loop was not + entered the above count_uids_with_flag would have + detected this case. */ + u32 now = make_timestamp (); if (primary_pk->expiredate <= now) diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 53b75a6..d552fa6 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -2517,6 +2517,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, } } + /* Note that KEYID below has been initialized above in list_mode. */ if (list_mode) es_fprintf (listfp, "\tkeyid: %08lX%08lX\n", (ulong) keyid[0], (ulong) keyid[1]); diff --git a/g10/sign.c b/g10/sign.c index 79a5f3b..081bd99 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -601,6 +601,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode) if (!opt.no_literal) { PACKET pkt; + /* Note that PT has been initialized above in no_literal mode. */ pt->timestamp = make_timestamp (); pt->mode = ptmode; pt->len = filesize; commit db82b6131d437bf6ba34db0e08b7dfa9edb11e45 Author: Werner Koch Date: Wed Jan 6 08:39:08 2016 +0100 kbx: Avoid faulty fclose in an error case. * kbx/keybox-update.c (blob_filecopy): Do not close an uninitialized file pointer after a failure to create a temp file. * kbx/keybox-openpgp.c (next_packet): Remove duplicate assignment of PKTLEN. Signed-off-by: Werner Koch diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index a5f602b..a0e4ab9 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -71,7 +71,6 @@ next_packet (unsigned char const **bufptr, size_t *buflen, if ( !(ctb & 0x80) ) return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */ - pktlen = 0; if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ { pkttype = (ctb & 0x3f); diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index ef3e330..aa80865 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -271,12 +271,11 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, goto leave; } - /* Create the new file. */ + /* Create the new file. On success NEWFP is initialized. */ rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); if (rc) { fclose (fp); - fclose (newfp); goto leave; } commit 6deafb92abe100ff67e3a0a230a39e8c0ad41900 Author: Werner Koch Date: Wed Jan 6 08:37:03 2016 +0100 dirmngr: Silence one regression test. * dirmngr/t-dns-stuff.c (main): Do not print info during standard "make check". Signed-off-by: Werner Koch diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c index 3030277..05b39a0 100644 --- a/dirmngr/t-dns-stuff.c +++ b/dirmngr/t-dns-stuff.c @@ -155,7 +155,8 @@ main (int argc, char **argv) void *key; size_t keylen; - printf ("CERT lookup on '%s'\n", name); + if (verbose || any_options) + printf ("CERT lookup on '%s'\n", name); err = get_dns_cert (name, DNS_CERTTYPE_ANY, &key, &keylen, &fpr, &fpr_len, &url); @@ -164,7 +165,8 @@ main (int argc, char **argv) gpg_strerror (err), gpg_strsource (err)); else if (key) { - printf ("Key found (%u bytes)\n", (unsigned int)keylen); + if (verbose || any_options) + printf ("Key found (%u bytes)\n", (unsigned int)keylen); } else { commit e64317c15e9960f3173d374e589f7c3565a4ad08 Author: Werner Koch Date: Wed Jan 6 08:35:56 2016 +0100 common: Avoid warnings about useless assignments. * common/b64enc.c (b64enc_finish): Remove var assignment which is not used later. * common/iobuf.c (file_filter): Ditto. * common/tlv.c (do_find_tlv): Ditto. * common/userids.c (classify_user_id): Ditto. Signed-off-by: Werner Koch diff --git a/common/b64enc.c b/common/b64enc.c index 087f27c..9101d98 100644 --- a/common/b64enc.c +++ b/common/b64enc.c @@ -348,7 +348,6 @@ b64enc_finish (struct b64state *state) { for (idx=0; idx < 4; idx++) es_putc (tmp[idx], state->stream); - idx = 0; if (es_ferror (state->stream)) goto write_error; } @@ -356,7 +355,6 @@ b64enc_finish (struct b64state *state) { for (idx=0; idx < 4; idx++) putc (tmp[idx], state->fp); - idx = 0; if (ferror (state->fp)) goto write_error; } diff --git a/common/iobuf.c b/common/iobuf.c index e8b4a03..d149e2e 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -589,7 +589,6 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, if (!a->keep_open) fd_cache_close (a->no_cache ? NULL : a->fname, f); } - f = GNUPG_INVALID_FD; xfree (a); /* We can free our context now. */ } diff --git a/common/tlv.c b/common/tlv.c index 74cb4a7..1a6c18f 100644 --- a/common/tlv.c +++ b/common/tlv.c @@ -59,7 +59,6 @@ do_find_tlv (const unsigned char *buffer, size_t length, for (;;) { - buffer = s; if (n < 2) return NULL; /* Buffer definitely too short for tag and length. */ if (!*s || *s == 0xff) diff --git a/common/userids.c b/common/userids.c index e094c69..b761d14 100644 --- a/common/userids.c +++ b/common/userids.c @@ -235,7 +235,6 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack) desc->u.fpr[i] = hextobyte(si); for (; i < 20; i++) desc->u.fpr[i]= 0; - s = se + 1; mode = KEYDB_SEARCH_MODE_FPR; } break; commit 1fbfa1bf0a6ad0dc7ed67d12252643c2c6c7370a Author: Werner Koch Date: Wed Jan 6 08:34:14 2016 +0100 tests: Use info and error instead of a plain echo. * tests/openpgp/4gb-packet.test: Use error and info. Signed-off-by: Werner Koch diff --git a/tests/openpgp/4gb-packet.test b/tests/openpgp/4gb-packet.test index 57b8fc7..548ebfe 100755 --- a/tests/openpgp/4gb-packet.test +++ b/tests/openpgp/4gb-packet.test @@ -8,9 +8,7 @@ i=$srcdir/4gb-packet.asc if ! $GPG --list-packets $i >/dev/null then - echo Failed to parse 4GB packet. - exit 1 + error Failed to parse 4GB packet. else - echo Can parse 4GB packets. - exit 0 + info Can parse 4GB packets. fi commit 0a00115ee2049ab2357b7a14a51c7da185ffcabd Author: Werner Koch Date: Wed Jan 6 08:31:38 2016 +0100 common: Do not deref vars in tests after a fail(). * common/t-convert.c (test_bin2hex): Turn if conditions into if-else chains to avoid accessing unchecked data. (test_bin2hexcolon): Ditto. * common/t-mapstrings.c (test_map_static_macro_string): Ditto. * common/t-stringhelp.c (test_percent_escape): Ditto. (test_make_filename_try): Ditto. (test_make_absfilename_try): Ditto. * common/t-timestuff.c (test_timegm): Ditto. -- Note that these dereference only occur after failed regression tests. Signed-off-by: Werner Koch diff --git a/common/t-convert.c b/common/t-convert.c index a03c680..ad33dff 100644 --- a/common/t-convert.c +++ b/common/t-convert.c @@ -232,13 +232,13 @@ test_bin2hex (void) p = bin2hex (stuff, 20, NULL); if (!p) fail (0); - if (strcmp (p, hexstuff)) + else if (strcmp (p, hexstuff)) fail (0); p = bin2hex (stuff, (size_t)(-1), NULL); if (p) fail (0); - if (errno != ENOMEM) + else if (errno != ENOMEM) fail (1); } @@ -264,13 +264,13 @@ test_bin2hexcolon (void) p = bin2hexcolon (stuff, 20, NULL); if (!p) fail (0); - if (strcmp (p, hexstuff)) + else if (strcmp (p, hexstuff)) fail (0); p = bin2hexcolon (stuff, (size_t)(-1), NULL); if (p) fail (0); - if (errno != ENOMEM) + else if (errno != ENOMEM) fail (1); } diff --git a/common/t-mapstrings.c b/common/t-mapstrings.c index 88c6674..8f4c650 100644 --- a/common/t-mapstrings.c +++ b/common/t-mapstrings.c @@ -68,7 +68,7 @@ test_map_static_macro_string (void) result = map_static_macro_string (tests[testno].string); if (!result) fail (testno); - if (strcmp (result, tests[testno].expected)) + else if (strcmp (result, tests[testno].expected)) fail (testno); if (!tests[testno].lastresult) tests[testno].lastresult = result; @@ -80,7 +80,7 @@ test_map_static_macro_string (void) result = map_static_macro_string (tests[testno].string); if (!result) fail (testno); - if (strcmp (result, tests[testno].expected)) + else if (strcmp (result, tests[testno].expected)) fail (testno); if (result != tests[testno].lastresult) fail (testno); diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c index e97b64a..af79cb5 100644 --- a/common/t-stringhelp.c +++ b/common/t-stringhelp.c @@ -143,7 +143,7 @@ test_percent_escape (void) result = percent_escape (tests[testno].value, tests[testno].extra); if (!result) fail (testno); - if (strcmp (result, tests[testno].expected)) + else if (strcmp (result, tests[testno].expected)) fail (testno); xfree (result); } @@ -398,13 +398,13 @@ test_make_filename_try (void) out = make_filename_try ("~/foo", "bar", NULL); if (!out) fail (2); - if (home) + else if (home) { if (strlen (out) < homelen + 7) fail (2); - if (strncmp (out, home, homelen)) + else if (strncmp (out, home, homelen)) fail (2); - if (strcmp (out+homelen, "/foo/bar")) + else if (strcmp (out+homelen, "/foo/bar")) fail (2); } else @@ -417,13 +417,13 @@ test_make_filename_try (void) out = make_filename_try ("~", "bar", NULL); if (!out) fail (2); - if (home) + else if (home) { if (strlen (out) < homelen + 3) fail (2); - if (strncmp (out, home, homelen)) + else if (strncmp (out, home, homelen)) fail (2); - if (strcmp (out+homelen, "/bar")) + else if (strcmp (out+homelen, "/bar")) fail (2); } else @@ -445,33 +445,33 @@ test_make_absfilename_try (void) out = make_absfilename_try ("foo", "bar", NULL); if (!out) fail (0); - if (strlen (out) < cwdlen + 7) + else if (strlen (out) < cwdlen + 7) fail (0); - if (strncmp (out, cwd, cwdlen)) + else if (strncmp (out, cwd, cwdlen)) fail (0); - if (strcmp (out+cwdlen, "/foo/bar")) + else if (strcmp (out+cwdlen, "/foo/bar")) fail (0); xfree (out); out = make_absfilename_try ("./foo", NULL); if (!out) fail (1); - if (strlen (out) < cwdlen + 5) + else if (strlen (out) < cwdlen + 5) fail (1); - if (strncmp (out, cwd, cwdlen)) + else if (strncmp (out, cwd, cwdlen)) fail (1); - if (strcmp (out+cwdlen, "/./foo")) + else if (strcmp (out+cwdlen, "/./foo")) fail (1); xfree (out); out = make_absfilename_try (".", NULL); if (!out) fail (2); - if (strlen (out) < cwdlen) + else if (strlen (out) < cwdlen) fail (2); - if (strncmp (out, cwd, cwdlen)) + else if (strncmp (out, cwd, cwdlen)) fail (2); - if (strcmp (out+cwdlen, "")) + else if (strcmp (out+cwdlen, "")) fail (2); xfree (out); diff --git a/common/t-timestuff.c b/common/t-timestuff.c index cb7cd39..a80aaff 100644 --- a/common/t-timestuff.c +++ b/common/t-timestuff.c @@ -124,25 +124,28 @@ test_timegm (void) tp = gmtime (&now); if (!tp) fail (tidx); - tbuf = *tp; - tbuf2 = tbuf; + else + { + tbuf = *tp; + tbuf2 = tbuf; #ifdef HAVE_TIMEGM - atime = timegm (&tbuf); + atime = timegm (&tbuf); #else - atime = mktime (&tbuf); + atime = mktime (&tbuf); #endif - if (atime == (time_t)(-1)) - fail (tidx); - if (atime != now) - fail (tidx); - - tp = gmtime (&atime); - if (!tp) - fail (tidx); - if (cmp_time_s (tp, &tbuf)) - fail (tidx); - if (cmp_time_s (tp, &tbuf2)) - fail (tidx); + if (atime == (time_t)(-1)) + fail (tidx); + else if (atime != now) + fail (tidx); + + tp = gmtime (&atime); + if (!tp) + fail (tidx); + else if (cmp_time_s (tp, &tbuf)) + fail (tidx); + else if (cmp_time_s (tp, &tbuf2)) + fail (tidx); + } } } ----------------------------------------------------------------------- Summary of changes: common/b64enc.c | 2 -- common/iobuf.c | 1 - common/t-convert.c | 8 ++++---- common/t-mapstrings.c | 4 ++-- common/t-stringhelp.c | 32 ++++++++++++++++---------------- common/t-timestuff.c | 35 +++++++++++++++++++---------------- common/tlv.c | 1 - common/userids.c | 1 - dirmngr/t-dns-stuff.c | 6 ++++-- g10/encrypt.c | 1 + g10/keyedit.c | 20 +++++++++++++++++--- g10/parse-packet.c | 9 +++++++-- g10/sign.c | 1 + g10/test.c | 11 ++++++----- kbx/keybox-openpgp.c | 1 - kbx/keybox-update.c | 3 +-- tests/openpgp/4gb-packet.test | 6 ++---- 17 files changed, 80 insertions(+), 62 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 6 15:07:58 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Wed, 06 Jan 2016 15:07:58 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-88-g2c3e674 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 2c3e67430d9b523c85c81ae562223fd51e3608cc (commit) from c7389ae90fa4a70766400cc241ff6a45aa750324 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2c3e67430d9b523c85c81ae562223fd51e3608cc Author: Daniel Kahn Gillmor Date: Wed Dec 9 13:01:04 2015 -0500 Fix keystrlen to work when OPT.KEYID_FORMAT is KF_DEFAULT. * g10/keyid.c (keystrlen): If opt.keyid_format is KF_DEFAULT unset, default to KF_SHORT. (format_keyid): Default to KF_SHORT, not KF_0xLONG. -- Without this fix, gpgv2 fails with: gpgv: Ohhhh jeeee: ... this is a bug (keyid.c:342:keystrlen) Signed-off-by: Daniel Kahn Gillmor Signed-off-by: Neal H. Walfield diff --git a/g10/keyid.c b/g10/keyid.c index cb237ef..69acbe4 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -284,7 +284,7 @@ format_keyid (u32 *keyid, int format, char *buffer, int len) if (format == KF_DEFAULT) format = opt.keyid_format; if (format == KF_DEFAULT) - format = KF_0xLONG; + format = KF_SHORT; switch (format) { @@ -324,7 +324,11 @@ format_keyid (u32 *keyid, int format, char *buffer, int len) size_t keystrlen(void) { - switch(opt.keyid_format) + int format = opt.keyid_format; + if (format == KF_DEFAULT) + format = KF_SHORT; + + switch(format) { case KF_SHORT: return 8; ----------------------------------------------------------------------- Summary of changes: g10/keyid.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 7 12:39:34 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 07 Jan 2016 12:39:34 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-1.3.0-45-g1097fe9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 1097fe9bf5d5d5f7b43f01cbf0cc161ba1706c83 (commit) from 4aadd33407535b83b04c62c0cd79c7ca2f0d2ebd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1097fe9bf5d5d5f7b43f01cbf0cc161ba1706c83 Author: Andre Heinecke Date: Thu Jan 7 12:38:56 2016 +0100 Update NEWS with latest changes. * NEWS: Update. diff --git a/NEWS b/NEWS index 7a20126..66a6655 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,11 @@ Noteworthy changes for version 2.0.0 (unreleased) IMAP or Exchange it tries to restore the original mail so that other clients can also read them. + * (OL > 2007) Improved lookup of Exchange Sender address. + + * (OL > 2007) Fixed crash when Exchange Active Sync (Outlook.com) + is used. + Noteworthy changes for version 1.3.0 (2015-11-24) ================================================= ----------------------------------------------------------------------- Summary of changes: NEWS | 5 +++++ 1 file changed, 5 insertions(+) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 7 19:18:23 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 07 Jan 2016 19:18:23 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-94-g8fd406c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 8fd406c317ad7c2e375ae4f7d20656dadf6d7fcc (commit) via 8a56a38387c10c02ba0790c655dd5c1d08e4a724 (commit) via 008aa6e6d4b213c3a0d15509eb46cf168b6f2c94 (commit) via 126aebbb82667d160c8c4435898efeb3b43c4ec8 (commit) via 0de7d61437bd0bfbe645d5eed7a62df03129fb32 (commit) via a41638acf4808caa619f4f3f4c0dcd12be00d6f8 (commit) from 2c3e67430d9b523c85c81ae562223fd51e3608cc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8fd406c317ad7c2e375ae4f7d20656dadf6d7fcc Author: Werner Koch Date: Thu Jan 7 19:07:59 2016 +0100 gpg: Return an error code from keygrip_from_pk. * g10/keyid.c (keygrip_from_pk): Return an error code. -- The error was show but the function did not return it. This change should improve error messages for unknown algorithms. Signed-off-by: Werner Koch diff --git a/g10/keyid.c b/g10/keyid.c index 69acbe4..f684276 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -883,7 +883,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) } gcry_sexp_release (s_pkey); - return 0; + return err; } commit 8a56a38387c10c02ba0790c655dd5c1d08e4a724 Author: Werner Koch Date: Thu Jan 7 19:05:35 2016 +0100 gpg: Avoid warnings about possible NULL deref. * g10/getkey.c (cache_public_key): Protect deref of CE which actually can't happen. * g10/keygen.c (quickgen_set_para): s/sprintf/snprintf/. * g10/tofu.c (end_transaction, rollback_transaction): Allow NULL for DB. * g10/trustdb.c (update_min_ownertrust): Remove useless clearling of ERR. -- Signed-off-by: Werner Koch diff --git a/g10/getkey.c b/g10/getkey.c index 6a1fce6..e66be0d 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -196,7 +196,7 @@ cache_public_key (PKT_public_key * pk) /* Remove the last 50% of the entries. */ for (ce = pk_cache, n = 0; ce && n < pk_cache_entries/2; n++) ce = ce->next; - if (ce != pk_cache && ce->next) + if (ce && ce != pk_cache && ce->next) { ce2 = ce->next; ce->next = NULL; diff --git a/g10/keygen.c b/g10/keygen.c index 40619ca..94ea126 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3395,7 +3395,7 @@ quickgen_set_para (struct para_data_s *para, int for_subkey, para = r; r = xmalloc_clear (sizeof *r + 20); r->key = for_subkey? pSUBKEYTYPE : pKEYTYPE; - sprintf (r->u.value, "%d", algo); + snprintf (r->u.value, 20, "%d", algo); r->next = para; para = r; diff --git a/g10/tofu.c b/g10/tofu.c index b7f61e9..903f076 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -306,6 +306,9 @@ end_transaction (struct db *db, int only_batch) int rc; char *err = NULL; + if (!db) + return 0; /* Shortcut to allow for easier cleanup code. */ + if ((! batch_update || only_batch == 2) && db->batch_update) /* The batch transaction is still in open, but we left batch mode. */ @@ -353,6 +356,9 @@ rollback_transaction (struct db *db) int rc; char *err = NULL; + if (!db) + return 0; /* Shortcut to allow for easier cleanup code. */ + if (db->batch_update) /* Just undo the most recent update; don't revert any progress made by the batch transaction. */ diff --git a/g10/trustdb.c b/g10/trustdb.c index 9217dd9..cb2b5b9 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -781,7 +781,6 @@ update_min_ownertrust (u32 *kid, unsigned int new_trust ) write_record (&rec); tdb_revalidation_mark (); do_sync (); - err = 0; } else { commit 008aa6e6d4b213c3a0d15509eb46cf168b6f2c94 Author: Werner Koch Date: Thu Jan 7 19:01:18 2016 +0100 gpg: Fix warnings about useless assignments. * g10/armor.c (parse_hash_header): Remove duplicate var assignment. * g10/getkey.c (cache_user_id): Ditto. * g10/keygen.c (ask_curve): Ditto. This also fixes a small memory leak. * g10/keygen.c (proc_parameter_file): Remove useless assignment or pointer increment. (generate_keypair): Ditto. * g10/getkey.c (finish_lookup, lookup): Ditto. * g10/card-util.c (change_pin): Ditto. * g10/gpg.c (main) : Ditto. * g10/import.c (import): Ditto. (print_import_check): Ditto * g10/keyring.c (do_copy): Ditto. * g10/tdbio.c (tdbio_read_record): Ditto. * g10/trustdb.c (tdb_update_ownertrust): Ditto. (update_validity): Ditto. * g10/server.c (cmd_passwd): Remove useless call to skip_options. -- Signed-off-by: Werner Koch diff --git a/g10/armor.c b/g10/armor.c index e368660..6c133a2 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -274,7 +274,7 @@ parse_hash_header( const char *line ) return 0; /* too short or too long */ if( memcmp( line, "Hash:", 5 ) ) return 0; /* invalid header */ - s = line+5; + for(s=line+5;;s=s2) { for(; *s && (*s==' ' || *s == '\t'); s++ ) ; diff --git a/g10/card-util.c b/g10/card-util.c index 7196031..b48705b 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -145,7 +145,6 @@ change_pin (int unblock_v2, int allow_admin) if (strlen (answer) != 1) continue; - rc = 0; if (*answer == '1') { /* Change PIN. */ diff --git a/g10/getkey.c b/g10/getkey.c index 86a3c80..6a1fce6 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -300,7 +300,8 @@ cache_user_id (KBNODE keyblock) /* First check for duplicates. */ for (r = user_id_db; r; r = r->next) { - keyid_list_t b = r->keyids; + keyid_list_t b; + for (b = r->keyids; b; b = b->next) { if (!memcmp (b->fpr, a->fpr, MAX_FINGERPRINT_LEN)) @@ -2997,7 +2998,6 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock) if (DBG_LOOKUP) log_debug ("\tprimary key may be used\n"); latest_key = keyblock; - latest_date = pk->timestamp; } } @@ -3074,7 +3074,6 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key, if (rc) { log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - rc = 0; goto skip; } diff --git a/g10/gpg.c b/g10/gpg.c index 0e61238..9b6a142 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3941,7 +3941,6 @@ main (int argc, char **argv) break; case aVerify: - rc = 0; if (multifile) { if ((rc = verify_files (ctrl, argc, argv))) diff --git a/g10/import.c b/g10/import.c index d35b5d5..8e75aa1 100644 --- a/g10/import.c +++ b/g10/import.c @@ -353,7 +353,6 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats, && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX) { stats->not_imported++; - rc = 0; } else if (rc) break; @@ -799,7 +798,6 @@ print_import_check (PKT_public_key * pk, PKT_user_id * id) for (i = 0; i < n; i++, pos += 2) sprintf (buf+pos, "%02X", fpr[i]); strcat (buf, " "); - pos += 1; strcat (buf, id->name); write_status_text (STATUS_IMPORT_CHECK, buf); xfree (buf); diff --git a/g10/keygen.c b/g10/keygen.c index 921e938..40619ca 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2242,10 +2242,7 @@ ask_curve (int *algo, int *subkey_algo) && curves[idx].fix_curve) { if (subkey_algo && *subkey_algo == PUBKEY_ALGO_ECDSA) - { - *subkey_algo = PUBKEY_ALGO_EDDSA; - result = xstrdup ("Ed25519"); - } + *subkey_algo = PUBKEY_ALGO_EDDSA; *algo = PUBKEY_ALGO_EDDSA; result = xstrdup ("Ed25519"); } @@ -3122,6 +3119,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, } else { + r = get_parameter (para, pKEYSERVER); log_error("%s:%d: invalid keyserver url\n", fname, r->lnr ); return -1; } @@ -3706,7 +3704,6 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, || algo == PUBKEY_ALGO_ECDH) { curve = ask_curve (&algo, NULL); - nbits = 0; r = xmalloc_clear (sizeof *r + strlen (curve)); r->key = pKEYCURVE; strcpy (r->u.value, curve); diff --git a/g10/keyring.c b/g10/keyring.c index 0f1e058..4dc7e0a 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1508,6 +1508,8 @@ keyring_rebuild_cache (void *token,int noisy) * the original file is closed */ tmpfp = NULL; } + /* Static analyzer note: BAKFILENAME is never NULL here + because it is controlled by LASTRESNAME. */ rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, lastresname) : 0; xfree (tmpfilename); tmpfilename = NULL; @@ -1720,7 +1722,6 @@ do_copy (int mode, const char *fname, KBNODE root, iobuf_cancel(newfp); goto leave; } - rc = 0; } if( mode == 2 || mode == 3 ) { /* delete or update */ @@ -1764,7 +1765,6 @@ do_copy (int mode, const char *fname, KBNODE root, iobuf_cancel(newfp); goto leave; } - rc = 0; } /* close both files */ diff --git a/g10/server.c b/g10/server.c index e5539d5..31e35a9 100644 --- a/g10/server.c +++ b/g10/server.c @@ -623,7 +623,8 @@ cmd_passwd (assuan_context_t ctx, char *line) gpg_error_t err; (void)ctx; - line = skip_options (line); + (void)line; + /* line = skip_options (line); */ err = gpg_error (GPG_ERR_NOT_SUPPORTED); diff --git a/g10/tdbio.c b/g10/tdbio.c index 63ccfae..3cc8bd3 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -1497,13 +1497,16 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected) rec->r.ver.trust_model = *p++; rec->r.ver.min_cert_level = *p++; p += 2; - rec->r.ver.created = buf32_to_ulong(p); p += 4; - rec->r.ver.nextcheck = buf32_to_ulong(p); p += 4; + rec->r.ver.created = buf32_to_ulong(p); p += 4; + rec->r.ver.nextcheck = buf32_to_ulong(p); p += 4; - rec->r.ver.firstfree =buf32_to_ulong(p); p += 4; p += 4; - rec->r.ver.trusthashtbl =buf32_to_ulong(p); p += 4; + p += 4; + rec->r.ver.firstfree = buf32_to_ulong(p); + p += 4; + p += 4; + rec->r.ver.trusthashtbl = buf32_to_ulong(p); if (recnum) { log_error( _("%s: version record with recnum %lu\n"), db_name, @@ -1520,37 +1523,43 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected) break; case RECTYPE_FREE: - rec->r.free.next = buf32_to_ulong(p); p += 4; + rec->r.free.next = buf32_to_ulong(p); break; case RECTYPE_HTBL: for (i=0; i < ITEMS_PER_HTBL_RECORD; i++) { - rec->r.htbl.item[i] = buf32_to_ulong(p); p += 4; + rec->r.htbl.item[i] = buf32_to_ulong(p); + p += 4; } break; case RECTYPE_HLST: - rec->r.hlst.next = buf32_to_ulong(p); p += 4; + rec->r.hlst.next = buf32_to_ulong(p); + p += 4; for (i=0; i < ITEMS_PER_HLST_RECORD; i++) { - rec->r.hlst.rnum[i] = buf32_to_ulong(p); p += 4; + rec->r.hlst.rnum[i] = buf32_to_ulong(p); + p += 4; } break; case RECTYPE_TRUST: - memcpy (rec->r.trust.fingerprint, p, 20); p+=20; + memcpy (rec->r.trust.fingerprint, p, 20); + p+=20; rec->r.trust.ownertrust = *p++; rec->r.trust.depth = *p++; rec->r.trust.min_ownertrust = *p++; p++; - rec->r.trust.validlist = buf32_to_ulong(p); p += 4; + rec->r.trust.validlist = buf32_to_ulong(p); break; case RECTYPE_VALID: - memcpy (rec->r.valid.namehash, p, 20); p+=20; + memcpy (rec->r.valid.namehash, p, 20); + p+=20; rec->r.valid.validity = *p++; - rec->r.valid.next = buf32_to_ulong(p); p += 4; + rec->r.valid.next = buf32_to_ulong(p); + p += 4; rec->r.valid.full_count = *p++; rec->r.valid.marginal_count = *p++; break; diff --git a/g10/trustdb.c b/g10/trustdb.c index af839d1..9217dd9 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -724,7 +724,6 @@ tdb_update_ownertrust (PKT_public_key *pk, unsigned int new_trust ) write_record (&rec); tdb_revalidation_mark (); do_sync (); - err = 0; } else { @@ -858,7 +857,6 @@ update_validity (PKT_public_key *pk, PKT_user_id *uid, /* No record yet - create a new one. */ size_t dummy; - err = 0; memset (&trec, 0, sizeof trec); trec.recnum = tdbio_new_recnum (); trec.rectype = RECTYPE_TRUST; commit 126aebbb82667d160c8c4435898efeb3b43c4ec8 Author: Werner Koch Date: Wed Jan 6 17:51:58 2016 +0100 sm: Avoid warnings about useless assignments. * sm/call-dirmngr.c (prepare_dirmngr): Remove setting of ERR. (unhexify_fpr): Remove useless computation on N. * sm/certchain.c (do_validate_chain): Remove clearing of RC. Remove useless setting of RC. * sm/fingerprint.c (gpgsm_get_keygrip): Remove setting of RC. * sm/gpgsm.c (build_list): Replace final stpcpy by strcpy. * sm/keydb.c (keydb_clear_some_cert_flags): Remove clearing of RC. * sm/server.c (cmd_getauditlog): Comment unused skip_options. Signed-off-by: Werner Koch diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index b06397f..379d7e9 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -181,9 +181,11 @@ prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err) server->host, server->port, user, pass, base); line[DIM (line) - 1] = 0; - err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD) - err = 0; /* Allow the use of old dirmngr versions. */ + assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + /* The code below is not required becuase we don't return an error. */ + /* err = [above call] */ + /* if (gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD) */ + /* err = 0; /\* Allow the use of old dirmngr versions. *\/ */ server = server->next; } @@ -402,7 +404,6 @@ unhexify_fpr (const char *hexstr, unsigned char *fpr) ; if (*s || (n != 40)) return 0; /* no fingerprint (invalid or wrong length). */ - n /= 2; for (s=hexstr, n=0; *s; s += 2, n++) fpr[n] = xtoi_2 (s); return 1; /* okay */ diff --git a/sm/certchain.c b/sm/certchain.c index d43147e..b884d3d 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -405,7 +405,9 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist) } while (!*p || *p == '\n' || *p == '#'); - /* parse line */ + /* Parse line. Note that the line has always a LF and spacep + does not consider a LF a space. Thus strpbrk will always + succeed. */ for (allowed=line; spacep (allowed); allowed++) ; p = strpbrk (allowed, " :\n"); @@ -1389,10 +1391,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, exptime, listmode, listfp, (depth && is_root)? -1: depth); if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED) - { - any_expired = 1; - rc = 0; - } + any_expired = 1; else if (rc) goto leave; @@ -1409,7 +1408,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, if (gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH) { any_no_policy_match = 1; - rc = 1; + rc = 1; /* Be on the safe side and set RC. */ } else if (rc) goto leave; @@ -1612,7 +1611,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, /* The find next did not work or returned an identical certificate. We better stop here to avoid infinite checks. */ - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); + /* No need to set RC because it is not used: + rc = gpg_error (GPG_ERR_BAD_SIGNATURE); */ ksba_cert_release (tmp_cert); } else diff --git a/sm/fingerprint.c b/sm/fingerprint.c index a82945e..8d2b800 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -192,7 +192,6 @@ gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array) gcry_sexp_release (s_pkey); if (!array) { - rc = gpg_error (GPG_ERR_GENERAL); log_error ("can't calculate keygrip\n"); return NULL; } diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 262781c..a0b7038 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -630,7 +630,7 @@ build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int)) } } if (p) - p = stpcpy(p, "\n" ); + strcpy (p, "\n" ); return list; } diff --git a/sm/keydb.c b/sm/keydb.c index 02b353a..168cf2c 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -1291,11 +1291,7 @@ keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names) { rc = classify_user_id (sl->d, desc+ndesc, 0); if (rc) - { - log_error ("key '%s' not found: %s\n", - sl->d, gpg_strerror (rc)); - rc = 0; - } + log_error ("key '%s' not found: %s\n", sl->d, gpg_strerror (rc)); else ndesc++; } diff --git a/sm/server.c b/sm/server.c index f0512ef..e21c6a4 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1083,7 +1083,7 @@ cmd_getauditlog (assuan_context_t ctx, char *line) opt_data = has_option (line, "--data"); opt_html = has_option (line, "--html"); - line = skip_options (line); + /* Not needed: line = skip_options (line); */ if (!ctrl->audit) return gpg_error (GPG_ERR_NO_DATA); commit 0de7d61437bd0bfbe645d5eed7a62df03129fb32 Author: Werner Koch Date: Wed Jan 6 17:46:44 2016 +0100 kbx: Avoid warnings about useless assignments. * kbx/keybox-dump.c (_keybox_dump_blob): Remove setting of IN_RANGE and the last increment of P. -- Signed-off-by: Werner Koch diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index 8815a6f..f4e7c98 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -388,21 +388,21 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) putc ('\n', fp ); } if (in_range) - { - fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); - in_range = 0; - } + fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); } fprintf (fp, "Ownertrust: %d\n", p[0] ); fprintf (fp, "All-Validity: %d\n", p[1] ); p += 4; - n = get32 (p); p += 4; + n = get32 (p); + p += 4; fprintf (fp, "Recheck-After: %lu\n", n ); - n = get32 (p ); p += 4; + n = get32 (p ); + p += 4; fprintf( fp, "Latest-Timestamp: %lu\n", n ); - n = get32 (p ); p += 4; + n = get32 (p ); + p += 4; fprintf (fp, "Created-At: %lu\n", n ); - n = get32 (p ); p += 4; + n = get32 (p ); fprintf (fp, "Reserved-Space: %lu\n", n ); if (n >= 4 && unhashed >= 24) commit a41638acf4808caa619f4f3f4c0dcd12be00d6f8 Author: Werner Koch Date: Wed Jan 6 16:39:04 2016 +0100 gpg: Fix DNS cert lookup returning an URL. * g10/call-dirmngr.c (dns_cert_status_cb): Store URL status in the URL param. The old code was entirely buggy (c+p error). -- Fixes-commit: 154f3ed2 Signed-off-by: Werner Koch diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index 83af0be..b1c856d 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -1080,10 +1080,8 @@ dns_cert_status_cb (void *opaque, const char *line) { if (parm->url) err = gpg_error (GPG_ERR_DUP_KEY); - else if (!(parm->fpr = xtrymalloc (nbytes))) + else if (!(parm->url = xtrystrdup (s))) err = gpg_error_from_syserror (); - else - memcpy (parm->fpr, line, (parm->fprlen = nbytes)); } return err; ----------------------------------------------------------------------- Summary of changes: g10/armor.c | 2 +- g10/call-dirmngr.c | 4 +--- g10/card-util.c | 1 - g10/getkey.c | 7 +++---- g10/gpg.c | 1 - g10/import.c | 2 -- g10/keygen.c | 9 +++------ g10/keyid.c | 2 +- g10/keyring.c | 4 ++-- g10/server.c | 3 ++- g10/tdbio.c | 33 +++++++++++++++++++++------------ g10/tofu.c | 6 ++++++ g10/trustdb.c | 3 --- kbx/keybox-dump.c | 16 ++++++++-------- sm/call-dirmngr.c | 9 +++++---- sm/certchain.c | 14 +++++++------- sm/fingerprint.c | 1 - sm/gpgsm.c | 2 +- sm/keydb.c | 6 +----- sm/server.c | 2 +- 20 files changed, 63 insertions(+), 64 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 8 06:47:26 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jan 2016 06:47:26 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-96-g4966432 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 496643291e1e346434e9c98405c5a370957eb7d3 (commit) via 833ba5faa1340aff80a205acbb701d4ae1d594d0 (commit) from 8fd406c317ad7c2e375ae4f7d20656dadf6d7fcc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 496643291e1e346434e9c98405c5a370957eb7d3 Author: Werner Koch Date: Fri Jan 8 06:42:29 2016 +0100 common: New function get_assuan_server_version. * common/asshelp.c: Include membuf.h. (get_assuan_server_version): New. * g10/call-agent.c (agent_get_version): Use new function. -- Signed-off-by: Werner Koch diff --git a/common/asshelp.c b/common/asshelp.c index d33ffb5..f2b4402 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -42,6 +42,7 @@ #include "exechelp.h" #include "sysutils.h" #include "status.h" +#include "membuf.h" #include "asshelp.h" /* The type we use for lock_agent_spawning. */ @@ -699,3 +700,40 @@ start_new_dirmngr (assuan_context_t *r_ctx, *r_ctx = ctx; return 0; } + + +/* Return the version of a server using "GETINFO version". On success + 0 is returned and R_VERSION receives a malloced string with the + version which must be freed by the caller. On error NULL is stored + at R_VERSION and an error code returned. Mode is in general 0 but + certian values may be used to modify the used version command: + + MODE == 0 = Use "GETINFO version" + MODE == 2 - Use "SCD GETINFO version" + */ +gpg_error_t +get_assuan_server_version (assuan_context_t ctx, int mode, char **r_version) +{ + gpg_error_t err; + membuf_t data; + + init_membuf (&data, 64); + err = assuan_transact (ctx, + mode == 2? "SCD GETINFO version" + /**/ : "GETINFO version", + put_membuf_cb, &data, + NULL, NULL, NULL, NULL); + if (err) + { + xfree (get_membuf (&data, NULL)); + *r_version = NULL; + } + else + { + put_membuf (&data, "", 1); + *r_version = get_membuf (&data, NULL); + if (!*r_version) + err = gpg_error_from_syserror (); + } + return err; +} diff --git a/common/asshelp.h b/common/asshelp.h index 35d2115..20414bd 100644 --- a/common/asshelp.h +++ b/common/asshelp.h @@ -74,6 +74,10 @@ start_new_dirmngr (assuan_context_t *r_ctx, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg); +/* Return the version of a server using "GETINFO version". */ +gpg_error_t get_assuan_server_version (assuan_context_t ctx, + int mode, char **r_version); + /*-- asshelp2.c --*/ diff --git a/g10/call-agent.c b/g10/call-agent.c index 363fc85..3600579 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2408,27 +2408,11 @@ gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version) { gpg_error_t err; - membuf_t data; err = start_agent (ctrl, 0); if (err) return err; - init_membuf (&data, 64); - err = assuan_transact (agent_ctx, "GETINFO version", - put_membuf_cb, &data, - NULL, NULL, NULL, NULL); - if (err) - { - xfree (get_membuf (&data, NULL)); - *r_version = NULL; - } - else - { - put_membuf (&data, "", 1); - *r_version = get_membuf (&data, NULL); - if (!*r_version) - err = gpg_error_from_syserror (); - } + err = get_assuan_server_version (agent_ctx, 0, r_version); return err; } commit 833ba5faa1340aff80a205acbb701d4ae1d594d0 Author: Werner Koch Date: Fri Jan 8 06:33:27 2016 +0100 common: New put_membuf_cb to replace static membuf_data_cb. * common/membuf.c (put_membuf_cb): New. * agent/call-scd.c (membuf_data_cb): Remove. Change callers to use put_membuf_cb. * common/get-passphrase.c (membuf_data_cb): Ditto. * g10/call-agent.c (membuf_data_cb): Ditto. * sm/call-agent.c (membuf_data_cb): Ditto. -- Signed-off-by: Werner Koch diff --git a/agent/call-scd.c b/agent/call-scd.c index 9c4d7b1..b776840 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -113,8 +113,6 @@ static int primary_scd_ctx_reusable; /* Local prototypes. */ -static gpg_error_t membuf_data_cb (void *opaque, - const void *buffer, size_t length); @@ -354,7 +352,7 @@ start_scd (ctrl_t ctrl) socket_name = NULL; init_membuf (&data, 256); assuan_transact (ctx, "GETINFO socket_name", - membuf_data_cb, &data, NULL, NULL, NULL, NULL); + put_membuf_cb, &data, NULL, NULL, NULL, NULL); databuf = get_membuf (&data, &datalen); if (databuf && datalen) @@ -688,16 +686,6 @@ agent_card_serialno (ctrl_t ctrl, char **r_serialno) -static gpg_error_t -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - /* Handle the NEEDPIN inquiry. */ static gpg_error_t inq_needpin (void *opaque, const char *line) @@ -855,7 +843,7 @@ agent_card_pksign (ctrl_t ctrl, snprintf (line, sizeof line, "PKSIGN %s %s", hash_algo_option (mdalgo), keyid); rc = assuan_transact (ctrl->scd_local->ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, inq_needpin, &inqparm, NULL, NULL); if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || @@ -944,7 +932,7 @@ agent_card_pkdecrypt (ctrl_t ctrl, snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid); line[DIM(line)-1] = 0; rc = assuan_transact (ctrl->scd_local->ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, inq_needpin, &inqparm, padding_info_cb, r_padding); if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || @@ -984,7 +972,7 @@ agent_card_readcert (ctrl_t ctrl, snprintf (line, DIM(line)-1, "READCERT %s", id); line[DIM(line)-1] = 0; rc = assuan_transact (ctrl->scd_local->ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, NULL, NULL, NULL, NULL); if (rc) @@ -1020,7 +1008,7 @@ agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf) snprintf (line, DIM(line)-1, "READKEY %s", id); line[DIM(line)-1] = 0; rc = assuan_transact (ctrl->scd_local->ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, NULL, NULL, NULL, NULL); if (rc) diff --git a/common/get-passphrase.c b/common/get-passphrase.c index 53ce7d1..f1517fb 100644 --- a/common/get-passphrase.c +++ b/common/get-passphrase.c @@ -130,17 +130,6 @@ default_inq_cb (void *opaque, const char *line) } -static gpg_error_t -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - - /* Ask for a passphrase via gpg-agent. On success the caller needs to free the string stored at R_PASSPHRASE. On error NULL will be stored at R_PASSPHRASE and an appropriate gpg error code is @@ -214,7 +203,7 @@ gnupg_get_passphrase (const char *cache_id, else init_membuf (&data, 64); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, NULL, NULL, NULL); /* Older Pinentries return the old assuan error code for canceled diff --git a/common/membuf.c b/common/membuf.c index f4430a9..fde24f6 100644 --- a/common/membuf.c +++ b/common/membuf.c @@ -116,6 +116,20 @@ put_membuf (membuf_t *mb, const void *buf, size_t len) } +/* A variant of put_membuf accepting a void * and returning a + gpg_error_t (which will always return 0) to be used as a generic + callback handler. This function also allows buffer to be NULL. */ +gpg_error_t +put_membuf_cb (void *opaque, const void *buf, size_t len) +{ + membuf_t *data = opaque; + + if (buf) + put_membuf (data, buf, len); + return 0; +} + + void put_membuf_str (membuf_t *mb, const char *string) { diff --git a/common/membuf.h b/common/membuf.h index eb7d565..a1610b6 100644 --- a/common/membuf.h +++ b/common/membuf.h @@ -53,6 +53,7 @@ void init_membuf (membuf_t *mb, int initiallen); void init_membuf_secure (membuf_t *mb, int initiallen); void clear_membuf (membuf_t *mb, size_t amount); void put_membuf (membuf_t *mb, const void *buf, size_t len); +gpg_error_t put_membuf_cb (void *opaque, const void *buf, size_t len); void put_membuf_str (membuf_t *mb, const char *string); void put_membuf_printf (membuf_t *mb, const char *format, ...) GPGRT_ATTR_PRINTF(2,3); diff --git a/g10/call-agent.c b/g10/call-agent.c index 26de72e..363fc85 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -137,18 +137,6 @@ status_sc_op_failure (int rc) } -static gpg_error_t -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - - - /* This is the default inquiry callback. It mainly handles the Pinentry notifications. */ static gpg_error_t @@ -214,7 +202,7 @@ check_hijacking (assuan_context_t ctx) /* AGENT_ID is a command implemented by gnome-keyring-daemon. It does not return any data but an OK line with a remark. */ if (assuan_transact (ctx, "AGENT_ID", - membuf_data_cb, &mb, NULL, NULL, NULL, NULL)) + put_membuf_cb, &mb, NULL, NULL, NULL, NULL)) { xfree (get_membuf (&mb, NULL)); return; /* Error - Probably not hijacked. */ @@ -780,7 +768,7 @@ agent_scd_apdu (const char *hexapdu, unsigned int *r_sw) snprintf (line, DIM(line)-1, "SCD APDU %s", hexapdu); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &mb, NULL, NULL, NULL, NULL); + put_membuf_cb, &mb, NULL, NULL, NULL, NULL); if (!err) { data = get_membuf (&mb, &datalen); @@ -1292,7 +1280,7 @@ agent_scd_readcert (const char *certidstr, snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr); line[DIM(line)-1] = 0; rc = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, &dfltparm, NULL, NULL); if (rc) @@ -1455,7 +1443,7 @@ agent_get_passphrase (const char *cache_id, init_membuf_secure (&data, 64); rc = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, &dfltparm, NULL, NULL); @@ -1553,7 +1541,7 @@ agent_get_s2k_count (unsigned long *r_count) init_membuf (&data, 32); err = assuan_transact (agent_ctx, "GETINFO s2k_count", - membuf_data_cb, &data, + put_membuf_cb, &data, NULL, NULL, NULL, NULL); if (err) xfree (get_membuf (&data, NULL)); @@ -1825,7 +1813,7 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, cn_parm.cache_nonce_addr = cache_nonce_addr; cn_parm.passwd_nonce_addr = NULL; err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, inq_genkey_parms, &gk_parm, cache_nonce_status_cb, &cn_parm); if (err) @@ -1879,7 +1867,7 @@ agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, init_membuf (&data, 1024); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, &dfltparm, NULL, NULL); if (err) @@ -1967,7 +1955,7 @@ agent_pksign (ctrl_t ctrl, const char *cache_nonce, cache_nonce? " -- ":"", cache_nonce? cache_nonce:""); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, &dfltparm, NULL, NULL); if (err) @@ -2097,7 +2085,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, if (err) return err; err = assuan_transact (agent_ctx, "PKDECRYPT", - membuf_data_cb, &data, + put_membuf_cb, &data, inq_ciphertext_cb, &parm, padding_info_cb, r_padding); xfree (parm.ciphertext); @@ -2177,7 +2165,7 @@ agent_keywrap_key (ctrl_t ctrl, int forexport, void **r_kek, size_t *r_keklen) init_membuf_secure (&data, 64); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, &dfltparm, NULL, NULL); if (err) @@ -2309,7 +2297,7 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc, cn_parm.cache_nonce_addr = cache_nonce_addr; cn_parm.passwd_nonce_addr = NULL; err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, &dfltparm, cache_nonce_status_cb, &cn_parm); if (err) @@ -2428,7 +2416,7 @@ agent_get_version (ctrl_t ctrl, char **r_version) init_membuf (&data, 64); err = assuan_transact (agent_ctx, "GETINFO version", - membuf_data_cb, &data, + put_membuf_cb, &data, NULL, NULL, NULL, NULL); if (err) { diff --git a/sm/call-agent.c b/sm/call-agent.c index c1457b6..b881fb8 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -128,18 +128,6 @@ start_agent (ctrl_t ctrl) } - -static gpg_error_t -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - - /* This is the default inquiry callback. It mainly handles the Pinentry notifications. */ static gpg_error_t @@ -215,7 +203,7 @@ gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, init_membuf (&data, 1024); rc = assuan_transact (agent_ctx, "PKSIGN", - membuf_data_cb, &data, default_inq_cb, ctrl, + put_membuf_cb, &data, default_inq_cb, ctrl, NULL, NULL); if (rc) { @@ -282,7 +270,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc, snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s", hashopt, keyid); line[DIM(line)-1] = 0; rc = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, default_inq_cb, ctrl, + put_membuf_cb, &data, default_inq_cb, ctrl, NULL, NULL); if (rc) { @@ -392,7 +380,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, cipher_parm.ciphertext = ciphertext; cipher_parm.ciphertextlen = ciphertextlen; rc = assuan_transact (agent_ctx, "PKDECRYPT", - membuf_data_cb, &data, + put_membuf_cb, &data, inq_ciphertext_cb, &cipher_parm, NULL, NULL); if (rc) { @@ -487,7 +475,7 @@ gpgsm_agent_genkey (ctrl_t ctrl, if (!gk_parm.sexplen) return gpg_error (GPG_ERR_INV_VALUE); rc = assuan_transact (agent_ctx, "GENKEY", - membuf_data_cb, &data, + put_membuf_cb, &data, inq_genkey_parms, &gk_parm, NULL, NULL); if (rc) { @@ -536,7 +524,7 @@ gpgsm_agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, init_membuf (&data, 1024); rc = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, ctrl, NULL, NULL); if (rc) { @@ -1117,7 +1105,7 @@ gpgsm_agent_ask_passphrase (ctrl_t ctrl, const char *desc_msg, int repeat, init_membuf_secure (&data, 64); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, NULL, NULL, NULL); if (err) @@ -1157,7 +1145,7 @@ gpgsm_agent_keywrap_key (ctrl_t ctrl, int forexport, init_membuf_secure (&data, 64); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, ctrl, NULL, NULL); if (err) { @@ -1251,7 +1239,7 @@ gpgsm_agent_export_key (ctrl_t ctrl, const char *keygrip, const char *desc, init_membuf_secure (&data, 1024); err = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, + put_membuf_cb, &data, default_inq_cb, ctrl, NULL, NULL); if (err) { ----------------------------------------------------------------------- Summary of changes: agent/call-scd.c | 22 +++++---------------- common/asshelp.c | 38 ++++++++++++++++++++++++++++++++++++ common/asshelp.h | 4 ++++ common/get-passphrase.c | 13 +------------ common/membuf.c | 14 +++++++++++++ common/membuf.h | 1 + g10/call-agent.c | 52 ++++++++++++------------------------------------- sm/call-agent.c | 28 ++++++++------------------ 8 files changed, 83 insertions(+), 89 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 8 10:38:16 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jan 2016 10:38:16 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-98-g2aa42ba Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 2aa42baaf3dd7c3ae613ae0c61760a17c8adfcd0 (commit) via 4d7ac43ff71fdadfd2e04621f74840a82fbe788a (commit) from 496643291e1e346434e9c98405c5a370957eb7d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2aa42baaf3dd7c3ae613ae0c61760a17c8adfcd0 Author: Werner Koch Date: Fri Jan 8 10:33:19 2016 +0100 Print warnings if old daemon versions are used. * common/status.h (STATUS_WARNING): New. * g10/call-agent.c (warn_version_mismatch): New. (start_agent): Call warn function. * g10/call-dirmngr.c: Include status.h. (warn_version_mismatch): New. (create_context): Call warn function. * sm/call-agent.c (warn_version_mismatch): New. (start_agent): Call warn function. (gpgsm_agent_learn): Call warn function. * sm/call-dirmngr.c (warn_version_mismatch): New. (prepare_dirmngr): Call warn function. -- We have seen too often bug reports which are due to still running old versions of the daemons. To catch this problematic use we now print warning messages and also provide the warning via the status interface. Signed-off-by: Werner Koch diff --git a/common/status.h b/common/status.h index 509e044..e50827f 100644 --- a/common/status.h +++ b/common/status.h @@ -141,6 +141,7 @@ enum STATUS_PLAINTEXT_FOLLOWS, /* Used by g13-syshelp */ STATUS_ERROR, + STATUS_WARNING, STATUS_SUCCESS, STATUS_FAILURE, diff --git a/doc/DETAILS b/doc/DETAILS index 7c3e67c..69c2e5b 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -840,7 +840,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: should not contain spaces. The error code is a either a string commencing with a letter or such a string prefixed with a numerical error code and an underscore; e.g.: "151011327_EOF". - +*** WARNING [] + This is a generic warning status message, it might be followed by + error location specific data. and + should not contain spaces. The error code is a either a string + commencing with a letter or such a string prefixed with a + numerical error code and an underscore; e.g.: "151011327_EOF". *** SUCCESS [] Postive confirmation that an operation succeeded. It is used similar to ISO-C's EXIT_SUCCESS. is optional but if diff --git a/g10/call-agent.c b/g10/call-agent.c index 3600579..83fabcc 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -253,6 +253,40 @@ check_hijacking (assuan_context_t ctx) +/* Print a warning if the server's version number is less than our + version number. Returns an error code on a connection problem. */ +static gpg_error_t +warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode) +{ + gpg_error_t err; + char *serverversion; + const char *myversion = strusage (13); + + err = get_assuan_server_version (ctx, mode, &serverversion); + if (err) + log_error (_("error getting version from '%s': %s\n"), + servername, gpg_strerror (err)); + else if (!compare_version_strings (serverversion, myversion)) + { + char *warn; + + warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"), + servername, serverversion, myversion); + if (!warn) + err = gpg_error_from_syserror (); + else + { + log_info (_("WARNING: %s\n"), warn); + write_status_strings (STATUS_WARNING, "server_version_mismatch 0", + " ", warn, NULL); + xfree (warn); + } + } + xfree (serverversion); + return err; +} + + /* Try to connect to the agent via socket or fork it off and work by pipes. Handle the server's initial greeting */ static int @@ -286,7 +320,8 @@ start_agent (ctrl_t ctrl, int for_card) log_info (_("no gpg-agent running in this session\n")); } } - else if (!rc) + else if (!rc + && !(rc = warn_version_mismatch (agent_ctx, GPG_AGENT_NAME, 0))) { /* Tell the agent that we support Pinentry notifications. No error checking so that it will work also with older @@ -324,9 +359,12 @@ start_agent (ctrl_t ctrl, int for_card) struct agent_card_info_s info; memset (&info, 0, sizeof info); - rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp", - NULL, NULL, NULL, NULL, - learn_status_cb, &info); + + rc = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2); + if (!rc) + rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp", + NULL, NULL, NULL, NULL, + learn_status_cb, &info); if (rc) { switch (gpg_err_code (rc)) diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index b1c856d..360e127 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -38,6 +38,7 @@ #include "i18n.h" #include "asshelp.h" #include "keyserver.h" +#include "status.h" #include "call-dirmngr.h" @@ -132,6 +133,40 @@ gpg_dirmngr_deinit_session_data (ctrl_t ctrl) } +/* Print a warning if the server's version number is less than our + version number. Returns an error code on a connection problem. */ +static gpg_error_t +warn_version_mismatch (assuan_context_t ctx, const char *servername) +{ + gpg_error_t err; + char *serverversion; + const char *myversion = strusage (13); + + err = get_assuan_server_version (ctx, 0, &serverversion); + if (err) + log_error (_("error getting version from '%s': %s\n"), + servername, gpg_strerror (err)); + else if (!compare_version_strings (serverversion, myversion)) + { + char *warn; + + warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"), + servername, serverversion, myversion); + if (!warn) + err = gpg_error_from_syserror (); + else + { + log_info (_("WARNING: %s\n"), warn); + write_status_strings (STATUS_WARNING, "server_version_mismatch 0", + " ", warn, NULL); + xfree (warn); + } + } + xfree (serverversion); + return err; +} + + /* Try to connect to the Dirmngr via a socket or spawn it if possible. Handle the server's initial greeting and set global options. */ static gpg_error_t @@ -157,7 +192,7 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx) log_info (_("no dirmngr running in this session\n")); } } - else if (!err) + else if (!err && !(err = warn_version_mismatch (ctx, DIRMNGR_NAME))) { char *line; diff --git a/sm/call-agent.c b/sm/call-agent.c index b881fb8..c7d4c5a 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -76,6 +76,41 @@ struct import_key_parm_s +/* Print a warning if the server's version number is less than our + version number. Returns an error code on a connection problem. */ +static gpg_error_t +warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx, + const char *servername, int mode) +{ + gpg_error_t err; + char *serverversion; + const char *myversion = strusage (13); + + err = get_assuan_server_version (ctx, mode, &serverversion); + if (err) + log_error (_("error getting version from '%s': %s\n"), + servername, gpg_strerror (err)); + else if (!compare_version_strings (serverversion, myversion)) + { + char *warn; + + warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"), + servername, serverversion, myversion); + if (!warn) + err = gpg_error_from_syserror (); + else + { + log_info (_("WARNING: %s\n"), warn); + gpgsm_status2 (ctrl, STATUS_WARNING, "server_version_mismatch 0", + warn, NULL); + xfree (warn); + } + } + xfree (serverversion); + return err; +} + + /* Try to connect to the agent via socket or fork it off and work by pipes. Handle the server's initial greeting */ static int @@ -108,7 +143,8 @@ start_agent (ctrl_t ctrl) log_info (_("no gpg-agent running in this session\n")); } } - else if (!rc) + else if (!rc && !(rc = warn_version_mismatch (ctrl, agent_ctx, + GPG_AGENT_NAME, 0))) { /* Tell the agent that we support Pinentry notifications. No error checking so that it will work also with older @@ -919,6 +955,10 @@ gpgsm_agent_learn (ctrl_t ctrl) if (rc) return rc; + rc = warn_version_mismatch (ctrl, agent_ctx, SCDAEMON_NAME, 2); + if (rc) + return rc; + init_membuf (&data, 4096); learn_parm.error = 0; learn_parm.ctrl = ctrl; diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 379d7e9..881c484 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -149,6 +149,41 @@ get_membuf (struct membuf *mb, size_t *len) } +/* Print a warning if the server's version number is less than our + version number. Returns an error code on a connection problem. */ +static gpg_error_t +warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx, + const char *servername, int mode) +{ + gpg_error_t err; + char *serverversion; + const char *myversion = strusage (13); + + err = get_assuan_server_version (ctx, mode, &serverversion); + if (err) + log_error (_("error getting version from '%s': %s\n"), + servername, gpg_strerror (err)); + else if (!compare_version_strings (serverversion, myversion)) + { + char *warn; + + warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"), + servername, serverversion, myversion); + if (!warn) + err = gpg_error_from_syserror (); + else + { + log_info (_("WARNING: %s\n"), warn); + gpgsm_status2 (ctrl, STATUS_WARNING, "server_version_mismatch 0", + warn, NULL); + xfree (warn); + } + } + xfree (serverversion); + return err; +} + + /* This function prepares the dirmngr for a new session. The audit-events option is used so that other dirmngr clients won't get disturbed by such events. */ @@ -158,6 +193,9 @@ prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err) struct keyserver_spec *server; if (!err) + err = warn_version_mismatch (ctrl, ctx, DIRMNGR_NAME, 0); + + if (!err) { err = assuan_transact (ctx, "OPTION audit-events=1", NULL, NULL, NULL, NULL, NULL, NULL); commit 4d7ac43ff71fdadfd2e04621f74840a82fbe788a Author: Werner Koch Date: Fri Jan 8 08:58:21 2016 +0100 common: New function compare_version_strings. * common/stringhelp.c (parse_version_number): New. (parse_version_string): New. (compare_version_strings): New. * common/t-stringhelp.c (test_compare_version_strings): New. (main): Call test. Return ERRCOUNT instead of 0. -- The code for that function is based on code from libgcrypt. Similar code is in all GnuPG related libraries this function is a candidates for inclusion in libgpg-error. Signed-off-by: Werner Koch diff --git a/common/stringhelp.c b/common/stringhelp.c index e8b990a..8b47a1c 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -1329,6 +1329,91 @@ strtokenize (const char *string, const char *delim) } + +/* Version number parsing. */ + +/* This function parses the first portion of the version number S and + stores it in *NUMBER. On success, this function returns a pointer + into S starting with the first character, which is not part of the + initial number portion; on failure, NULL is returned. */ +static const char* +parse_version_number (const char *s, int *number) +{ + int val = 0; + + if (*s == '0' && digitp (s+1)) + return NULL; /* Leading zeros are not allowed. */ + for (; digitp (s); s++) + { + val *= 10; + val += *s - '0'; + } + *number = val; + return val < 0 ? NULL : s; +} + + +/* This function breaks up the complete string-representation of the + version number S, which is of the following struture: ... The major, + minor and micro number components will be stored in *MAJOR, *MINOR + and *MICRO. + + On success, the last component, the patch level, will be returned; + in failure, NULL will be returned. */ +static const char * +parse_version_string (const char *s, int *major, int *minor, int *micro) +{ + s = parse_version_number (s, major); + if (!s || *s != '.') + return NULL; + s++; + s = parse_version_number (s, minor); + if (!s) + return NULL; + if (*s == '.') + { + s++; + s = parse_version_number (s, micro); + if (!s) + return NULL; + } + else + *micro = 0; + return s; /* Patchlevel. */ +} + + +/* Check that the version string MY_VERSION is greater or equal than + REQ_VERSION. Returns true if the condition is satisfied or false + if not. This works with 3 part and two part version strings; for a + two part version string the micor part is assumed to be 0. */ +int +compare_version_strings (const char *my_version, const char *req_version) +{ + int my_major, my_minor, my_micro; + int rq_major, rq_minor, rq_micro; + + if (!my_version || !req_version) + return 0; + + if (!parse_version_string (my_version, &my_major, &my_minor, &my_micro)) + return 0; + if (!parse_version_string(req_version, &rq_major, &rq_minor, &rq_micro)) + return 0; + + if (my_major > rq_major + || (my_major == rq_major && my_minor > rq_minor) + || (my_major == rq_major && my_minor == rq_minor + && my_micro >= rq_micro)) + { + return 1; + } + return 0; +} + + + /* Format a string so that it fits within about TARGET_COLS columns. If IN_PLACE is 0, then TEXT is copied to a new buffer, which is returned. Otherwise, TEXT is modified in place and returned. diff --git a/common/stringhelp.h b/common/stringhelp.h index c813662..d9225a3 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -148,6 +148,9 @@ char **strsplit (char *string, char delim, char replacement, int *count); /* Tokenize STRING using the set of delimiters in DELIM. */ char **strtokenize (const char *string, const char *delim); +/* Return True if MYVERSION is greater or equal than REQ_VERSION. */ +int compare_version_strings (const char *my_version, const char *req_version); + /* Format a string so that it fits within about TARGET_COLS columns. */ char *format_text (char *text, int in_place, int target_cols, int max_cols); diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c index af79cb5..b4a41ac 100644 --- a/common/t-stringhelp.c +++ b/common/t-stringhelp.c @@ -705,6 +705,7 @@ stresc (char *s) return p; } + static void test_format_text (void) { @@ -813,6 +814,65 @@ test_format_text (void) fail(0); } + +static void +test_compare_version_strings (void) +{ + struct { const char *a; const char *b; int okay; } tests[] = { + { "1.0.0", "1.0.0", 1 }, + { "1.0.0-", "1.0.0", 1 }, + { "1.0.0-1", "1.0.0", 1 }, + { "1.0.0.1", "1.0.0", 1 }, + { "1.0.0", "1.0.1", 0 }, + { "1.0.0-", "1.0.1", 0 }, + { "1.0.0-1", "1.0.1", 0 }, + { "1.0.0.1", "1.0.1", 0 }, + { "1.0.0", "1.1.0", 0 }, + { "1.0.0-", "1.1.0", 0 }, + { "1.0.0-1", "1.1.0", 0 }, + { "1.0.0.1", "1.1.0", 0 }, + + { "1.0.0", "1.0.0-", 1 }, + { "1.0.0", "1.0.0-1", 1 }, + { "1.0.0", "1.0.0.1", 1 }, + { "1.1.0", "1.0.0", 1 }, + { "1.1.1", "1.1.0", 1 }, + { "1.1.2", "1.1.2", 1 }, + { "1.1.2", "1.0.2", 1 }, + { "1.1.2", "0.0.2", 1 }, + { "1.1.2", "1.1.3", 0 }, + + { "0.99.1", "0.9.9", 1 }, + { "0.9.1", "0.91.0", 0 }, + + { "1.5.3", "1.5", 1 }, + { "1.5.0", "1.5", 1 }, + { "1.4.99", "1.5", 0 }, + { "1.5", "1.4.99", 1 }, + { "1.5", "1.5.0", 1 }, + { "1.5", "1.5.1", 0 }, + + { "1.5.3-x17", "1.5-23", 1 }, + + { "1.5.3a", "1.5.3", 1 }, + { "1.5.3a", "1.5.3b", 1 }, + + { NULL, NULL, 0 } + }; + int idx; + int res; + + for (idx=0; idx < DIM(tests); idx++) + { + res = compare_version_strings (tests[idx].a, tests[idx].b); + /* printf ("test %d: '%s' '%s' %d -> %d\n", */ + /* idx, tests[idx].a, tests[idx].b, tests[idx].okay, res); */ + if (res != tests[idx].okay) + fail (idx); + } +} + + int main (int argc, char **argv) { @@ -827,8 +887,9 @@ main (int argc, char **argv) test_make_absfilename_try (); test_strsplit (); test_strtokenize (); + test_compare_version_strings (); test_format_text (); xfree (home_buffer); - return 0; + return !!errcount; } ----------------------------------------------------------------------- Summary of changes: common/status.h | 1 + common/stringhelp.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ common/stringhelp.h | 3 ++ common/t-stringhelp.c | 63 +++++++++++++++++++++++++++++++++++++- doc/DETAILS | 7 ++++- g10/call-agent.c | 46 +++++++++++++++++++++++++--- g10/call-dirmngr.c | 37 +++++++++++++++++++++- sm/call-agent.c | 42 ++++++++++++++++++++++++- sm/call-dirmngr.c | 38 +++++++++++++++++++++++ 9 files changed, 314 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 8 17:27:33 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jan 2016 17:27:33 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-100-g4970868 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 4970868d8d84d3a64b067e5aafc9f097621758d3 (commit) via 34bca9cd4b8517795833cb754b0d5b1dd33b08ed (commit) from 2aa42baaf3dd7c3ae613ae0c61760a17c8adfcd0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4970868d8d84d3a64b067e5aafc9f097621758d3 Author: Werner Koch Date: Fri Jan 8 17:22:32 2016 +0100 gpg: New command --export-ssh-key * g10/export.c: Include membuf.h and host2net.h. (key_to_sshblob): New. (export_ssh_key): New. * g10/gpg.c (aExportSshKey): New. (opts): Add command. (main): Implement that command. -- GnuPG-bug-id: 2212 I have done only a few tests rights now and the ECDSA curves do not yet work. However ssh-keygen -l accept RSA and ed25519 keys exported using this command. Signed-off-by: Werner Koch diff --git a/g10/export.c b/g10/export.c index 95ddb9d..f415c1b 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1,7 +1,7 @@ /* export.c - Export keys in the OpenPGP defined format. * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * 2005, 2010 Free Software Foundation, Inc. - * Copyright (C) 1998-2015 Werner Koch + * Copyright (C) 1998-2016 Werner Koch * * This file is part of GnuPG. * @@ -34,6 +34,8 @@ #include "util.h" #include "main.h" #include "i18n.h" +#include "membuf.h" +#include "host2net.h" #include "trustdb.h" #include "call-agent.h" @@ -1350,3 +1352,295 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, log_info(_("WARNING: nothing exported\n")); return err; } + + + + +static gpg_error_t +key_to_sshblob (membuf_t *mb, const char *identifier, ...) +{ + va_list arg_ptr; + gpg_error_t err = 0; + unsigned char nbuf[4]; + unsigned char *buf; + size_t buflen; + gcry_mpi_t a; + + ulongtobuf (nbuf, (ulong)strlen (identifier)); + put_membuf (mb, nbuf, 4); + put_membuf_str (mb, identifier); + va_start (arg_ptr, identifier); + while ((a = va_arg (arg_ptr, gcry_mpi_t))) + { + err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, &buf, &buflen, a); + if (err) + break; + if (!strcmp (identifier, "ssh-ed25519") + && buflen > 5 && buf[4] == 0x40) + { + /* We need to strip our 0x40 prefix. */ + put_membuf (mb, "\x00\x00\x00\x20", 4); + put_membuf (mb, buf+5, buflen-5); + } + else + put_membuf (mb, buf, buflen); + gcry_free (buf); + } + va_end (arg_ptr); + return err; +} + +/* Export the key identified by USERID in the SSH public key format. + The function exports the latest subkey with Authentication + capability unless the '!' suffix is used to export a specific + key. */ +gpg_error_t +export_ssh_key (ctrl_t ctrl, const char *userid) +{ + gpg_error_t err; + kbnode_t keyblock = NULL; + KEYDB_SEARCH_DESC desc; + u32 latest_date; + u32 curtime = make_timestamp (); + kbnode_t latest_key, node; + PKT_public_key *pk; + const char *identifier; + membuf_t mb; + estream_t fp = NULL; + struct b64state b64_state; + const char *fname = "-"; + + init_membuf (&mb, 4096); + + /* We need to know whether the key has been specified using the + exact syntax ('!' suffix). Thus we need to run a + classify_user_id on our own. */ + err = classify_user_id (userid, &desc, 1); + + /* Get the public key. */ + if (!err) + { + getkey_ctx_t getkeyctx; + + err = get_pubkey_byname (ctrl, &getkeyctx, NULL, userid, &keyblock, + NULL, + 0 /* Only usable keys or given exact. */, + 1 /* No AKL lookup. */); + if (!err) + { + err = getkey_next (getkeyctx, NULL, NULL); + if (!err) + err = gpg_error (GPG_ERR_AMBIGUOUS_NAME); + else if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY) + err = 0; + } + getkey_end (getkeyctx); + } + if (err) + { + log_error (_("key \"%s\" not found: %s\n"), userid, gpg_strerror (err)); + return err; + } + + /* The finish_lookup code in getkey.c does not handle auth keys, + thus we have to duplicate the code here to find the latest + subkey. However, if the key has been found using an exact match + ('!' notation) we use that key without any further checks and + even allow the use of the primary key. */ + latest_date = 0; + latest_key = NULL; + for (node = keyblock; node; node = node->next) + { + if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_PUBLIC_KEY) + && node->pkt->pkt.public_key->flags.exact) + { + latest_key = node; + break; + } + } + if (!latest_key) + { + for (node = keyblock; node; node = node->next) + { + if (node->pkt->pkttype != PKT_PUBLIC_SUBKEY) + continue; + + pk = node->pkt->pkt.public_key; + if (DBG_LOOKUP) + log_debug ("\tchecking subkey %08lX\n", + (ulong) keyid_from_pk (pk, NULL)); + if (!(pk->pubkey_usage & PUBKEY_USAGE_AUTH)) + { + if (DBG_LOOKUP) + log_debug ("\tsubkey not usable for authentication\n"); + continue; + } + if (!pk->flags.valid) + { + if (DBG_LOOKUP) + log_debug ("\tsubkey not valid\n"); + continue; + } + if (pk->flags.revoked) + { + if (DBG_LOOKUP) + log_debug ("\tsubkey has been revoked\n"); + continue; + } + if (pk->has_expired) + { + if (DBG_LOOKUP) + log_debug ("\tsubkey has expired\n"); + continue; + } + if (pk->timestamp > curtime && !opt.ignore_valid_from) + { + if (DBG_LOOKUP) + log_debug ("\tsubkey not yet valid\n"); + continue; + } + if (DBG_LOOKUP) + log_debug ("\tsubkey might be fine\n"); + /* In case a key has a timestamp of 0 set, we make sure that it + is used. A better change would be to compare ">=" but that + might also change the selected keys and is as such a more + intrusive change. */ + if (pk->timestamp > latest_date || (!pk->timestamp && !latest_date)) + { + latest_date = pk->timestamp; + latest_key = node; + } + } + } + + if (!latest_key) + { + err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); + log_error (_("key \"%s\" not found: %s\n"), userid, gpg_strerror (err)); + goto leave; + } + + pk = latest_key->pkt->pkt.public_key; + if (DBG_LOOKUP) + log_debug ("\tusing key %08lX\n", (ulong) keyid_from_pk (pk, NULL)); + + switch (pk->pubkey_algo) + { + case PUBKEY_ALGO_DSA: + identifier = "ssh-dss"; + err = key_to_sshblob (&mb, identifier, + pk->pkey[0], pk->pkey[1], pk->pkey[2], pk->pkey[3], + NULL); + break; + + case PUBKEY_ALGO_RSA: + case PUBKEY_ALGO_RSA_S: + identifier = "ssh-rsa"; + err = key_to_sshblob (&mb, identifier, pk->pkey[1], pk->pkey[0], NULL); + break; + + case PUBKEY_ALGO_ECDSA: + { + char *curveoid; + const char *curve; + + curveoid = openpgp_oid_to_str (pk->pkey[0]); + if (!curveoid) + err = gpg_error_from_syserror (); + else if (!(curve = openpgp_oid_to_curve (curveoid, 0))) + err = gpg_error (GPG_ERR_UNKNOWN_CURVE); + else + { + if (!strcmp (curve, "nistp256")) + identifier = "ecdsa-sha2-nistp256"; + else if (!strcmp (curve, "nistp384")) + identifier = "ecdsa-sha2-nistp384"; + else if (!strcmp (curve, "nistp521")) + identifier = "ecdsa-sha2-nistp521"; + else + identifier = NULL; + + if (!identifier) + err = gpg_error (GPG_ERR_UNKNOWN_CURVE); + else + err = key_to_sshblob (&mb, identifier, pk->pkey[1], NULL); + } + xfree (curveoid); + } + break; + + case PUBKEY_ALGO_EDDSA: + if (!openpgp_oid_is_ed25519 (pk->pkey[0])) + err = gpg_error (GPG_ERR_UNKNOWN_CURVE); + else + { + identifier = "ssh-ed25519"; + err = key_to_sshblob (&mb, identifier, pk->pkey[1], NULL); + } + break; + + case PUBKEY_ALGO_ELGAMAL_E: + case PUBKEY_ALGO_ELGAMAL: + err = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); + break; + + default: + err = GPG_ERR_PUBKEY_ALGO; + break; + } + + if (err) + goto leave; + + if (opt.outfile && *opt.outfile && strcmp (opt.outfile, "-")) + fp = es_fopen ((fname = opt.outfile), "w"); + else + fp = es_stdout; + if (!fp) + { + err = gpg_error_from_syserror (); + log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err)); + goto leave; + } + + es_fprintf (fp, "%s ", identifier); + err = b64enc_start_es (&b64_state, fp, ""); + if (err) + goto leave; + { + void *blob; + size_t bloblen; + + blob = get_membuf (&mb, &bloblen); + if (!blob) + err = gpg_error_from_syserror (); + else + err = b64enc_write (&b64_state, blob, bloblen); + xfree (blob); + if (err) + goto leave; + } + err = b64enc_finish (&b64_state); + if (err) + goto leave; + es_fprintf (fp, " openpgp:0x%08lX\n", (ulong)keyid_from_pk (pk, NULL)); + + if (es_ferror (fp)) + err = gpg_error_from_syserror (); + else + { + if (es_fclose (fp)) + err = gpg_error_from_syserror (); + fp = NULL; + } + + if (err) + log_error (_("error writing '%s': %s\n"), fname, gpg_strerror (err)); + + leave: + es_fclose (fp); + xfree (get_membuf (&mb, NULL)); + release_kbnode (keyblock); + return err; +} diff --git a/g10/gpg.c b/g10/gpg.c index 9b6a142..4287bda 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1,6 +1,6 @@ /* gpg.c - The GnuPG utility (main for gpg) * Copyright (C) 1998-2011 Free Software Foundation, Inc. - * Copyright (C) 1997-2014 Werner Koch + * Copyright (C) 1997-2016 Werner Koch * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. @@ -141,6 +141,7 @@ enum cmd_and_opt_values aExport, aExportSecret, aExportSecretSub, + aExportSshKey, aCheckKeys, aGenRevoke, aDesigRevoke, @@ -453,6 +454,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aFetchKeys, "fetch-keys" , "@" ), ARGPARSE_c (aExportSecret, "export-secret-keys" , "@" ), ARGPARSE_c (aExportSecretSub, "export-secret-subkeys" , "@" ), + ARGPARSE_c (aExportSshKey, "export-ssh-key", "@" ), ARGPARSE_c (aImport, "import", N_("import/merge keys")), ARGPARSE_c (aFastImport, "fast-import", "@"), #ifdef ENABLE_CARD_SUPPORT @@ -2400,6 +2402,7 @@ main (int argc, char **argv) case aListSigs: case aExportSecret: case aExportSecretSub: + case aExportSshKey: case aSym: case aClearsign: case aGenRevoke: @@ -4184,6 +4187,17 @@ main (int argc, char **argv) free_strlist(sl); break; + case aExportSshKey: + if (argc != 1) + wrong_args ("--export-ssh-key "); + rc = export_ssh_key (ctrl, argv[0]); + if (rc) + { + write_status_failure ("export-ssh-key", rc); + log_error (_("export as ssh key failed: %s\n"), gpg_strerror (rc)); + } + break; + case aSearchKeys: sl = NULL; for (; argc; argc--, argv++) diff --git a/g10/main.h b/g10/main.h index 0682172..503f262 100644 --- a/g10/main.h +++ b/g10/main.h @@ -368,6 +368,8 @@ gpg_error_t receive_seckey_from_agent (ctrl_t ctrl, gcry_cipher_hd_t cipherhd, char **cache_nonce_addr, const char *hexgrip, PKT_public_key *pk); +gpg_error_t export_ssh_key (ctrl_t ctrl, const char *userid); + /*-- dearmor.c --*/ int dearmor_file( const char *fname ); int enarmor_file( const char *fname ); commit 34bca9cd4b8517795833cb754b0d5b1dd33b08ed Author: Werner Koch Date: Fri Jan 8 15:16:12 2016 +0100 gpg: Add an exact search flag to the PK struct. * g10/getkey.c (merge_selfsigs_subkey): Clear exact flag. (finish_lookup): Set exact flag. * g10/packet.h (PKT_public_key): Add field flags.exact. -- Signed-off-by: Werner Koch diff --git a/g10/getkey.c b/g10/getkey.c index e66be0d..37a5b56 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2510,6 +2510,7 @@ merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode) keytimestamp = subpk->timestamp; subpk->flags.valid = 0; + subpk->flags.exact = 0; subpk->main_keyid[0] = mainpk->main_keyid[0]; subpk->main_keyid[1] = mainpk->main_keyid[1]; @@ -2836,6 +2837,8 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock) u32 latest_date; KBNODE latest_key; + PKT_public_key *pk; + assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); @@ -2850,6 +2853,8 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock) assert (k->pkt->pkttype == PKT_PUBLIC_KEY || k->pkt->pkttype == PKT_PUBLIC_SUBKEY); foundk = k; + pk = k->pkt->pkt.public_key; + pk->flags.exact = 1; break; } } @@ -2893,8 +2898,6 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock) /* Either start a loop or check just this one subkey. */ for (k = foundk ? foundk : keyblock; k; k = nextk) { - PKT_public_key *pk; - if (foundk) /* If FOUNDK is not NULL, then only consider that exact key, i.e., don't iterate. */ @@ -2968,7 +2971,6 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock) - we're just considering the primary key. */ if ((!latest_key && !ctx->exact) || foundk == keyblock || req_prim) { - PKT_public_key *pk; if (DBG_LOOKUP && !foundk && !req_prim) log_debug ("\tno suitable subkeys found - trying primary\n"); pk = keyblock->pkt->pkt.public_key; @@ -3015,7 +3017,7 @@ found: if (latest_key) { - PKT_public_key *pk = latest_key->pkt->pkt.public_key; + pk = latest_key->pkt->pkt.public_key; if (pk->user_id) free_user_id (pk->user_id); pk->user_id = scopy_user_id (foundu); diff --git a/g10/packet.h b/g10/packet.h index 9eb16cf..16524f8 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -298,6 +298,7 @@ typedef struct unsigned int dont_cache:1; /* Do not cache this key. */ unsigned int backsig:2; /* 0=none, 1=bad, 2=good. */ unsigned int serialno_valid:1;/* SERIALNO below is valid. */ + unsigned int exact:1; /* Found via exact (!) search. */ } flags; PKT_user_id *user_id; /* If != NULL: found by that uid. */ struct revocation_key *revkey; ----------------------------------------------------------------------- Summary of changes: g10/export.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- g10/getkey.c | 10 +- g10/gpg.c | 16 +++- g10/main.h | 2 + g10/packet.h | 1 + 5 files changed, 319 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 8 20:42:31 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jan 2016 20:42:31 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-101-gb2da395 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via b2da3951a395366bf1644bc4c4eb42d657effe17 (commit) from 4970868d8d84d3a64b067e5aafc9f097621758d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b2da3951a395366bf1644bc4c4eb42d657effe17 Author: Werner Koch Date: Fri Jan 8 20:37:25 2016 +0100 gpg: Support ECDSA keys with --export-ssh-key. * g10/export.c (key_to_sshblob): Add hack for ECDSA. Signed-off-by: Werner Koch diff --git a/g10/export.c b/g10/export.c index f415c1b..3f06934 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1369,6 +1369,12 @@ key_to_sshblob (membuf_t *mb, const char *identifier, ...) ulongtobuf (nbuf, (ulong)strlen (identifier)); put_membuf (mb, nbuf, 4); put_membuf_str (mb, identifier); + if (!strncmp (identifier, "ecdsa-sha2-", 11)) + { + ulongtobuf (nbuf, (ulong)strlen (identifier+11)); + put_membuf (mb, nbuf, 4); + put_membuf_str (mb, identifier+11); + } va_start (arg_ptr, identifier); while ((a = va_arg (arg_ptr, gcry_mpi_t))) { ----------------------------------------------------------------------- Summary of changes: g10/export.c | 6 ++++++ 1 file changed, 6 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jan 9 11:36:10 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 09 Jan 2016 11:36:10 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-102-geb9c021 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via eb9c021631174fde4c1c444bbc533a7a46d570cd (commit) from b2da3951a395366bf1644bc4c4eb42d657effe17 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eb9c021631174fde4c1c444bbc533a7a46d570cd Author: Werner Koch Date: Sat Jan 9 11:28:42 2016 +0100 tools: Remove gpgkey2ssh. * tools/gpgkey2ssh.c: Remove. * tools/Makefile.am (bin_PROGRAMS): Ditto. -- Also remove it form the docs. Signed-off-by: Werner Koch diff --git a/doc/Makefile.am b/doc/Makefile.am index 6e0bc15..5449d07 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -84,7 +84,7 @@ watchgnupg_SOURCE = gnupg.texi CLEANFILES = yat2m mkdefsinc defs.inc DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \ - $(myman_pages) gpg-zip.1 gpgkey2ssh.1 gnupg.7 + $(myman_pages) gpg-zip.1 gnupg.7 yat2m: yat2m.c $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c diff --git a/doc/gpg.texi b/doc/gpg.texi index d6ae579..5510d57 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -396,6 +396,21 @@ GnuPG may ask you to enter the passphrase for the key. This is required because the internal protection method of the secret key is different from the one specified by the OpenPGP protocol. + at item --export-ssh-key + at opindex export-ssh-key +This command is used to export a key in the OpenSSH public key format. +It requires the specification of one key by the usual means and +exports the latest valid subkey which has an authentication capability +to STDOUT or to the file given with option @option{--output}. That +output can directly be added to ssh's @file{authorized_key} file. + +By specifying the key to export using a key ID or a fingerprint +suffixed with an exclamation mark (!), a specific subkey or the +primary key can be exported. This does not even require that the key +has the authentication capability flag set. To view the capability +flags of a key use @code{--list-options show-usage} along with a key +listing command. + @item --import @itemx --fast-import @opindex import diff --git a/doc/tools.texi b/doc/tools.texi index 633502e..425790e 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -21,7 +21,6 @@ GnuPG comes with a couple of smaller tools: * gpgparsemail:: Parse a mail message into an annotated format * symcryptrun:: Call a simple symmetric encryption tool. * gpg-zip:: Encrypt or sign files into an archive. -* gpgkey2ssh:: Emit GPG public keys in OpenSSH format. @end menu @c @@ -1894,75 +1893,3 @@ gpg-zip --list-archive test1 @command{tar}(1), @end ifset @include see-also-note.texi - - - at c - at c GPGKEY2SSH - at c - at manpage gpgkey2ssh.1 - at node gpgkey2ssh - at section Emit GPG public keys in OpenSSH format - at ifset manverb -.B gpgkey2ssh \- Emit GPG public keys in OpenSSH format - at end ifset - - at mansect synopsis - at ifset manverb -.B gpgkey2ssh -.I keyid - at end ifset - - at mansect description -This tool is deprecated and will be removed soon. - - at command{gpgkey2ssh} emits the public key of an OpenPGP RSA or DSA key -in a format readable by OpenSSH clients and servers. - -It takes only a single argument, a key ID, which designates the -primary key or subkey whose public key should be converted. - -The key ID should use upper-case (A-F, not a-f) for all hex digits -greater than 9, and the key in question must be present in - at code{gpg}'s public keyring. - -The output of a successful run can be used verbatim as an entry in an - at code{authorized_keys} file for @code{sshd}, or can be prefixed with a -host name and appended to a @code{known_hosts} file for @code{ssh}. - - at mansect return value - -The program returns 0 if the key was successfully converted and -non-zero if there was an error (e.g., if the key ID was malformed, the -key was not present in the public keyring, or if the key is not an RSA -or DSA key). - - at mansect environment - at subsection Environment - - at table @asis - - at item HOME -Used to locate the default home directory. - - at item GNUPGHOME -If set directory used instead of "~/.gnupg". - - at end table - - at mansect files - at subsection FILES - - at table @asis - - at item gpg2 -The command used to search the user's keyring. - - at end table - - at mansect see also - at ifset isman - at command{gpg2}(1), - at command{sshd}(8), - at command{ssh}(1) - at end ifset - at include see-also-note.texi diff --git a/g10/keyring.c b/g10/keyring.c index 4dc7e0a..a0b7a0e 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1229,7 +1229,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (!rc) { if (DBG_LOOKUP) - log_debug ("%s: returing success\n", __func__); + log_debug ("%s: returning success\n", __func__); hd->found.offset = main_offset; hd->found.kr = hd->current.kr; hd->found.pk_no = pk? pk_no : 0; diff --git a/tools/Makefile.am b/tools/Makefile.am index a268811..39c0f9c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -51,13 +51,12 @@ else gpgtar = endif -# Fixme: We should remove the gpgkey2ssh tool. bin_PROGRAMS = gpgconf gpg-connect-agent ${symcryptrun} if !HAVE_W32_SYSTEM bin_PROGRAMS += watchgnupg gpgparsemail endif if !HAVE_W32CE_SYSTEM -bin_PROGRAMS += gpgkey2ssh ${gpgtar} +bin_PROGRAMS += ${gpgtar} endif if !DISABLE_REGEX @@ -119,15 +118,6 @@ gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \ $(LIBREADLINE) $(LIBINTL) $(NETLIBS) $(LIBICONV) \ $(resource_objs) -if !HAVE_W32CE_SYSTEM -gpgkey2ssh_SOURCES = gpgkey2ssh.c -gpgkey2ssh_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) -# common via use of BUG() in an inline function, which -# some compilers do not eliminate. -gpgkey2ssh_LDADD = $(common_libs) \ - $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) \ - $(NETLIBS) -endif if !DISABLE_REGEX gpg_check_pattern_SOURCES = gpg-check-pattern.c diff --git a/tools/gpgkey2ssh.c b/tools/gpgkey2ssh.c deleted file mode 100644 index f12c5f4..0000000 --- a/tools/gpgkey2ssh.c +++ /dev/null @@ -1,337 +0,0 @@ -/* gpgkey2ssh.c - Converter (Debug helper) - * Copyright (C) 2005 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -/* - FIXME: This tool needs some cleanup: - - - Do not use assert() for error output. - - Add proper option parsing and standard options. - - retrieve_key_material needs to take the ordinal at field 1 in account. - 0 Write a man page. -*/ - -#include - -#include -#include -#include -#include -#include -#include - -#include "util.h" -#include "sysutils.h" - - - -typedef struct pkdbuf -{ - unsigned char *buffer; - size_t buffer_n; -} pkdbuf_t; - - - -/* Retrieve the public key material for the RSA key, whose fingerprint - is FPR, from gpg output, which can be read through the stream FP. - The RSA modulus will be stored at the address of M and MLEN, the - public exponent at E and ELEN. Returns zero on success, an error - code on failure. Caller must release the allocated buffers at M - and E if the function returns success. */ -static gpg_error_t -retrieve_key_material (FILE *fp, const char *hexkeyid, int *algorithm_id, - pkdbuf_t **pkdbuf, size_t *pkdbuf_n) -{ - pkdbuf_t *pkdbuf_new; - pkdbuf_t *pkdbuf_tmp; - size_t pkdbuf_new_n; - gcry_error_t err = 0; - char *line = NULL; /* read_line() buffer. */ - size_t line_size = 0; /* Helper for for read_line. */ - int found_key = 0; /* Helper to find a matching key. */ - int id; - unsigned char *buffer; - size_t buffer_n; - int i; - - pkdbuf_new = NULL; - pkdbuf_new_n = 0; - id = 0; - - /* Loop over all records until we have found the subkey - corresponding to the fingerprint. In general the first record - should be the pub record, but we don't rely on that. Given that - we only need to look at one key, it is sufficient to compare the - keyid so that we don't need to look at "fpr" records. */ - for (;;) - { - char *p; - char *fields[6]; - int nfields; - size_t max_length; - gcry_mpi_t mpi; - - max_length = 4096; - i = read_line (fp, &line, &line_size, &max_length); - if (!i) - break; /* EOF. */ - if (i < 0) - { - err = gpg_error_from_syserror (); - goto leave; /* Error. */ - } - if (!max_length) - { - err = gpg_error (GPG_ERR_TRUNCATED); - goto leave; /* Line truncated - we better stop processing. */ - } - - /* Parse the line into fields. */ - for (nfields=0, p=line; p && nfields < DIM (fields); nfields++) - { - fields[nfields] = p; - p = strchr (p, ':'); - if (p) - *(p++) = 0; - } - if (!nfields) - continue; /* No fields at all - skip line. */ - - if (!found_key) - { - if ( (!strcmp (fields[0], "sub") || !strcmp (fields[0], "pub") ) - && nfields > 4 && - (((strlen (hexkeyid) == 8) - && (strlen (fields[4]) == 16) - && (! strcmp (fields[4] + 8, hexkeyid))) - || ((strlen (hexkeyid) == 16) - && (! strcmp (fields[4], hexkeyid))))) - { - found_key = 1; - /* Save algorithm ID. */ - id = atoi (fields[3]); - } - continue; - } - - if ( !strcmp (fields[0], "sub") || !strcmp (fields[0], "pub") ) - break; /* Next key - stop. */ - - if ( strcmp (fields[0], "pkd") ) - continue; /* Not a key data record. */ - - /* FIXME, necessary? */ - - i = atoi (fields[1]); - if ((nfields < 4) || (i < 0)) - { - err = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, fields[3], 0, NULL); - if (err) - mpi = NULL; - - err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &buffer, &buffer_n, mpi); - gcry_mpi_release (mpi); - if (err) - goto leave; - - pkdbuf_tmp = xrealloc (pkdbuf_new, sizeof (*pkdbuf_new) * (pkdbuf_new_n + 1)); - if (pkdbuf_new != pkdbuf_tmp) - pkdbuf_new = pkdbuf_tmp; - pkdbuf_new[pkdbuf_new_n].buffer = buffer; - pkdbuf_new[pkdbuf_new_n].buffer_n = buffer_n; - pkdbuf_new_n++; - } - - *algorithm_id = id; - *pkdbuf = pkdbuf_new; - *pkdbuf_n = pkdbuf_new_n; - - leave: - - if (err) - if (pkdbuf_new) - { - for (i = 0; i < pkdbuf_new_n; i++) - xfree (pkdbuf_new[i].buffer); - xfree (pkdbuf_new); - } - xfree (line); - - return err; -} - - - -int -key_to_blob (unsigned char **blob, size_t *blob_n, const char *identifier, ...) -{ - unsigned char *blob_new; - size_t blob_new_n; - unsigned char uint32_buffer[4]; - u32 identifier_n; - FILE *stream; - va_list ap; - int ret; - pkdbuf_t *pkd; - - stream = gnupg_tmpfile (); - assert (stream); - - identifier_n = strlen (identifier); - uint32_buffer[0] = identifier_n >> 24; - uint32_buffer[1] = identifier_n >> 16; - uint32_buffer[2] = identifier_n >> 8; - uint32_buffer[3] = identifier_n >> 0; - ret = fwrite (uint32_buffer, sizeof (uint32_buffer), 1, stream); - assert (ret == 1); - ret = fwrite (identifier, identifier_n, 1, stream); - assert (ret == 1); - - va_start (ap, identifier); - while (1) - { - pkd = va_arg (ap, pkdbuf_t *); - if (! pkd) - break; - - uint32_buffer[0] = pkd->buffer_n >> 24; - uint32_buffer[1] = pkd->buffer_n >> 16; - uint32_buffer[2] = pkd->buffer_n >> 8; - uint32_buffer[3] = pkd->buffer_n >> 0; - ret = fwrite (uint32_buffer, sizeof (uint32_buffer), 1, stream); - assert (ret == 1); - ret = fwrite (pkd->buffer, pkd->buffer_n, 1, stream); - assert (ret == 1); - } - - va_end (ap); - - blob_new_n = ftell (stream); - rewind (stream); - - blob_new = xmalloc (blob_new_n); - ret = fread (blob_new, blob_new_n, 1, stream); - assert (ret == 1); - - *blob = blob_new; - *blob_n = blob_new_n; - - fclose (stream); - - return 0; -} - -int -main (int argc, char **argv) -{ - const char *keyid; - int algorithm_id; - pkdbuf_t *pkdbuf; - size_t pkdbuf_n; - char *command = NULL; - FILE *fp; - int ret; - gcry_error_t err; - unsigned char *blob; - size_t blob_n; - struct b64state b64_state; - const char *identifier; - - pkdbuf = NULL; - pkdbuf_n = 0; - - algorithm_id = 0; /* (avoid cc warning) */ - identifier = NULL; /* (avoid cc warning) */ - - if (argc != 2) - { - fprintf (stderr, "Usage: %s KEYID\n", argv[0]); - exit (1); - } - if (strcmp (argv[1], "--help") == 0) - { - fprintf (stderr, "Usage: %s KEYID\n", argv[0]); - fprintf (stderr, "\n"); - fprintf (stderr, - "Convert a gpg key to a format appropriate for inclusion in an\n" - "ssh authorized_keys file.\n"); - exit (0); - } - - keyid = argv[1]; - - asprintf (&command, - "gpg2 --list-keys --with-colons --with-key-data '%s'", - keyid); - if (! command) - { - fprintf (stderr, "Out of memory.\n"); - exit (1); - } - - fp = popen (command, "r"); - if (! fp) - { - fprintf (stderr, "Failed to running: '%s'\n", command); - exit (1); - } - - err = retrieve_key_material (fp, keyid, &algorithm_id, &pkdbuf, &pkdbuf_n); - if (err) - { - fprintf (stderr, "Error looking up key: %s\n", gpg_strerror (err)); - exit (1); - } - if (! ((algorithm_id == 1) || (algorithm_id == 17))) - { - fprintf (stderr, "Unsupported algorithm: %d\n", algorithm_id); - exit (1); - } - - if (algorithm_id == 1) - { - identifier = "ssh-rsa"; - ret = key_to_blob (&blob, &blob_n, identifier, - &pkdbuf[1], &pkdbuf[0], NULL); - } - else if (algorithm_id == 17) - { - identifier = "ssh-dss"; - ret = key_to_blob (&blob, &blob_n, identifier, - &pkdbuf[0], &pkdbuf[1], &pkdbuf[2], &pkdbuf[3], NULL); - } - assert (! ret); - - printf ("%s ", identifier); - - err = b64enc_start (&b64_state, stdout, ""); - assert (! err); - err = b64enc_write (&b64_state, blob, blob_n); - assert (! err); - err = b64enc_finish (&b64_state); - assert (! err); - - printf (" COMMENT\n"); - - return 0; -} ----------------------------------------------------------------------- Summary of changes: doc/Makefile.am | 2 +- doc/gpg.texi | 15 +++ doc/tools.texi | 73 ------------ g10/keyring.c | 2 +- tools/Makefile.am | 12 +- tools/gpgkey2ssh.c | 337 ----------------------------------------------------- 6 files changed, 18 insertions(+), 423 deletions(-) delete mode 100644 tools/gpgkey2ssh.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jan 10 13:26:05 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 10 Jan 2016 13:26:05 +0100 Subject: [git] gnupg-doc - branch, master, updated. a08b117d893915c75e7bc0c925cbab6ce64947e1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via a08b117d893915c75e7bc0c925cbab6ce64947e1 (commit) from 5dedb55faddf94f16bd44480d339ca755fee4b83 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a08b117d893915c75e7bc0c925cbab6ce64947e1 Author: Werner Koch Date: Sun Jan 10 13:21:13 2016 +0100 web: Complete donation summary for 2015. diff --git a/web/donate/kudos.org b/web/donate/kudos.org index 8fc5a63..9fbf8ac 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -19,17 +19,16 @@ | Year | # | \EUR | net \EUR | | | | | | |------+------+--------+----------| -| 2015 | 5844 | 205560 | | +| 2015 | 5846 | 295405 | 283537 | | 2014 | 801 | 34700 | 30305 | | 2013 | 148 | 5041 | 4145 | | 2012 | 53 | 5991 | 4963 | | 2011 | 21 | 553 | 465 | |------+------+--------+----------| -| | | 251845 | | +| | | 341690 | 323415 | #+TBLFM: $LR3=vsum(@I.. at II)::$LR4=vsum(@I.. at II) #+HTML:
-The "net" column gives the actual value without VAT and credit card -fees.\\ +The "net" column gives the actual value without taxes and banking fees.\\ #+HTML:
The [[https://gnupg.org/blog/20140512-rewards-sent.html][Goteo crowdfunding]] campaign raised an additional @@ -37,12 +36,20 @@ The [[https://gnupg.org/blog/20140512-rewards-sent.html][Goteo crowdfunding]] ca # Goteo transferred that money in March 2014 in 6 chunks: # 11423, 6000, 5000, 5000, 5218 = 32641 +# About 2014: # Some of the 801 donations from 2014 have been hold back by Stripe # over the end of the year and thus VAT was only payable in 2015. # That VAT is not included in the net amount for 2014. The net amount # received from individual donations in 2014 have been 2525, 919, 541, # 26320 Euro per quarter. +# About 2015: +# | Individual Donations in 2015 | 5844 | 205560 | 193692 | +# | Facebook+Stripe in 2015 | 2 | 89845 | 89845 | +# |------------------------------+------+--------+--------| +# | | 5846 | 295405 | 283537 | + + * List of Donors #+HTML:
    ----------------------------------------------------------------------- Summary of changes: web/donate/kudos.org | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 11 11:47:27 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jan 2016 11:47:27 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-104-g0617a05 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 0617a05eb5cb76b239700355d897eb7b49088bf1 (commit) via b280aa6423c9492e8c5a9afa57339d06d957996d (commit) from eb9c021631174fde4c1c444bbc533a7a46d570cd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0617a05eb5cb76b239700355d897eb7b49088bf1 Author: Werner Koch Date: Mon Jan 11 11:41:49 2016 +0100 gpg: Move documentation from keydb.h to keydb.c and getkey.c. -- When using tags (e.g. GNU global) to navigate the source code it is way easier to have the documentation close to the function we are looking at. Having the documentation in the header file would require an extra manual lookup to understand the function. Signed-off-by: Werner Koch diff --git a/g10/getkey.c b/g10/getkey.c index 1df7287..d6e27e6 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -155,7 +155,18 @@ print_stats () #endif -/* For documentation see keydb.h. */ +/* Cache a copy of a public key in the public key cache. PK is not + * cached if caching is disabled (via getkey_disable_caches), if + * PK->FLAGS.DONT_CACHE is set, we don't know how to derive a key id + * from the public key (e.g., unsupported algorithm), or a key with + * the key id is already in the cache. + * + * The public key packet is copied into the cache using + * copy_public_key. Thus, any secret parts are not copied, for + * instance. + * + * This cache is filled by get_pubkey and is read by get_pubkey and + * get_pubkey_fast. */ void cache_public_key (PKT_public_key * pk) { @@ -344,7 +355,9 @@ cache_user_id (KBNODE keyblock) } -/* For documentation see keydb.h. */ +/* Disable and drop the public key cache (which is filled by + cache_public_key and get_pubkey). Note: there is currently no way + to reenable this cache. */ void getkey_disable_caches () { @@ -653,7 +666,27 @@ pk_from_block (GETKEY_CTX ctx, PKT_public_key * pk, KBNODE keyblock, } -/* For documentation see keydb.h. */ +/* Return the public key with the key id KEYID and store it at PK. + * The resources in *PK should be released using + * release_public_key_parts(). This function also stores a copy of + * the public key in the user id cache (see cache_public_key). + * + * If PK is NULL, this function just stores the public key in the + * cache and returns the usual return code. + * + * PK->REQ_USAGE (which is a mask of PUBKEY_USAGE_SIG, + * PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT) is passed through to the + * lookup function. If this is non-zero, only keys with the specified + * usage will be returned. As such, it is essential that + * PK->REQ_USAGE be correctly initialized! + * + * Returns 0 on success, GPG_ERR_NO_PUBKEY if there is no public key + * with the specified key id, or another error code if an error + * occurs. + * + * If the data was not read from the cache, then the self-signed data + * has definitely been merged into the public key using + * merge_selfsigs. */ int get_pubkey (PKT_public_key * pk, u32 * keyid) { @@ -728,7 +761,16 @@ leave: } -/* For documentation see keydb.h. */ +/* Similar to get_pubkey, but it does not take PK->REQ_USAGE into + * account nor does it merge in the self-signed data. This function + * also only considers primary keys. It is intended to be used as a + * quick check of the key to avoid recursion. It should only be used + * in very certain cases. Like get_pubkey and unlike any of the other + * lookup functions, this function also consults the user id cache + * (see cache_public_key). + * + * Return the public key in *PK. The resources in *PK should be + * released using release_public_key_parts(). */ int get_pubkey_fast (PKT_public_key * pk, u32 * keyid) { @@ -795,8 +837,12 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid) } -/* For documentation see keydb.h. */ -KBNODE +/* Return the key block for the key with key id KEYID or NULL, if an + * error occurs. Use release_kbnode() to release the key block. + * + * The self-signed data has already been merged into the public key + * using merge_selfsigs. */ +kbnode_t get_pubkeyblock (u32 * keyid) { struct getkey_ctx_s ctx; @@ -820,7 +866,23 @@ get_pubkeyblock (u32 * keyid) } -/* For documentation see keydb.h. */ +/* Return the public key with the key id KEYID iff the secret key is + * available and store it at PK. The resources should be released + * using release_public_key_parts(). + * + * Unlike other lookup functions, PK may not be NULL. PK->REQ_USAGE + * is passed through to the lookup function and is a mask of + * PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. Thus, it + * must be valid! If this is non-zero, only keys with the specified + * usage will be returned. + * + * Returns 0 on success. If a public key with the specified key id is + * not found or a secret key is not available for that public key, an + * error code is returned. Note: this function ignores legacy keys. + * An error code is also return if an error occurs. + * + * The self-signed data has already been merged into the public key + * using merge_selfsigs. */ gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid) { @@ -1070,7 +1132,56 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist, } -/* For documentation see keydb.h. */ +/* Find a public key identified by NAME. + * + * If name appears to be a valid valid RFC822 mailbox (i.e., email + * address) and auto key lookup is enabled (no_akl == 0), then the + * specified auto key lookup methods (--auto-key-lookup) are used to + * import the key into the local keyring. Otherwise, just the local + * keyring is consulted. + * + * If RETCTX is not NULL, then the constructed context is returned in + * *RETCTX so that getpubkey_next can be used to get subsequent + * results. In this case, getkey_end() must be used to free the + * search context. If RETCTX is not NULL, then RET_KDBHD must be + * NULL. + * + * If PK is not NULL, the public key of the first result is returned + * in *PK. Note: PK->REQ_USAGE must be valid!!! PK->REQ_USAGE is + * passed through to the lookup function and is a mask of + * PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. If this + * is non-zero, only keys with the specified usage will be returned. + * Note: The self-signed data has already been merged into the public + * key using merge_selfsigs. Free *PK by calling + * release_public_key_parts (or, if PK was allocated using xfree, you + * can use free_public_key, which calls release_public_key_parts(PK) + * and then xfree(PK)). + * + * NAME is a string, which is turned into a search query using + * classify_user_id. + * + * If RET_KEYBLOCK is not NULL, the keyblock is returned in + * *RET_KEYBLOCK. This should be freed using release_kbnode(). + * + * If RET_KDBHD is not NULL, then the new database handle used to + * conduct the search is returned in *RET_KDBHD. This can be used to + * get subsequent results using keydb_search_next or to modify the + * returned record. Note: in this case, no advanced filtering is done + * for subsequent results (e.g., PK->REQ_USAGE is not respected). + * Unlike RETCTX, this is always returned. + * + * If INCLUDE_UNUSABLE is set, then unusable keys (see the + * documentation for skip_unusable for an exact definition) are + * skipped unless they are looked up by key id or by fingerprint. + * + * If NO_AKL is set, then the auto key locate functionality is + * disabled and only the local key ring is considered. Note: the + * local key ring is consulted even if local is not in the + * --auto-key-locate option list! + * + * This function returns 0 on success. Otherwise, an error code is + * returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY + * (if want_secret is set) is returned if the key is not found. */ int get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk, const char *name, KBNODE * ret_keyblock, @@ -1334,11 +1445,34 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk, } -/* For documentation see keydb.h. - - FIXME: We should replace this with the _byname function. This can - be done by creating a userID conforming to the unified fingerprint - style. */ +/* Lookup a key with the specified fingerprint. + * + * If PK is not NULL, the public key of the first result is returned + * in *PK. Note: this function does an exact search and thus the + * returned public key may be a subkey rather than the primary key. + * Note: The self-signed data has already been merged into the public + * key using merge_selfsigs. Free *PK by calling + * release_public_key_parts (or, if PK was allocated using xfree, you + * can use free_public_key, which calls release_public_key_parts(PK) + * and then xfree(PK)). + * + * If PK->REQ_USAGE is set, it is used to filter the search results. + * (Thus, if PK is not NULL, PK->REQ_USAGE must be valid!!!) See the + * documentation for finish_lookup to understand exactly how this is + * used. + * + * If R_KEYBLOCK is not NULL, then the first result's keyblock is + * returned in *R_KEYBLOCK. This should be freed using + * release_kbnode(). + * + * FPRINT is a byte array whose contents is the fingerprint to use as + * the search term. FPRINT_LEN specifies the length of the + * fingerprint (in bytes). Currently, only 16 and 20-byte + * fingerprints are supported. + * + * FIXME: We should replace this with the _byname function. This can + * be done by creating a userID conforming to the unified fingerprint + * style. */ int get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock, const byte * fprint, size_t fprint_len) @@ -1382,7 +1516,16 @@ get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock, } -/* For documentation see keydb.h. */ +/* This function is similar to get_pubkey_byfprint, but it doesn't + * merge the self-signed data into the public key and subkeys or into + * the user ids. It also doesn't add the key to the user id cache. + * Further, this function ignores PK->REQ_USAGE. + * + * This function is intended to avoid recursion and, as such, should + * only be used in very specific situations. + * + * Like get_pubkey_byfprint, PK may be NULL. In that case, this + * function effectively just checks for the existence of the key. */ int get_pubkey_byfprint_fast (PKT_public_key * pk, const byte * fprint, size_t fprint_len) @@ -1556,7 +1699,30 @@ parse_def_secret_key (ctrl_t ctrl) return NULL; } -/* For documentation see keydb.h. */ + +/* Look up a secret key. + * + * If PK is not NULL, the public key of the first result is returned + * in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is + * set, it is used to filter the search results. See the + * documentation for finish_lookup to understand exactly how this is + * used. Note: The self-signed data has already been merged into the + * public key using merge_selfsigs. Free *PK by calling + * release_public_key_parts (or, if PK was allocated using xfree, you + * can use free_public_key, which calls release_public_key_parts(PK) + * and then xfree(PK)). + * + * If --default-key was set, then the specified key is looked up. (In + * this case, the default key is returned even if it is considered + * unusable. See the documentation for skip_unusable for exactly what + * this means.) + * + * Otherwise, this initiates a DB scan that returns all keys that are + * usable (see previous paragraph for exactly what usable means) and + * for which a secret key is available. + * + * This function returns the first match. Additional results can be + * returned using getkey_next. */ gpg_error_t get_seckey_default (ctrl_t ctrl, PKT_public_key *pk) { @@ -1577,8 +1743,44 @@ get_seckey_default (ctrl_t ctrl, PKT_public_key *pk) return err; } + + -/* For documentation see keydb.h. */ +/* Search for keys matching some criteria. + * + * If RETCTX is not NULL, then the constructed context is returned in + * *RETCTX so that getpubkey_next can be used to get subsequent + * results. In this case, getkey_end() must be used to free the + * search context. If RETCTX is not NULL, then RET_KDBHD must be + * NULL. + * + * If PK is not NULL, the public key of the first result is returned + * in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is + * set, it is used to filter the search results. See the + * documentation for finish_lookup to understand exactly how this is + * used. Note: The self-signed data has already been merged into the + * public key using merge_selfsigs. Free *PK by calling + * release_public_key_parts (or, if PK was allocated using xfree, you + * can use free_public_key, which calls release_public_key_parts(PK) + * and then xfree(PK)). + * + * If NAMES is not NULL, then a search query is constructed using + * classify_user_id on each of the strings in the list. (Recall: the + * database does an OR of the terms, not an AND.) If NAMES is + * NULL, then all results are returned. + * + * If WANT_SECRET is set, then only keys with an available secret key + * (either locally or via key registered on a smartcard) are returned. + * + * This function does not skip unusable keys (see the documentation + * for skip_unusable for an exact definition). + * + * If RET_KEYBLOCK is not NULL, the keyblock is returned in + * *RET_KEYBLOCK. This should be freed using release_kbnode(). + * + * This function returns 0 on success. Otherwise, an error code is + * returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY + * (if want_secret is set) is returned if the key is not found. */ gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, strlist_t names, int want_secret, kbnode_t *ret_keyblock) @@ -1588,7 +1790,46 @@ getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, } -/* For documentation see keydb.h. */ +/* Search for one key matching some criteria. + * + * If RETCTX is not NULL, then the constructed context is returned in + * *RETCTX so that getpubkey_next can be used to get subsequent + * results. In this case, getkey_end() must be used to free the + * search context. If RETCTX is not NULL, then RET_KDBHD must be + * NULL. + * + * If PK is not NULL, the public key of the first result is returned + * in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is + * set, it is used to filter the search results. See the + * documentation for finish_lookup to understand exactly how this is + * used. Note: The self-signed data has already been merged into the + * public key using merge_selfsigs. Free *PK by calling + * release_public_key_parts (or, if PK was allocated using xfree, you + * can use free_public_key, which calls release_public_key_parts(PK) + * and then xfree(PK)). + * + * If NAME is not NULL, then a search query is constructed using + * classify_user_id on the string. In this case, even unusable keys + * (see the documentation for skip_unusable for an exact definition of + * unusable) are returned. Otherwise, if --default-key was set, then + * that key is returned (even if it is unusable). If neither of these + * conditions holds, then the first usable key is returned. + * + * If WANT_SECRET is set, then only keys with an available secret key + * (either locally or via key registered on a smartcard) are returned. + * + * This function does not skip unusable keys (see the documentation + * for skip_unusable for an exact definition). + * + * If RET_KEYBLOCK is not NULL, the keyblock is returned in + * *RET_KEYBLOCK. This should be freed using release_kbnode(). + * + * This function returns 0 on success. Otherwise, an error code is + * returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY + * (if want_secret is set) is returned if the key is not found. + * + * FIXME: We also have the get_pubkey_byname function which has a + * different semantic. Should be merged with this one. */ gpg_error_t getkey_byname (ctrl_t ctrl, getkey_ctx_t *retctx, PKT_public_key *pk, const char *name, int want_secret, kbnode_t *ret_keyblock) @@ -1620,7 +1861,22 @@ getkey_byname (ctrl_t ctrl, getkey_ctx_t *retctx, PKT_public_key *pk, } -/* For documentation see keydb.h. */ +/* Return the next search result. + * + * If PK is not NULL, the public key of the next result is returned in + * *PK. Note: The self-signed data has already been merged into the + * public key using merge_selfsigs. Free *PK by calling + * release_public_key_parts (or, if PK was allocated using xfree, you + * can use free_public_key, which calls release_public_key_parts(PK) + * and then xfree(PK)). + * + * RET_KEYBLOCK can be given as NULL; if it is not NULL it the entire + * found keyblock wis retruned hich must be released with + * release_kbnode. If the function returns an error NULL is stored at + * RET_KEYBLOCK. + * + * The self-signed data has already been merged into the public key + * using merge_selfsigs. */ gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock) { @@ -1641,7 +1897,8 @@ getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock) } -/* For documentation see keydb.h. */ +/* Release any resources used by a key listing context. This must be + * called on the context returned by, e.g., getkey_byname. */ void getkey_end (getkey_ctx_t ctx) { @@ -1660,7 +1917,10 @@ getkey_end (getkey_ctx_t ctx) ************* Merging stuff ******************** ************************************************/ -/* For documentation see keydb.h. */ +/* Set the mainkey_id fields for all keys in KEYBLOCK. This is + * usually done by merge_selfsigs but at some places we only need the + * main_kid not a full merge. The function also guarantees that all + * pk->keyids are computed. */ void setup_main_keyids (kbnode_t keyblock) { @@ -1689,7 +1949,13 @@ setup_main_keyids (kbnode_t keyblock) } -/* For documentation see keydb.h. */ +/* KEYBLOCK corresponds to a public key block. This function merges + * much of the information from the self-signed data into the public + * key, public subkey and user id data structures. If you use the + * high-level search API (e.g., get_pubkey) for looking up key blocks, + * then you don't need to call this function. This function is + * useful, however, if you change the keyblock, e.g., by adding or + * removing a self-signed data packet. */ void merge_keys_and_selfsig (KBNODE keyblock) { @@ -3139,7 +3405,38 @@ found: } -/* For documentation see keydb.h. */ +/* Enumerate some secret keys (specifically, those specified with + * --default-key and --try-secret-key). Use the following procedure: + * + * 1) Initialize a void pointer to NULL + * 2) Pass a reference to this pointer to this function (content) + * and provide space for the secret key (sk) + * 3) Call this function as long as it does not return an error (or + * until you are done). The error code GPG_ERR_EOF indicates the + * end of the listing. + * 4) Call this function a last time with SK set to NULL, + * so that can free it's context. + * + * In pseudo-code: + * + * void *ctx = NULL; + * PKT_public_key *sk = xmalloc_clear (sizeof (*sk)); + * + * while ((err = enum_secret_keys (&ctx, sk))) + * { // Process SK. + * if (done) + * break; + * free_public_key (sk); + * sk = xmalloc_clear (sizeof (*sk)); + * } + * + * // Release any resources used by CTX. + * enum_secret_keys (&ctx, NULL); + * free_public_key (sk); + * + * if (gpg_err_code (err) != GPG_ERR_EOF) + * ; // An error occurred. + */ gpg_error_t enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) { @@ -3402,8 +3699,8 @@ get_user_id_byfpr_native (const byte *fpr) } - -/* For documentation see keydb.h. */ +/* Return the database handle used by this context. The context still + owns the handle. */ KEYDB_HANDLE get_ctx_handle (GETKEY_CTX ctx) { diff --git a/g10/keydb.c b/g10/keydb.c index 2150a92..e1814fe 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -533,7 +533,52 @@ keydb_search_desc_dump (struct keydb_search_desc *desc) return xasprintf ("Bad search mode (%d)", desc->mode); } } + + +/* Register a resource (keyring or keybox). The first keyring or + * keybox that is added using this function is created if it does not + * already exist and the KEYDB_RESOURCE_FLAG_READONLY is not set. + * + * FLAGS are a combination of the KEYDB_RESOURCE_FLAG_* constants. + * + * URL must have the following form: + * + * gnupg-ring:filename = plain keyring + * gnupg-kbx:filename = keybox file + * filename = check file's type (create as a plain keyring) + * + * Note: on systems with drive letters (Windows) invalid URLs (i.e., + * those with an unrecognized part before the ':' such as "c:\...") + * will silently be treated as bare filenames. On other systems, such + * URLs will cause this function to return GPG_ERR_GENERAL. + * + * If KEYDB_RESOURCE_FLAG_DEFAULT is set, the resource is a keyring + * and the file ends in ".gpg", then this function also checks if a + * file with the same name, but the extension ".kbx" exists, is a + * keybox and the OpenPGP flag is set. If so, this function opens + * that resource instead. + * + * If the file is not found, KEYDB_RESOURCE_FLAG_GPGVDEF is set and + * the URL ends in ".kbx", then this function will try opening the + * same URL, but with the extension ".gpg". If that file is a keybox + * with the OpenPGP flag set or it is a keyring, then we use that + * instead. + * + * If the file is not found, KEYDB_RESOURCE_FLAG_DEFAULT is set, the + * file should be created and the file's extension is ".gpg" then we + * replace the extension with ".kbx". + * + * If the KEYDB_RESOURCE_FLAG_PRIMARY is set and the resource is a + * keyring (not a keybox), then this resource is considered the + * primary resource. This is used by keydb_locate_writable(). If + * another primary keyring is set, then that keyring is considered the + * primary. + * + * If KEYDB_RESOURCE_FLAG_READONLY is set and the resource is a + * keyring (not a keybox), then the keyring is marked as read only and + * operations just as keyring_insert_keyblock will return + * GPG_ERR_ACCESS. */ gpg_error_t keydb_add_resource (const char *url, unsigned int flags) { @@ -864,6 +909,9 @@ keydb_release (KEYDB_HANDLE hd) } +/* Set a flag on the handle to suppress use of cached results. This + * is required for updating a keyring and for key listings. Fixme: + * Using a new parameter for keydb_new might be a better solution. */ void keydb_disable_caching (KEYDB_HANDLE hd) { @@ -872,6 +920,14 @@ keydb_disable_caching (KEYDB_HANDLE hd) } +/* Return the file name of the resource in which the current search + * result was found or, if there is no search result, the filename of + * the current resource (i.e., the resource that the file position + * points to). Note: the filename is not necessarily the URL used to + * open it! + * + * This function only returns NULL if no handle is specified, in all + * other error cases an empty string is returned. */ const char * keydb_get_resource_name (KEYDB_HANDLE hd) { @@ -985,6 +1041,22 @@ unlock_all (KEYDB_HANDLE hd) +/* Save the last found state and invalidate the current selection + * (i.e., the entry selected by keydb_search() is invalidated and + * something like keydb_get_keyblock() will return an error). This + * does not change the file position. This makes it possible to do + * something like: + * + * keydb_search (hd, ...); // Result 1. + * keydb_push_found_state (hd); + * keydb_search_reset (hd); + * keydb_search (hd, ...); // Result 2. + * keydb_pop_found_state (hd); + * keydb_get_keyblock (hd, ...); // -> Result 1. + * + * Note: it is only possible to save a single save state at a time. + * In other words, the the save stack only has room for a single + * instance of the state. */ void keydb_push_found_state (KEYDB_HANDLE hd) { @@ -1014,6 +1086,8 @@ keydb_push_found_state (KEYDB_HANDLE hd) } +/* Restore the previous save state. If the saved state is NULL or + invalid, this is a NOP. */ void keydb_pop_found_state (KEYDB_HANDLE hd) { @@ -1204,6 +1278,15 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no, } +/* Return the keyblock last found by keydb_search() in *RET_KB. + * + * On success, the function returns 0 and the caller must free *RET_KB + * using release_kbnode(). Otherwise, the function returns an error + * code. + * + * The returned keyblock has the kbnode flag bit 0 set for the node + * with the public key used to locate the keyblock or flag bit 1 set + * for the user ID node. */ gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) { @@ -1382,6 +1465,21 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus) } +/* Update the keyblock KB (i.e., extract the fingerprint and find the + * corresponding keyblock in the keyring). + * + * This doesn't do anything if --dry-run was specified. + * + * Returns 0 on success. Otherwise, it returns an error code. Note: + * if there isn't a keyblock in the keyring corresponding to KB, then + * this function returns GPG_ERR_VALUE_NOT_FOUND. + * + * This function selects the matching record and modifies the current + * file position to point to the record just after the selected entry. + * Thus, if you do a subsequent search using HD, you should first do a + * keydb_search_reset. Further, if the selected record is important, + * you should use keydb_push_found_state and keydb_pop_found_state to + * save and restore it. */ gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb) { @@ -1449,6 +1547,16 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb) } +/* Insert a keyblock into one of the underlying keyrings or keyboxes. + * + * Be default, the keyring / keybox from which the last search result + * came is used. If there was no previous search result (or + * keydb_search_reset was called), then the keyring / keybox where the + * next search would start is used (i.e., the current file position). + * + * Note: this doesn't do anything if --dry-run was specified. + * + * Returns 0 on success. Otherwise, it returns an error code. */ gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) { @@ -1510,6 +1618,11 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) } +/* Delete the currently selected keyblock. If you haven't done a + * search yet on this database handle (or called keydb_search_reset), + * then this will return an error. + * + * Returns 0 on success or an error code, if an error occurs. */ gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd) { @@ -1550,6 +1663,15 @@ keydb_delete_keyblock (KEYDB_HANDLE hd) +/* A database may consists of multiple keyrings / key boxes. This + * sets the "file position" to the start of the first keyring / key + * box that is writable (i.e., doesn't have the read-only flag set). + * + * This first tries the primary keyring (the last keyring (not + * keybox!) added using keydb_add_resource() and with + * KEYDB_RESOURCE_FLAG_PRIMARY set). If that is not writable, then it + * tries the keyrings / keyboxes in the order in which they were + * added. */ gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd) { @@ -1602,6 +1724,8 @@ keydb_locate_writable (KEYDB_HANDLE hd) return gpg_error (GPG_ERR_NOT_FOUND); } + +/* Rebuild the on-disk caches of all key resources. */ void keydb_rebuild_caches (int noisy) { @@ -1629,6 +1753,8 @@ keydb_rebuild_caches (int noisy) } +/* Return the number of skipped blocks (because they were to large to + read from a keybox) since the last search reset. */ unsigned long keydb_get_skipped_counter (KEYDB_HANDLE hd) { @@ -1636,6 +1762,12 @@ keydb_get_skipped_counter (KEYDB_HANDLE hd) } +/* Clears the current search result and resets the handle's position + * so that the next search starts at the beginning of the database + * (the start of the first resource). + * + * Returns 0 on success and an error code if an error occurred. + * (Currently, this function always returns 0 if HD is valid.) */ gpg_error_t keydb_search_reset (KEYDB_HANDLE hd) { @@ -1676,6 +1808,24 @@ keydb_search_reset (KEYDB_HANDLE hd) } +/* Search the database for keys matching the search description. If + * the DB contains any legacy keys, these are silently ignored. + * + * DESC is an array of search terms with NDESC entries. The search + * terms are or'd together. That is, the next entry in the DB that + * matches any of the descriptions will be returned. + * + * Note: this function resumes searching where the last search left + * off (i.e., at the current file position). If you want to search + * from the start of the database, then you need to first call + * keydb_search_reset(). + * + * If no key matches the search description, returns + * GPG_ERR_NOT_FOUND. If there was a match, returns 0. If an error + * occurred, returns an error code. + * + * The returned key is considered to be selected and the raw data can, + * for instance, be returned by calling keydb_get_keyblock(). */ gpg_error_t keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex) @@ -1827,6 +1977,11 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, } +/* Return the first non-legacy key in the database. + * + * If you want the very first key in the database, you can directly + * call keydb_search with the search description + * KEYDB_SEARCH_MODE_FIRST. */ gpg_error_t keydb_search_first (KEYDB_HANDLE hd) { @@ -1843,6 +1998,10 @@ keydb_search_first (KEYDB_HANDLE hd) } +/* Return the next key (not the next matching key!). + * + * Unlike calling keydb_search with KEYDB_SEARCH_MODE_NEXT, this + * function silently skips legacy keys. */ gpg_error_t keydb_search_next (KEYDB_HANDLE hd) { @@ -1853,6 +2012,13 @@ keydb_search_next (KEYDB_HANDLE hd) return keydb_search (hd, &desc, 1, NULL); } + +/* This is a convenience function for searching for keys with a long + * key id. + * + * Note: this function resumes searching where the last search left + * off. If you want to search the whole database, then you need to + * first call keydb_search_reset(). */ gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) { @@ -1865,6 +2031,13 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) return keydb_search (hd, &desc, 1, NULL); } + +/* This is a convenience function for searching for keys with a long + * (20 byte) fingerprint. + * + * Note: this function resumes searching where the last search left + * off. If you want to search the whole database, then you need to + * first call keydb_search_reset(). */ gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) { diff --git a/g10/keydb.h b/g10/keydb.h index 41d786c..e679d94 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -151,50 +151,7 @@ union pref_hint the result. */ char *keydb_search_desc_dump (struct keydb_search_desc *desc); -/* Register a resource (keyring or keybox). The first keyring or - keybox that is added using this function is created if it does not - already exist and the KEYDB_RESOURCE_FLAG_READONLY is not set. - - FLAGS are a combination of the KEYDB_RESOURCE_FLAG_* constants. - - URL must have the following form: - - gnupg-ring:filename = plain keyring - gnupg-kbx:filename = keybox file - filename = check file's type (create as a plain keyring) - - Note: on systems with drive letters (Windows) invalid URLs (i.e., - those with an unrecognized part before the ':' such as "c:\...") - will silently be treated as bare filenames. On other systems, such - URLs will cause this function to return GPG_ERR_GENERAL. - - If KEYDB_RESOURCE_FLAG_DEFAULT is set, the resource is a keyring - and the file ends in ".gpg", then this function also checks if a - file with the same name, but the extension ".kbx" exists, is a - keybox and the OpenPGP flag is set. If so, this function opens - that resource instead. - - If the file is not found, KEYDB_RESOURCE_FLAG_GPGVDEF is set and - the URL ends in ".kbx", then this function will try opening the - same URL, but with the extension ".gpg". If that file is a keybox - with the OpenPGP flag set or it is a keyring, then we use that - instead. - - If the file is not found, KEYDB_RESOURCE_FLAG_DEFAULT is set, the - file should be created and the file's extension is ".gpg" then we - replace the extension with ".kbx". - - - If the KEYDB_RESOURCE_FLAG_PRIMARY is set and the resource is a - keyring (not a keybox), then this resource is considered the - primary resource. This is used by keydb_locate_writable(). If - another primary keyring is set, then that keyring is considered the - primary. - - If KEYDB_RESOURCE_FLAG_READONLY is set and the resource is a - keyring (not a keybox), then the keyring is marked as read only and - operations just as keyring_insert_keyblock will return - GPG_ERR_ACCESS. */ +/* Register a resource (keyring or keybox). */ gpg_error_t keydb_add_resource (const char *url, unsigned int flags); /* Dump some statistics to the log. */ @@ -212,94 +169,28 @@ void keydb_release (KEYDB_HANDLE hd); Using a new parameter for keydb_new might be a better solution. */ void keydb_disable_caching (KEYDB_HANDLE hd); -/* Save the last found state and invalidate the current selection - (i.e., the entry selected by keydb_search() is invalidated and - something like keydb_get_keyblock() will return an error). This - does not change the file position. This makes it possible to do - something like: - - keydb_search (hd, ...); // Result 1. - keydb_push_found_state (hd); - keydb_search_reset (hd); - keydb_search (hd, ...); // Result 2. - keydb_pop_found_state (hd); - keydb_get_keyblock (hd, ...); // -> Result 1. - - Note: it is only possible to save a single save state at a time. - In other words, the the save stack only has room for a single - instance of the state. */ +/* Save the last found state and invalidate the current selection. */ void keydb_push_found_state (KEYDB_HANDLE hd); -/* Restore the previous save state. If the saved state is invalid, - this is equivalent to */ +/* Restore the previous save state. */ void keydb_pop_found_state (KEYDB_HANDLE hd); -/* Return the file name of the resource in which the current search - result was found or, if there is no search result, the filename of - the current resource (i.e., the resource that the file position - points to). Note: the filename is not necessarily the URL used to - open it! - - This function only returns NULL if no handle is specified, in all - other error cases an empty string is returned. */ +/* Return the file name of the resource. */ const char *keydb_get_resource_name (KEYDB_HANDLE hd); -/* Return the keyblock last found by keydb_search() in *RET_KB. - - On success, the function returns 0 and the caller must free *RET_KB - using release_kbnode(). Otherwise, the function returns an error - code. - - The returned keyblock has the kbnode flag bit 0 set for the node - with the public key used to locate the keyblock or flag bit 1 set - for the user ID node. */ +/* Return the keyblock last found by keydb_search. */ gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); -/* Update the keyblock KB (i.e., extract the fingerprint and find the - corresponding keyblock in the keyring). - - This doesn't do anything if --dry-run was specified. - - Returns 0 on success. Otherwise, it returns an error code. Note: - if there isn't a keyblock in the keyring corresponding to KB, then - this function returns GPG_ERR_VALUE_NOT_FOUND. - - This function selects the matching record and modifies the current - file position to point to the record just after the selected entry. - Thus, if you do a subsequent search using HD, you should first do a - keydb_search_reset. Further, if the selected record is important, - you should use keydb_push_found_state and keydb_pop_found_state to - save and restore it. */ +/* Update the keyblock KB. */ gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb); -/* Insert a keyblock into one of the underlying keyrings or keyboxes. - - Be default, the keyring / keybox from which the last search result - came is used. If there was no previous search result (or - keydb_search_reset was called), then the keyring / keybox where the - next search would start is used (i.e., the current file position). - - Note: this doesn't do anything if --dry-run was specified. - - Returns 0 on success. Otherwise, it returns an error code. */ +/* Insert a keyblock into one of the underlying keyrings or keyboxes. */ gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb); -/* Delete the currently selected keyblock. If you haven't done a - search yet on this database handle (or called keydb_search_reset), - then this will return an error. - - Returns 0 on success or an error code, if an error occurs. */ +/* Delete the currently selected keyblock. */ gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd); -/* A database may consists of multiple keyrings / key boxes. This - sets the "file position" to the start of the first keyring / key - box that is writable (i.e., doesn't have the read-only flag set). - - This first tries the primary keyring (the last keyring (not - keybox!) added using keydb_add_resource() and with - KEYDB_RESOURCE_FLAG_PRIMARY set). If that is not writable, then it - tries the keyrings / keyboxes in the order in which they were - added. */ +/* Find the first writable resource. */ gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd); /* Rebuild the on-disk caches of all key resources. */ @@ -309,62 +200,25 @@ void keydb_rebuild_caches (int noisy); read from a keybox) since the last search reset. */ unsigned long keydb_get_skipped_counter (KEYDB_HANDLE hd); -/* Clears the current search result and resets the handle's position - so that the next search starts at the beginning of the database - (the start of the first resource). - - Returns 0 on success and an error code if an error occurred. - (Currently, this function always returns 0 if HD is valid.) */ +/* Clears the current search result and resets the handle's position. */ gpg_error_t keydb_search_reset (KEYDB_HANDLE hd); -/* Search the database for keys matching the search description. If - the DB contains any legacy keys, these are silently ignored. - - DESC is an array of search terms with NDESC entries. The search - terms are or'd together. That is, the next entry in the DB that - matches any of the descriptions will be returned. - - Note: this function resumes searching where the last search left - off (i.e., at the current file position). If you want to search - from the start of the database, then you need to first call - keydb_search_reset(). - - If no key matches the search description, returns - GPG_ERR_NOT_FOUND. If there was a match, returns 0. If an error - occurred, returns an error code. - - The returned key is considered to be selected and the raw data can, - for instance, be returned by calling keydb_get_keyblock(). */ +/* Search the database for keys matching the search description. */ gpg_error_t keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex); -/* Return the first non-legacy key in the database. - - If you want the very first key in the database, you can directly - call keydb_search with the search description - KEYDB_SEARCH_MODE_FIRST. */ +/* Return the first non-legacy key in the database. */ gpg_error_t keydb_search_first (KEYDB_HANDLE hd); -/* Return the next key (not the next matching key!). - - Unlike calling keydb_search with KEYDB_SEARCH_MODE_NEXT, this - function silently skips legacy keys. */ +/* Return the next key (not the next matching key!). */ gpg_error_t keydb_search_next (KEYDB_HANDLE hd); /* This is a convenience function for searching for keys with a long - key id. - - Note: this function resumes searching where the last search left - off. If you want to search the whole database, then you need to - first call keydb_search_reset(). */ + key id. */ gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); /* This is a convenience function for searching for keys with a long - (20 byte) fingerprint. - - Note: this function resumes searching where the last search left - off. If you want to search the whole database, then you need to - first call keydb_search_reset(). */ + (20 byte) fingerprint. */ gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr); @@ -424,66 +278,22 @@ char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped); /*-- getkey.c --*/ -/* Cache a copy of a public key in the public key cache. PK is not - cached if caching is disabled (via getkey_disable_caches), if - PK->FLAGS.DONT_CACHE is set, we don't know how to derive a key id - from the public key (e.g., unsupported algorithm), or a key with - the key id is already in the cache. - - The public key packet is copied into the cache using - copy_public_key. Thus, any secret parts are not copied, for - instance. - - This cache is filled by get_pubkey and is read by get_pubkey and - get_pubkey_fast. */ +/* Cache a copy of a public key in the public key cache. */ void cache_public_key( PKT_public_key *pk ); -/* Disable and drop the public key cache (which is filled by - cache_public_key and get_pubkey). Note: there is currently no way - to reenable this cache. */ +/* Disable and drop the public key cache. */ void getkey_disable_caches(void); -/* Return the public key with the key id KEYID and store it in *PK. - The resources in *PK should be released using - release_public_key_parts(). This function also stores a copy of - the public key in the user id cache (see cache_public_key). - - If PK is NULL, this function just stores the public key in the - cache and returns the usual return code. - - PK->REQ_USAGE (which is a mask of PUBKEY_USAGE_SIG, - PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT) is passed through to the - lookup function. If this is non-zero, only keys with the specified - usage will be returned. As such, it is essential that - PK->REQ_USAGE be correctly initialized! - - Returns 0 on success, GPG_ERR_NO_PUBKEY if there is no public key - with the specified key id, or another error code if an error - occurs. - - If the data was not read from the cache, then the self-signed data - has definitely been merged into the public key using - merge_selfsigs. */ +/* Return the public key with the key id KEYID and store it at PK. */ int get_pubkey( PKT_public_key *pk, u32 *keyid ); /* Similar to get_pubkey, but it does not take PK->REQ_USAGE into account nor does it merge in the self-signed data. This function - also only considers primary keys. It is intended to be used as a - quick check of the key to avoid recursion. It should only be used - in very certain cases. Like get_pubkey and unlike any of the other - lookup functions, this function also consults the user id cache - (see cache_public_key). + also only considers primary keys. */ +int get_pubkey_fast (PKT_public_key *pk, u32 *keyid); - Return the public key in *PK. The resources in *PK should be - released using release_public_key_parts(). */ -int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid ); - -/* Return the key block for the key with key id KEYID or NULL, if an - error occurs. Use release_kbnode() to release the key block. - - The self-signed data has already been merged into the public key - using merge_selfsigs. */ -KBNODE get_pubkeyblock( u32 *keyid ); +/* Return the key block for the key with KEYID. */ +kbnode_t get_pubkeyblock (u32 *keyid); /* A list used by get_pubkeys to gather all of the matches. */ struct pubkey_s @@ -509,118 +319,24 @@ get_pubkeys (ctrl_t ctrl, int warn_possibly_ambiguous, pubkey_t *r_keys); -/* Find a public key identified by the name NAME. - - If name appears to be a valid valid RFC822 mailbox (i.e., email - address) and auto key lookup is enabled (no_akl == 0), then the - specified auto key lookup methods (--auto-key-lookup) are used to - import the key into the local keyring. Otherwise, just the local - keyring is consulted. - - - If RETCTX is not NULL, then the constructed context is returned in - *RETCTX so that getpubkey_next can be used to get subsequent - results. In this case, getkey_end() must be used to free the - search context. If RETCTX is not NULL, then RET_KDBHD must be - NULL. - - If PK is not NULL, the public key of the first result is returned - in *PK. Note: PK->REQ_USAGE must be valid!!! PK->REQ_USAGE is - passed through to the lookup function and is a mask of - PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. If this - is non-zero, only keys with the specified usage will be returned. - Note: The self-signed data has already been merged into the public - key using merge_selfsigs. Free *PK by calling - release_public_key_parts (or, if PK was allocated using xfree, you - can use free_public_key, which calls release_public_key_parts(PK) - and then xfree(PK)). - - NAME is a string, which is turned into a search query using - classify_user_id. - - If RET_KEYBLOCK is not NULL, the keyblock is returned in - *RET_KEYBLOCK. This should be freed using release_kbnode(). - - If RET_KDBHD is not NULL, then the new database handle used to - conduct the search is returned in *RET_KDBHD. This can be used to - get subsequent results using keydb_search_next or to modify the - returned record. Note: in this case, no advanced filtering is done - for subsequent results (e.g., PK->REQ_USAGE is not respected). - Unlike RETCTX, this is always returned. - - If INCLUDE_UNUSABLE is set, then unusable keys (see the - documentation for skip_unusable for an exact definition) are - skipped unless they are looked up by key id or by fingerprint. - - If NO_AKL is set, then the auto key locate functionality is - disabled and only the local key ring is considered. Note: the - local key ring is consulted even if local is not in the - --auto-key-locate option list! - - This function returns 0 on success. Otherwise, an error code is - returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY - (if want_secret is set) is returned if the key is not found. */ +/* Find a public key identified by NAME. */ int get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX *retctx, PKT_public_key *pk, const char *name, KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd, int include_unusable, int no_akl ); -/* Return the public key with the key id KEYID and store it in *PK. - The resources should be released using release_public_key_parts(). - - Unlike other lookup functions, PK may not be NULL. PK->REQ_USAGE - is passed through to the lookup function and is a mask of - PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. Thus, it - must be valid! If this is non-zero, only keys with the specified - usage will be returned. - - Returns 0 on success. If a public key with the specified key id is - not found or a secret key is not available for that public key, an - error code is returned. Note: this function ignores legacy keys. - An error code is also return if an error occurs. - - The self-signed data has already been merged into the public key - using merge_selfsigs. */ +/* Return the public key with the key id KEYID iff the secret key is + * available and store it at PK. */ gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid); -/* Lookup a key with the specified fingerprint. - - If PK is not NULL, the public key of the first result is returned - in *PK. Note: this function does an exact search and thus the - returned public key may be a subkey rather than the primary key. - Note: The self-signed data has already been merged into the public - key using merge_selfsigs. Free *PK by calling - release_public_key_parts (or, if PK was allocated using xfree, you - can use free_public_key, which calls release_public_key_parts(PK) - and then xfree(PK)). - - If PK->REQ_USAGE is set, it is used to filter the search results. - (Thus, if PK is not NULL, PK->REQ_USAGE must be valid!!!) See the - documentation for finish_lookup to understand exactly how this is - used. - - If R_KEYBLOCK is not NULL, then the first result's keyblock is - returned in *R_KEYBLOCK. This should be freed using - release_kbnode(). - - FPRINT is a byte array whose contents is the fingerprint to use as - the search term. FPRINT_LEN specifies the length of the - fingerprint (in bytes). Currently, only 16 and 20-byte - fingerprints are supported. */ +/* Lookup a key with the specified fingerprint. */ int get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock, const byte *fprint, size_t fprint_len); /* This function is similar to get_pubkey_byfprint, but it doesn't merge the self-signed data into the public key and subkeys or into - the user ids. It also doesn't add the key to the user id cache. - Further, this function ignores PK->REQ_USAGE. - - This function is intended to avoid recursion and, as such, should - only be used in very specific situations. - - Like get_pubkey_byfprint, PK may be NULL. In that case, this - function effectively just checks for the existence of the key. */ + the user ids. */ int get_pubkey_byfprint_fast (PKT_public_key *pk, const byte *fprint, size_t fprint_len); @@ -632,194 +348,40 @@ int have_secret_key_with_kid (u32 *keyid); of when the option is given) that is available. */ const char *parse_def_secret_key (ctrl_t ctrl); -/* Look up a secret key. - - If PK is not NULL, the public key of the first result is returned - in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is - set, it is used to filter the search results. See the - documentation for finish_lookup to understand exactly how this is - used. Note: The self-signed data has already been merged into the - public key using merge_selfsigs. Free *PK by calling - release_public_key_parts (or, if PK was allocated using xfree, you - can use free_public_key, which calls release_public_key_parts(PK) - and then xfree(PK)). - - If --default-key was set, then the specified key is looked up. (In - this case, the default key is returned even if it is considered - unusable. See the documentation for skip_unusable for exactly what - this means.) - - Otherwise, this initiates a DB scan that returns all keys that are - usable (see previous paragraph for exactly what usable means) and - for which a secret key is available. - - This function returns the first match. Additional results can be - returned using getkey_next. */ +/* Look up a secret key. */ gpg_error_t get_seckey_default (ctrl_t ctrl, PKT_public_key *pk); -/* Search for keys matching some criteria. - - If RETCTX is not NULL, then the constructed context is returned in - *RETCTX so that getpubkey_next can be used to get subsequent - results. In this case, getkey_end() must be used to free the - search context. If RETCTX is not NULL, then RET_KDBHD must be - NULL. - - If PK is not NULL, the public key of the first result is returned - in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is - set, it is used to filter the search results. See the - documentation for finish_lookup to understand exactly how this is - used. Note: The self-signed data has already been merged into the - public key using merge_selfsigs. Free *PK by calling - release_public_key_parts (or, if PK was allocated using xfree, you - can use free_public_key, which calls release_public_key_parts(PK) - and then xfree(PK)). - - If NAMES is not NULL, then a search query is constructed using - classify_user_id on each of the strings in the list. (Recall: the - database does an OR of the terms, not an AND.) If NAMES is - NULL, then all results are returned. - - If WANT_SECRET is set, then only keys with an available secret key - (either locally or via key registered on a smartcard) are returned. - - This function does not skip unusable keys (see the documentation - for skip_unusable for an exact definition). - - If RET_KEYBLOCK is not NULL, the keyblock is returned in - *RET_KEYBLOCK. This should be freed using release_kbnode(). - - This function returns 0 on success. Otherwise, an error code is - returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY - (if want_secret is set) is returned if the key is not found. */ +/* Search for keys matching some criteria. */ gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, strlist_t names, int want_secret, kbnode_t *ret_keyblock); -/* Search for keys matching some criteria. - - If RETCTX is not NULL, then the constructed context is returned in - *RETCTX so that getpubkey_next can be used to get subsequent - results. In this case, getkey_end() must be used to free the - search context. If RETCTX is not NULL, then RET_KDBHD must be - NULL. - - If PK is not NULL, the public key of the first result is returned - in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is - set, it is used to filter the search results. See the - documentation for finish_lookup to understand exactly how this is - used. Note: The self-signed data has already been merged into the - public key using merge_selfsigs. Free *PK by calling - release_public_key_parts (or, if PK was allocated using xfree, you - can use free_public_key, which calls release_public_key_parts(PK) - and then xfree(PK)). - - If NAME is not NULL, then a search query is constructed using - classify_user_id on the string. In this case, even unusable keys - (see the documentation for skip_unusable for an exact definition of - unusable) are returned. Otherwise, if --default-key was set, then - that key is returned (even if it is unusable). If neither of these - conditions holds, then the first usable key is returned. - - If WANT_SECRET is set, then only keys with an available secret key - (either locally or via key registered on a smartcard) are returned. - - This function does not skip unusable keys (see the documentation - for skip_unusable for an exact definition). - - If RET_KEYBLOCK is not NULL, the keyblock is returned in - *RET_KEYBLOCK. This should be freed using release_kbnode(). - - This function returns 0 on success. Otherwise, an error code is - returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY - (if want_secret is set) is returned if the key is not found. - - FIXME: We also have the get_pubkey_byname function which has a - different semantic. Should be merged with this one. */ +/* Search for one key matching some criteria. */ gpg_error_t getkey_byname (ctrl_t ctrl, getkey_ctx_t *retctx, PKT_public_key *pk, const char *name, int want_secret, kbnode_t *ret_keyblock); -/* Return the next search result. - - If PK is not NULL, the public key of the next result is returned in - *PK. Note: The self-signed data has already been merged into the - public key using merge_selfsigs. Free *PK by calling - release_public_key_parts (or, if PK was allocated using xfree, you - can use free_public_key, which calls release_public_key_parts(PK) - and then xfree(PK)). - - RET_KEYBLOCK can be given as NULL; if it is not NULL it the entire - found keyblock wis retruned hich must be released with - release_kbnode. If the function returns an error NULL is stored at - RET_KEYBLOCK. - - The self-signed data has already been merged into the public key - using merge_selfsigs. */ +/* Return the next search result. */ gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock); -/* Release any resources used by a key listing content. This must be - called on the context returned by, e.g., getkey_byname. */ +/* Release any resources used by a key listing context. */ void getkey_end (getkey_ctx_t ctx); /* Return the database handle used by this context. The context still owns the handle. */ KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx); -/* Enumerate some secret keys (specifically, those specified with - --default-key and --try-secret-key). Use the following procedure: - - 1) Initialize a void pointer to NULL - 2) Pass a reference to this pointer to this function (content) - and provide space for the secret key (sk) - 3) Call this function as long as it does not return an error (or - until you are done). The error code GPG_ERR_EOF indicates the - end of the listing. - 4) Call this function a last time with SK set to NULL, - so that can free it's context. - - In pseudo-code: - - void *ctx = NULL; - PKT_public_key *sk = xmalloc_clear (sizeof (*sk)); - gpg_error_t err; - - while ((err = enum_secret_keys (&ctx, sk))) - { - // Process SK. - - if (done) - break; - - free_public_key (sk); - sk = xmalloc_clear (sizeof (*sk)); - } - - // Release any resources used by CTX. - enum_secret_keys (&ctx, NULL); - free_public_key (sk); - - if (gpg_err_code (err) != GPG_ERR_EOF) - ; // An error occurred. - */ +/* Enumerate some secret keys. */ gpg_error_t enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *pk); -/* Set the mainkey_id fields for all keys in KEYBLOCK. This is - usually done by merge_selfsigs but at some places we only need the - main_kid not a full merge. The function also guarantees that all - pk->keyids are computed. */ +/* Set the mainkey_id fields for all keys in KEYBLOCK. */ void setup_main_keyids (kbnode_t keyblock); -/* KEYBLOCK corresponds to a public key block. This function merges - much of the information from the self-signed data into the public - key, public subkey and user id data structures. If you use the - high-level search API (e.g., get_pubkey) for looking up key blocks, - then you don't need to call this function. This function is - useful, however, if you change the keyblock, e.g., by adding or - removing a self-signed data packet. */ -void merge_keys_and_selfsig( KBNODE keyblock ); +/* This function merges information from the self-signed data into the + data structures. */ +void merge_keys_and_selfsig (kbnode_t keyblock); char*get_user_id_string_native( u32 *keyid ); char*get_long_user_id_string( u32 *keyid ); commit b280aa6423c9492e8c5a9afa57339d06d957996d Author: Werner Koch Date: Mon Jan 11 10:59:13 2016 +0100 gpg: Fix NULL de-ref for ambiguous key check in --export-ssh-keys. * g10/getkey.c: Allow arg RET_KEYBLOCK to be NULL. -- This change adds the expected behavior for the getkey_next function to fix this NULL de-ref. GnuPG-bug-id: 2212 Signed-off-by: Werner Koch diff --git a/g10/getkey.c b/g10/getkey.c index 37a5b56..1df7287 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3059,6 +3059,9 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key, KBNODE keyblock = NULL; KBNODE found_key = NULL; + if (ret_keyblock) + *ret_keyblock = NULL; + for (;;) { rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems, NULL); @@ -3113,7 +3116,8 @@ found: if (!rc) { - *ret_keyblock = keyblock; /* Return the keyblock. */ + if (ret_keyblock) + *ret_keyblock = keyblock; /* Return the keyblock. */ keyblock = NULL; } else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND && no_suitable_key) diff --git a/g10/keydb.h b/g10/keydb.h index f99136a..41d786c 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -750,6 +750,11 @@ gpg_error_t getkey_byname (ctrl_t ctrl, can use free_public_key, which calls release_public_key_parts(PK) and then xfree(PK)). + RET_KEYBLOCK can be given as NULL; if it is not NULL it the entire + found keyblock wis retruned hich must be released with + release_kbnode. If the function returns an error NULL is stored at + RET_KEYBLOCK. + The self-signed data has already been merged into the public key using merge_selfsigs. */ gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, ----------------------------------------------------------------------- Summary of changes: g10/getkey.c | 351 ++++++++++++++++++++++++++++++++++++++--- g10/keydb.c | 173 ++++++++++++++++++++ g10/keydb.h | 507 +++++------------------------------------------------------ 3 files changed, 536 insertions(+), 495 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 11 16:50:03 2016 From: cvs at cvs.gnupg.org (by Oleg Gurevich) Date: Mon, 11 Jan 2016 16:50:03 +0100 Subject: [git] Scute - branch, master, updated. scute-1.3.0-50-g4983f77 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PKCS#11 token on top of gpg-agent". The branch, master has been updated via 4983f77cfbc810795f24e7452363413597bbe2e4 (commit) from be53b88aa2b3d9e8952d89251d40bca0059bab40 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4983f77cfbc810795f24e7452363413597bbe2e4 Author: Oleg Gurevich Date: Mon Jan 11 13:50:17 2016 +0100 Fix Windows build * configure.ac: Require newer automake version. Print configuration summary. (BUILD_REVISION): Fix. (BUILD_REVISION_DEC): Add and use the decimal revision where required. * src/scute.def: Add required 'LIBRARY' statement. * src/versioninfo.rc.in: Use decimal revision. Signed-off-by: Justus Winter diff --git a/configure.ac b/configure.ac index 43f1ebd..598f437 100644 --- a/configure.ac +++ b/configure.ac @@ -28,8 +28,8 @@ # Process this file with autoconf to produce a configure script. -AC_PREREQ(2.59) -min_automake_version="1.9.3" +AC_PREREQ(2.61) +min_automake_version="1.14" # To build a release you need to create a tag with the version number # (git tag -s scute-1.n.m) and run "./autogen.sh --force". Please @@ -80,7 +80,12 @@ NEED_GPGSM_VERSION=1.9.6 have_gpg_error=no have_libassuan=no -BUILD_REVISION=svn_revision +# +# Provide information about the build. +# +BUILD_REVISION="mym4_revision" +BUILD_REVISION_DEC="mym4_revision_dec" + PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION @@ -250,9 +255,10 @@ if test "$have_w32_system" = yes; then changequote(,)dnl BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` changequote([,])dnl - BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION}" + BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION_DEC}" fi AC_SUBST(BUILD_REVISION) +AC_SUBST(BUILD_REVISION_DEC) AC_SUBST(BUILD_TIMESTAMP) AC_SUBST(BUILD_FILEVERSION) @@ -467,3 +473,10 @@ AC_CONFIG_FILES([Makefile doc/Makefile src/versioninfo.rc]) AC_OUTPUT + +echo " + Scute v${VERSION} has been configured as follows: + + Revision: mym4_revision (mym4_revision_dec) + Platform: $host +" diff --git a/src/scute.def b/src/scute.def index d0cae3f..a74a027 100644 --- a/src/scute.def +++ b/src/scute.def @@ -27,6 +27,8 @@ ; not obligated to do so. If you do not wish to do so, delete this ; exception statement from your version. +LIBRARY scute.dll + EXPORTS C_CancelFunction @1 C_CloseAllSessions @2 diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index d4f534e..6968473 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -18,7 +18,7 @@ VS_VERSION_INFO VERSIONINFO - FILEVERSION @LIBSCUTE_LT_CURRENT@, at LIBSCUTE_LT_AGE@, at LIBSCUTE_LT_REVISION@, at BUILD_REVISION@ + FILEVERSION @LIBSCUTE_LT_CURRENT@, at LIBSCUTE_LT_AGE@, at LIBSCUTE_LT_REVISION@, at BUILD_REVISION_DEC@ PRODUCTVERSION @BUILD_FILEVERSION@ FILEFLAGSMASK 0x3fL #ifdef _DEBUG ----------------------------------------------------------------------- Summary of changes: configure.ac | 21 +++++++++++++++++---- src/scute.def | 2 ++ src/versioninfo.rc.in | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 12 02:47:14 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 12 Jan 2016 02:47:14 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-105-g3f52c7d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3f52c7da3940ec06572270d511000dc7fe9c27d2 (commit) from 0617a05eb5cb76b239700355d897eb7b49088bf1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3f52c7da3940ec06572270d511000dc7fe9c27d2 Author: NIIBE Yutaka Date: Tue Jan 12 10:32:20 2016 +0900 common: Fix iobuf API of filter function for alignment. * common/iobuf.h (IOBUFCTRL_DESC): Change the call semantics. * common/iobuf.c (iobuf_desc): Add the second argument DESC. (print_chain, iobuf_close, do_open, iobuf_sockopen, iobuf_ioctl) (iobuf_push_filter2, pop_filter, iobuf_write_temp): Change calls of iobuf_desc. (file_filter, file_es_filter, sock_filter, block_filter): Fill the description. * common/t-iobuf.c (every_other_filter, double_filter): Likewise. * g10/armor.c, g10/cipher.c, g10/compress-bz2.c, g10/compress.c, g10/decrypt-data.c, g10/encrypt.c, g10/mdfilter.c, g10/progress.c, g10/textfilter.c: Likewise. -- Newer GCC warns against possible alignment difference of pointers. This change can silence those warnings. Signed-off-by: NIIBE Yutaka diff --git a/common/iobuf.c b/common/iobuf.c index d149e2e..b6e7885 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -578,7 +578,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, } else if (control == IOBUFCTRL_DESC) { - *(char **) buf = "file_filter(fd)"; + mem2str (buf, "file_filter(fd)", *ret_len); } else if (control == IOBUFCTRL_FREE) { @@ -667,7 +667,7 @@ file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf, } else if (control == IOBUFCTRL_DESC) { - *(char **) buf = "estream_filter"; + mem2str (buf, "estream_filter", *ret_len); } else if (control == IOBUFCTRL_FREE) { @@ -765,7 +765,7 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, } else if (control == IOBUFCTRL_DESC) { - *(char **) buf = "sock_filter"; + mem2str (buf, "sock_filter", *ret_len); } else if (control == IOBUFCTRL_FREE) { @@ -993,7 +993,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer, } else if (control == IOBUFCTRL_DESC) { - *(char **) buf = "block_filter"; + mem2str (buf, "block_filter", *ret_len); } else if (control == IOBUFCTRL_FREE) { @@ -1057,19 +1057,23 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer, return rc; } +#define MAX_IOBUF_DESC 32 +/* + * Fill the buffer by the description of iobuf A. + * The buffer size should be MAX_IOBUF_DESC (or larger). + * Returns BUF as (const char *). + */ static const char * -iobuf_desc (iobuf_t a) +iobuf_desc (iobuf_t a, byte *buf) { - size_t dummy_len = 0; - const char *desc = "?"; + size_t len = MAX_IOBUF_DESC; if (! a || ! a->filter) - return desc; - - a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL, - (byte *) & desc, &dummy_len); + memcpy (buf, "?", 2); + else + a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL, buf, &len); - return desc; + return buf; } static void @@ -1079,9 +1083,10 @@ print_chain (iobuf_t a) return; for (; a; a = a->chain) { + byte desc[MAX_IOBUF_DESC]; log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n", - a->no, a->subno, iobuf_desc (a), a->filter_eof, + a->no, a->subno, iobuf_desc (a, desc), a->filter_eof, (int) a->d.start, (int) a->d.len); } } @@ -1126,6 +1131,7 @@ iobuf_close (iobuf_t a) for (; a; a = a_chain) { + byte desc[MAX_IOBUF_DESC]; int rc2 = 0; a_chain = a->chain; @@ -1135,7 +1141,7 @@ iobuf_close (iobuf_t a) if (DBG_IOBUF) log_debug ("iobuf-%d.%d: close '%s'\n", - a->no, a->subno, iobuf_desc (a)); + a->no, a->subno, iobuf_desc (a, desc)); if (a->filter && (rc2 = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain, NULL, &dummy_len))) @@ -1275,6 +1281,7 @@ do_open (const char *fname, int special_filenames, size_t len = 0; int print_only = 0; int fd; + byte desc[MAX_IOBUF_DESC]; assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT); @@ -1321,7 +1328,7 @@ do_open (const char *fname, int special_filenames, file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); if (DBG_IOBUF) log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n", - a->no, a->subno, fname, iobuf_desc (a), FD2INT (fcx->fp)); + a->no, a->subno, fname, iobuf_desc (a, desc), FD2INT (fcx->fp)); return a; } @@ -1439,6 +1446,8 @@ iobuf_sockopen (int fd, const char *mode) int iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval) { + byte desc[MAX_IOBUF_DESC]; + if (cmd == IOBUF_IOCTL_KEEP_OPEN) { /* Keep system filepointer/descriptor open. This was used in @@ -1446,7 +1455,7 @@ iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval) anymore. */ if (DBG_IOBUF) log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n", - a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a), + a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc), intval); for (; a; a = a->chain) if (!a->chain && a->filter == file_filter) @@ -1480,7 +1489,7 @@ iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval) { if (DBG_IOBUF) log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n", - a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a), + a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc), intval); for (; a; a = a->chain) if (!a->chain && a->filter == file_filter) @@ -1658,8 +1667,9 @@ iobuf_push_filter2 (iobuf_t a, if (DBG_IOBUF) { + byte desc[MAX_IOBUF_DESC]; log_debug ("iobuf-%d.%d: push '%s'\n", - a->no, a->subno, iobuf_desc (a)); + a->no, a->subno, iobuf_desc (a, desc)); print_chain (a); } @@ -1681,10 +1691,11 @@ pop_filter (iobuf_t a, int (*f) (void *opaque, int control, iobuf_t b; size_t dummy_len = 0; int rc = 0; + byte desc[MAX_IOBUF_DESC]; if (DBG_IOBUF) log_debug ("iobuf-%d.%d: pop '%s'\n", - a->no, a->subno, iobuf_desc (a)); + a->no, a->subno, iobuf_desc (a, desc)); if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP) { /* This should be the last filter in the pipeline. */ @@ -2188,6 +2199,7 @@ iobuf_write_temp (iobuf_t dest, iobuf_t source) size_t iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen) { + byte desc[MAX_IOBUF_DESC]; size_t n; while (1) @@ -2195,7 +2207,7 @@ iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen) int rc = filter_flush (a); if (rc) log_bug ("Flushing iobuf %d.%d (%s) from iobuf_temp_to_buffer failed. Ignoring.\n", - a->no, a->subno, iobuf_desc (a)); + a->no, a->subno, iobuf_desc (a, desc)); if (! a->chain) break; a = a->chain; diff --git a/common/iobuf.h b/common/iobuf.h index cb79105..69764d6 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -404,10 +404,10 @@ int iobuf_cancel (iobuf_t iobuf); called on the pipeline. IOBUFCTRL_DESC: Called with this value to get a human-readable - description of the filter. * (char **) BUF should set to the - NUL-terminated string. Note: you need to keep track of this - value and, if necessary, free it when the filter function is - called with control set to IOBUFCTRL_FREE. + description of the filter. *LEN is the size of the buffer. + The description is filled into BUF, NUL-terminated. Always + returns 0. When the size of the buffer is shorter than the + description, it is truncated and not NUL-terminated. */ int iobuf_push_filter (iobuf_t a, int (*f) (void *opaque, int control, iobuf_t chain, byte * buf, diff --git a/common/t-iobuf.c b/common/t-iobuf.c index 99581b9..2835df4 100644 --- a/common/t-iobuf.c +++ b/common/t-iobuf.c @@ -5,6 +5,7 @@ #include #include "iobuf.h" +#include "stringhelp.h" /* Return every other byte. In particular, reads two bytes, returns the second one. */ @@ -16,7 +17,7 @@ every_other_filter (void *opaque, int control, if (control == IOBUFCTRL_DESC) { - *(char **) buf = "every_other_filter"; + mem2str (buf, "every_other_filter", *len); } if (control == IOBUFCTRL_UNDERFLOW) { @@ -52,7 +53,7 @@ double_filter (void *opaque, int control, if (control == IOBUFCTRL_DESC) { - * (char **) buf = "double_filter"; + mem2str (buf, "double_filter", *len); } if (control == IOBUFCTRL_FLUSH) { diff --git a/g10/armor.c b/g10/armor.c index 6c133a2..55ee5d3 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1251,7 +1251,7 @@ armor_filter( void *opaque, int control, release_armor_context (afx); } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "armor_filter"; + mem2str (buf, "armor_filter", *ret_len); return rc; } diff --git a/g10/cipher.c b/g10/cipher.c index b72b144..41324c3 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -157,7 +157,7 @@ cipher_filter( void *opaque, int control, gcry_cipher_close (cfx->cipher_hd); } else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "cipher_filter"; + mem2str (buf, "cipher_filter", *ret_len); } return rc; } diff --git a/g10/compress-bz2.c b/g10/compress-bz2.c index ea80956..128eadf 100644 --- a/g10/compress-bz2.c +++ b/g10/compress-bz2.c @@ -248,6 +248,6 @@ compress_filter_bz2( void *opaque, int control, zfx->release (zfx); } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "compress_filter"; + mem2str (buf, "compress_filter", *ret_len); return rc; } diff --git a/g10/compress.c b/g10/compress.c index 8047dbb..fd1ed6a 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -288,7 +288,7 @@ compress_filter( void *opaque, int control, zfx->release (zfx); } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "compress_filter"; + mem2str (buf, "compress_filter", *ret_len); return rc; } #endif /*HAVE_ZIP*/ diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 2d9f54f..1380faf 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -425,7 +425,7 @@ mdc_decode_filter (void *opaque, int control, IOBUF a, } else if ( control == IOBUFCTRL_DESC ) { - *(char**)buf = "mdc_decode_filter"; + mem2str (buf, "mdc_decode_filter", *ret_len); } return rc; } @@ -496,7 +496,7 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) } else if ( control == IOBUFCTRL_DESC ) { - *(char**)buf = "decode_filter"; + mem2str (buf, "decode_filter", *ret_len); } return rc; } diff --git a/g10/encrypt.c b/g10/encrypt.c index eca1c27..abd8002 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -848,7 +848,7 @@ encrypt_filter (void *opaque, int control, } else if ( control == IOBUFCTRL_DESC ) { - *(char**)buf = "encrypt_filter"; + mem2str (buf, "encrypt_filter", *ret_len); } return rc; } diff --git a/g10/mdfilter.c b/g10/mdfilter.c index 708bdcd..88b2ee1 100644 --- a/g10/mdfilter.c +++ b/g10/mdfilter.c @@ -58,7 +58,7 @@ md_filter( void *opaque, int control, *ret_len = i; } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "md_filter"; + mem2str (buf, "md_filter", *ret_len); return rc; } diff --git a/g10/progress.c b/g10/progress.c index ca20223..f4b4698 100644 --- a/g10/progress.c +++ b/g10/progress.c @@ -131,7 +131,7 @@ progress_filter (void *opaque, int control, release_progress_context (pfx); } else if (control == IOBUFCTRL_DESC) - *(char**)buf = "progress_filter"; + mem2str (buf, "progress_filter", *ret_len); return rc; } diff --git a/g10/textfilter.c b/g10/textfilter.c index 394d9c3..da303c4 100644 --- a/g10/textfilter.c +++ b/g10/textfilter.c @@ -150,7 +150,7 @@ text_filter( void *opaque, int control, tfx->buffer = NULL; } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "text_filter"; + mem2str (buf, "text_filter", *ret_len); return rc; } ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 52 ++++++++++++++++++++++++++++++++-------------------- common/iobuf.h | 8 ++++---- common/t-iobuf.c | 5 +++-- g10/armor.c | 2 +- g10/cipher.c | 2 +- g10/compress-bz2.c | 2 +- g10/compress.c | 2 +- g10/decrypt-data.c | 4 ++-- g10/encrypt.c | 2 +- g10/mdfilter.c | 2 +- g10/progress.c | 2 +- g10/textfilter.c | 2 +- 12 files changed, 49 insertions(+), 36 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 12 03:46:53 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 12 Jan 2016 03:46:53 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-106-g4b4639b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 4b4639b0b04dc82c550fa711dd7193e13fc4a428 (commit) from 3f52c7da3940ec06572270d511000dc7fe9c27d2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4b4639b0b04dc82c550fa711dd7193e13fc4a428 Author: NIIBE Yutaka Date: Tue Jan 12 11:45:31 2016 +0900 common: Fix iobuf API of filter function for alignment. * common/iobuf.h: Fix comment. -- Signed-off-by: NIIBE Yutaka diff --git a/common/iobuf.h b/common/iobuf.h index 69764d6..8ba02b3 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -406,8 +406,7 @@ int iobuf_cancel (iobuf_t iobuf); IOBUFCTRL_DESC: Called with this value to get a human-readable description of the filter. *LEN is the size of the buffer. The description is filled into BUF, NUL-terminated. Always - returns 0. When the size of the buffer is shorter than the - description, it is truncated and not NUL-terminated. + returns 0. */ int iobuf_push_filter (iobuf_t a, int (*f) (void *opaque, int control, iobuf_t chain, byte * buf, ----------------------------------------------------------------------- Summary of changes: common/iobuf.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 12 10:50:35 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Jan 2016 10:50:35 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-107-g4619ea8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 4619ea8e519215b4ae0685cd3881937ec26c32d3 (commit) from 4b4639b0b04dc82c550fa711dd7193e13fc4a428 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4619ea8e519215b4ae0685cd3881937ec26c32d3 Author: Werner Koch Date: Tue Jan 12 10:41:07 2016 +0100 gpg: Re-indent check_key_signature2. -- I am considering some changes and thus better start off by switching to standard GNU indentation. This patch also changes comment lines like if (foo) /* Comment on foo. */ { to if (foo) { /* Comment on foo. */ or if (foo) /* Comment on foo. */ { to make the brace of the opening block stand out immediately. Further stars on the left are added to longer comments because that makes the code easier to read by disabled hackers, when reading without font locking, and for reading black-white printouts. diff --git a/g10/sig-check.c b/g10/sig-check.c index 75b06e8..bcf46f8 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -48,42 +48,43 @@ check_signature (PKT_signature *sig, gcry_md_hd_t digest) return check_signature2 (sig, digest, NULL, NULL, NULL, NULL); } -/* Check a signature. - - Looks up the public key that created the signature (SIG->KEYID) - from the key db. Makes sure that the signature is valid (it was - not created prior to the key, the public key was created in the - past, and the signature does not include any unsupported critical - features), finishes computing the hash of the signature data, and - checks that the signature verifies the digest. If the key that - generated the signature is a subkey, this function also verifies - that there is a valid backsig from the subkey to the primary key. - Finally, if status fd is enabled and the signature class is 0x00 or - 0x01, then a STATUS_SIG_ID is emitted on the status fd. - - SIG is the signature to check. - - DIGEST contains a valid hash context that already includes the - signed data. This function adds the relevant meta-data from the - signature packet to compute the final hash. (See Section 5.2 of - RFC 4880: "The concatenation of the data being signed and the - signature data from the version number through the hashed subpacket - data (inclusive) is hashed.") - - If R_EXPIREDATE is not NULL, R_EXPIREDATE is set to the key's - expiry. - - If R_EXPIRED is not NULL, *R_EXPIRED is set to 1 if PK has expired - (0 otherwise). Note: PK being expired does not cause this function - to fail. - - If R_REVOKED is not NULL, *R_REVOKED is set to 1 if PK has been - revoked (0 otherwise). Note: PK being revoked does not cause this - function to fail. - - If PK is not NULL, the public key is saved in *PK on success. - Returns 0 on success. An error code otherwise. */ +/* Check a signature. + * + * Looks up the public key that created the signature (SIG->KEYID) + * from the key db. Makes sure that the signature is valid (it was + * not created prior to the key, the public key was created in the + * past, and the signature does not include any unsupported critical + * features), finishes computing the hash of the signature data, and + * checks that the signature verifies the digest. If the key that + * generated the signature is a subkey, this function also verifies + * that there is a valid backsig from the subkey to the primary key. + * Finally, if status fd is enabled and the signature class is 0x00 or + * 0x01, then a STATUS_SIG_ID is emitted on the status fd. + * + * SIG is the signature to check. + * + * DIGEST contains a valid hash context that already includes the + * signed data. This function adds the relevant meta-data from the + * signature packet to compute the final hash. (See Section 5.2 of + * RFC 4880: "The concatenation of the data being signed and the + * signature data from the version number through the hashed subpacket + * data (inclusive) is hashed.") + * + * If R_EXPIREDATE is not NULL, R_EXPIREDATE is set to the key's + * expiry. + * + * If R_EXPIRED is not NULL, *R_EXPIRED is set to 1 if PK has expired + * (0 otherwise). Note: PK being expired does not cause this function + * to fail. + * + * If R_REVOKED is not NULL, *R_REVOKED is set to 1 if PK has been + * revoked (0 otherwise). Note: PK being revoked does not cause this + * function to fail. + * + * If PK is not NULL, the public key is saved in *PK on success. + * + * Returns 0 on success. An error code otherwise. */ int check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, int *r_expired, int *r_revoked, PKT_public_key *pk ) @@ -237,22 +238,22 @@ check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, /* The signature SIG was generated with the public key PK. Check - whether the signature is valid in the following sense: - - - Make sure the public key was created before the signature was - generated. - - - Make sure the public key was created in the past - - - Check whether PK has expired (set *R_EXPIRED to 1 if so and 0 - otherwise) - - - Check whether PK has been revoked (set *R_REVOKED to 1 if so - and 0 otherwise). - - If either of the first two tests fail, returns an error code. - Otherwise returns 0. (Thus, this function doesn't fail if the - public key is expired or revoked.) */ + * whether the signature is valid in the following sense: + * + * - Make sure the public key was created before the signature was + * generated. + * + * - Make sure the public key was created in the past + * + * - Check whether PK has expired (set *R_EXPIRED to 1 if so and 0 + * otherwise) + * + * - Check whether PK has been revoked (set *R_REVOKED to 1 if so + * and 0 otherwise). + * + * If either of the first two tests fail, returns an error code. + * Otherwise returns 0. (Thus, this function doesn't fail if the + * public key is expired or revoked.) */ static int check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig, int *r_expired, int *r_revoked) @@ -318,34 +319,34 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig, /* Finish generating a signature and check it. Concretely: make sure - that the signature is valid (it was not created prior to the key, - the public key was created in the past, and the signature does not - include any unsupported critical features), finish computing the - digest by adding the relevant data from the signature packet, and - check that the signature verifies the digest. - - DIGEST contains a hash context, which has already hashed the signed - data. This function adds the relevant meta-data from the signature - packet to compute the final hash. (See Section 5.2 of RFC 4880: - "The concatenation of the data being signed and the signature data - from the version number through the hashed subpacket data - (inclusive) is hashed.") - - SIG is the signature to check. - - PK is the public key used to generate the signature. - - If R_EXPIRED is not NULL, *R_EXPIRED is set to 1 if PK has expired - (0 otherwise). Note: PK being expired does not cause this function - to fail. - - If R_REVOKED is not NULL, *R_REVOKED is set to 1 if PK has been - revoked (0 otherwise). Note: PK being revoked does not cause this - function to fail. - - If RET_PK is not NULL, PK is copied into RET_PK on success. - - Returns 0 on success. An error code other. */ + * that the signature is valid (it was not created prior to the key, + * the public key was created in the past, and the signature does not + * include any unsupported critical features), finish computing the + * digest by adding the relevant data from the signature packet, and + * check that the signature verifies the digest. + * + * DIGEST contains a hash context, which has already hashed the signed + * data. This function adds the relevant meta-data from the signature + * packet to compute the final hash. (See Section 5.2 of RFC 4880: + * "The concatenation of the data being signed and the signature data + * from the version number through the hashed subpacket data + * (inclusive) is hashed.") + * + * SIG is the signature to check. + * + * PK is the public key used to generate the signature. + * + * If R_EXPIRED is not NULL, *R_EXPIRED is set to 1 if PK has expired + * (0 otherwise). Note: PK being expired does not cause this function + * to fail. + * + * If R_REVOKED is not NULL, *R_REVOKED is set to 1 if PK has been + * revoked (0 otherwise). Note: PK being revoked does not cause this + * function to fail. + * + * If RET_PK is not NULL, PK is copied into RET_PK on success. + * + * Returns 0 on success. An error code other. */ static int check_signature_end (PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest, @@ -486,35 +487,36 @@ cache_sig_result ( PKT_signature *sig, int result ) } } + /* SIG is a key revocation signature. Check if this signature was - generated by any of the public key PK's designated revokers. - - PK is the public key that SIG allegedly revokes. - - SIG is the revocation signature to check. - - This function avoids infinite recursion, which can happen if two - keys are designed revokers for each other and they revoke each - other. This is done by observing that if a key A is revoked by key - B we still consider the revocation to be valid even if B is - revoked. Thus, we don't need to determine whether B is revoked to - determine whether A has been revoked by B, we just need to check - the signature. - - Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not - revoked. We are careful to make sure that GPG_ERR_NO_PUBKEY is - only returned when a revocation signature is from a valid - revocation key designated in a revkey subpacket, but the revocation - key itself isn't present. */ - -/* XXX: This code will need to be modified if gpg ever becomes - multi-threaded. Note that this guarantees that a designated - revocation sig will never be considered valid unless it is actually - valid, as well as being issued by a revocation key in a valid - direct signature. Note also that this is written so that a revoked - revoker can still issue revocations: i.e. If A revokes B, but A is - revoked, B is still revoked. I'm not completely convinced this is - the proper behavior, but it matches how PGP does it. -dms */ + * generated by any of the public key PK's designated revokers. + * + * PK is the public key that SIG allegedly revokes. + * + * SIG is the revocation signature to check. + * + * This function avoids infinite recursion, which can happen if two + * keys are designed revokers for each other and they revoke each + * other. This is done by observing that if a key A is revoked by key + * B we still consider the revocation to be valid even if B is + * revoked. Thus, we don't need to determine whether B is revoked to + * determine whether A has been revoked by B, we just need to check + * the signature. + * + * Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not + * revoked. We are careful to make sure that GPG_ERR_NO_PUBKEY is + * only returned when a revocation signature is from a valid + * revocation key designated in a revkey subpacket, but the revocation + * key itself isn't present. + * + * XXX: This code will need to be modified if gpg ever becomes + * multi-threaded. Note that this guarantees that a designated + * revocation sig will never be considered valid unless it is actually + * valid, as well as being issued by a revocation key in a valid + * direct signature. Note also that this is written so that a revoked + * revoker can still issue revocations: i.e. If A revokes B, but A is + * revoked, B is still revoked. I'm not completely convinced this is + * the proper behavior, but it matches how PGP does it. -dms */ int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig) { @@ -526,29 +528,29 @@ check_revocation_keys (PKT_public_key *pk, PKT_signature *sig) assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1])); /* Avoid infinite recursion. Consider the following: - - - We want to check if A is revoked. - - - C is a designated revoker for B and has revoked B. - - - B is a designated revoker for A and has revoked A. - - When checking if A is revoked (in merge_selfsigs_main), we - observe that A has a designed revoker. As such, we call this - function. This function sees that there is a valid revocation - signature, which is signed by B. It then calls check_signature() - to verify that the signature is good. To check the sig, we need - to lookup B. Looking up B means calling merge_selfsigs_main, - which checks whether B is revoked, which calls this function to - see if B was revoked by some key. - - In this case, the added level of indirection doesn't hurt. It - just means a bit more work. However, if C == A, then we'd end up - in a loop. But, it doesn't make sense to look up C anyways: even - if B is revoked, we conservatively consider a valid revocation - signed by B to revoke A. Since this is the only place where this - type of recursion can occur, we simply cause this function to - fail if it is entered recursively. */ + * + * - We want to check if A is revoked. + * + * - C is a designated revoker for B and has revoked B. + * + * - B is a designated revoker for A and has revoked A. + * + * When checking if A is revoked (in merge_selfsigs_main), we + * observe that A has a designed revoker. As such, we call this + * function. This function sees that there is a valid revocation + * signature, which is signed by B. It then calls check_signature() + * to verify that the signature is good. To check the sig, we need + * to lookup B. Looking up B means calling merge_selfsigs_main, + * which checks whether B is revoked, which calls this function to + * see if B was revoked by some key. + * + * In this case, the added level of indirection doesn't hurt. It + * just means a bit more work. However, if C == A, then we'd end up + * in a loop. But, it doesn't make sense to look up C anyways: even + * if B is revoked, we conservatively consider a valid revocation + * signed by B to revoke A. Since this is the only place where this + * type of recursion can occur, we simply cause this function to + * fail if it is entered recursively. */ if (busy) { /* Return an error (i.e. not revoked), but mark the pk as @@ -637,202 +639,225 @@ check_backsig (PKT_public_key *main_pk,PKT_public_key *sub_pk, /* Check that a signature over a key is valid. This is a - specialization of check_key_signature2 with the unnamed parameters - passed as NULL. See the documentation for that function for more - details. */ + * specialization of check_key_signature2 with the unnamed parameters + * passed as NULL. See the documentation for that function for more + * details. */ int check_key_signature (KBNODE root, KBNODE node, int *is_selfsig) { return check_key_signature2 (root, node, NULL, NULL, is_selfsig, NULL, NULL); } -/* Check that a signature over a key (e.g., a key revocation, key - binding, user id certification, etc.) is valid. If the function - detects a self-signature, it uses the public key from the specified - key block and does not bother looking up the key specified in the - signature packet. - - ROOT is a keyblock. - - NODE references a signature packet that appears in the keyblock - that should be verified. - - If CHECK_PK is set, the specified key is sometimes preferred for - verifying signatures. See the implementation for details. - - If RET_PK is not NULL, the public key that successfully verified - the signature is copied into *RET_PK. - - If IS_SELFSIG is not NULL, *IS_SELFSIG is set to 1 if NODE is a - self-signature. - - If R_EXPIREDATE is not NULL, *R_EXPIREDATE is set to the expiry - date. - - If R_EXPIRED is not NULL, *R_EXPIRED is set to 1 if PK has been - expired (0 otherwise). Note: PK being revoked does not cause this - function to fail. - - If OPT.NO_SIG_CACHE is not set, this function will first check if - the result of a previous verification is already cached in the - signature packet's data structure. */ -/* TODO: add r_revoked here as well. It has the same problems as - r_expiredate and r_expired and the cache. */ +/* Check that a signature over a key (e.g., a key revocation, key + * binding, user id certification, etc.) is valid. If the function + * detects a self-signature, it uses the public key from the specified + * key block and does not bother looking up the key specified in the + * signature packet. + * + * ROOT is a keyblock. + * + * NODE references a signature packet that appears in the keyblock + * that should be verified. + * + * If CHECK_PK is set, the specified key is sometimes preferred for + * verifying signatures. See the implementation for details. + * + * If RET_PK is not NULL, the public key that successfully verified + * the signature is copied into *RET_PK. + * + * If IS_SELFSIG is not NULL, *IS_SELFSIG is set to 1 if NODE is a + * self-signature. + * + * If R_EXPIREDATE is not NULL, *R_EXPIREDATE is set to the expiry + * date. + * + * If R_EXPIRED is not NULL, *R_EXPIRED is set to 1 if PK has been + * expired (0 otherwise). Note: PK being revoked does not cause this + * function to fail. + * + * + * If OPT.NO_SIG_CACHE is not set, this function will first check if + * the result of a previous verification is already cached in the + * signature packet's data structure. + * + * TODO: add r_revoked here as well. It has the same problems as + * r_expiredate and r_expired and the cache. */ int -check_key_signature2(KBNODE root, KBNODE node, PKT_public_key *check_pk, - PKT_public_key *ret_pk, int *is_selfsig, - u32 *r_expiredate, int *r_expired ) +check_key_signature2 (kbnode_t root, kbnode_t node, PKT_public_key *check_pk, + PKT_public_key *ret_pk, int *is_selfsig, + u32 *r_expiredate, int *r_expired ) { - gcry_md_hd_t md; - PKT_public_key *pk; - PKT_signature *sig; - int algo; - int rc; - - if( is_selfsig ) - *is_selfsig = 0; - if( r_expiredate ) - *r_expiredate = 0; - if( r_expired ) - *r_expired = 0; - assert( node->pkt->pkttype == PKT_SIGNATURE ); - assert( root->pkt->pkttype == PKT_PUBLIC_KEY ); - - pk = root->pkt->pkt.public_key; - sig = node->pkt->pkt.signature; - algo = sig->digest_algo; - - /* Check whether we have cached the result of a previous signature - check. Note that we may no longer have the pubkey or hash - needed to verify a sig, but can still use the cached value. A - cache refresh detects and clears these cases. */ - if ( !opt.no_sig_cache ) { - if (sig->flags.checked) { /*cached status available*/ - if( is_selfsig ) { - u32 keyid[2]; + gcry_md_hd_t md; + PKT_public_key *pk; + PKT_signature *sig; + int algo; + int rc; - keyid_from_pk( pk, keyid ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - *is_selfsig = 1; + if (is_selfsig) + *is_selfsig = 0; + if (r_expiredate) + *r_expiredate = 0; + if (r_expired) + *r_expired = 0; + assert (node->pkt->pkttype == PKT_SIGNATURE); + assert (root->pkt->pkttype == PKT_PUBLIC_KEY); + + pk = root->pkt->pkt.public_key; + sig = node->pkt->pkt.signature; + algo = sig->digest_algo; + + /* Check whether we have cached the result of a previous signature + check. Note that we may no longer have the pubkey or hash + needed to verify a sig, but can still use the cached value. A + cache refresh detects and clears these cases. */ + if ( !opt.no_sig_cache ) + { + if (sig->flags.checked) /* Cached status available. */ + { + if (is_selfsig) + { + u32 keyid[2]; + + keyid_from_pk (pk, keyid); + if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]) + *is_selfsig = 1; } - /* BUG: This is wrong for non-self-sigs.. needs to be the - actual pk */ - if((rc = check_signature_metadata_validity (pk, sig, - r_expired, NULL))) - return rc; - return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE); + /* BUG: This is wrong for non-self-sigs... needs to be the + actual pk. */ + rc = check_signature_metadata_validity (pk, sig, r_expired, NULL); + if (rc) + return rc; + return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE); } } - if( (rc=openpgp_pk_test_algo(sig->pubkey_algo)) ) - return rc; - if( (rc=openpgp_md_test_algo(algo)) ) - return rc; - - if( sig->sig_class == 0x20 ) { /* key revocation */ - u32 keyid[2]; - keyid_from_pk( pk, keyid ); + rc = openpgp_pk_test_algo(sig->pubkey_algo); + if (rc) + return rc; + rc = openpgp_md_test_algo(algo); + if (rc) + return rc; - /* is it a designated revoker? */ - if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1]) - rc=check_revocation_keys(pk,sig); - else - { - if (gcry_md_open (&md, algo, 0 )) - BUG (); - hash_public_key( md, pk ); - rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } + if (sig->sig_class == 0x20) /* key revocation */ + { + u32 keyid[2]; + keyid_from_pk( pk, keyid ); + + /* Is it a designated revoker? */ + if (keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1]) + rc = check_revocation_keys (pk, sig); + else + { + if (gcry_md_open (&md, algo, 0)) + BUG (); + hash_public_key (md, pk); + rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); + cache_sig_result (sig, rc); + gcry_md_close (md); + } } - else if( sig->sig_class == 0x28 ) { /* subkey revocation */ - KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY ); - - if( snode ) { - if (gcry_md_open (&md, algo, 0)) - BUG (); - hash_public_key( md, pk ); - hash_public_key( md, snode->pkt->pkt.public_key ); - rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - cache_sig_result ( sig, rc ); - gcry_md_close(md); + else if (sig->sig_class == 0x28) /* subkey revocation */ + { + kbnode_t snode = find_prev_kbnode (root, node, PKT_PUBLIC_SUBKEY); + + if (snode) + { + if (gcry_md_open (&md, algo, 0)) + BUG (); + hash_public_key (md, pk); + hash_public_key (md, snode->pkt->pkt.public_key); + rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); + cache_sig_result (sig, rc); + gcry_md_close (md); } - else - { - if (opt.verbose) - log_info (_("key %s: no subkey for subkey" - " revocation signature\n"),keystr_from_pk(pk)); - rc = GPG_ERR_SIG_CLASS; - } + else + { + if (opt.verbose) + log_info (_("key %s: no subkey for subkey" + " revocation signature\n"), keystr_from_pk(pk)); + rc = GPG_ERR_SIG_CLASS; + } } - else if( sig->sig_class == 0x18 ) { /* key binding */ - KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY ); + else if (sig->sig_class == 0x18) /* key binding */ + { + kbnode_t snode = find_prev_kbnode (root, node, PKT_PUBLIC_SUBKEY); - if( snode ) { - if( is_selfsig ) { /* does this make sense????? */ - u32 keyid[2]; /* it should always be a selfsig */ + if (snode) + { + if (is_selfsig) + { + /* Does this make sense? It should always be a + selfsig. Yes: We can't be sure about this and we + need to be able to indicate that it is a selfsig. + FIXME: The question is whether we should reject + such a signature if it is not a selfsig. */ + u32 keyid[2]; - keyid_from_pk( pk, keyid ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - *is_selfsig = 1; - } + keyid_from_pk (pk, keyid); + if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]) + *is_selfsig = 1; + } if (gcry_md_open (&md, algo, 0)) BUG (); - hash_public_key( md, pk ); - hash_public_key( md, snode->pkt->pkt.public_key ); + hash_public_key (md, pk); + hash_public_key (md, snode->pkt->pkt.public_key); rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); cache_sig_result ( sig, rc ); - gcry_md_close(md); - } + gcry_md_close (md); + } else { if (opt.verbose) log_info(_("key %s: no subkey for subkey" - " binding signature\n"),keystr_from_pk(pk)); + " binding signature\n"), keystr_from_pk(pk)); rc = GPG_ERR_SIG_CLASS; } - } - else if( sig->sig_class == 0x1f ) { /* direct key signature */ + } + else if (sig->sig_class == 0x1f) /* direct key signature */ + { if (gcry_md_open (&md, algo, 0 )) BUG (); hash_public_key( md, pk ); rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { /* all other classes */ - KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID ); + cache_sig_result (sig, rc); + gcry_md_close (md); + } + else /* all other classes */ + { + kbnode_t unode = find_prev_kbnode (root, node, PKT_USER_ID); - if( unode ) { + if (unode) + { u32 keyid[2]; - keyid_from_pk( pk, keyid ); - if (gcry_md_open (&md, algo, 0 )) + keyid_from_pk (pk, keyid); + if (gcry_md_open (&md, algo, 0)) BUG (); - hash_public_key( md, pk ); - hash_uid_node( unode, md, sig ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - /* The primary key is the signing key. */ - { - if( is_selfsig ) + hash_public_key (md, pk); + hash_uid_node (unode, md, sig); + if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]) + { /* The primary key is the signing key. */ + + if (is_selfsig) *is_selfsig = 1; rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); } else if (check_pk) - /* The caller specified a key. Try that. */ - rc = check_signature_end (check_pk, sig, md, - r_expired, NULL, ret_pk); + { /* The caller specified a key. Try that. */ + + rc = check_signature_end (check_pk, sig, md, + r_expired, NULL, ret_pk); + } else - /* Look up the key. XXX: Could it be that the key is - not is not in this keyblock? */ - rc = check_signature2 (sig, md, r_expiredate, r_expired, - NULL, ret_pk); + { /* Look up the key. */ + rc = check_signature2 (sig, md, r_expiredate, r_expired, + NULL, ret_pk); + } - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } + cache_sig_result (sig, rc); + gcry_md_close (md); + } else { if (!opt.quiet) @@ -840,7 +865,7 @@ check_key_signature2(KBNODE root, KBNODE node, PKT_public_key *check_pk, " of class %02x\n",keystr_from_pk(pk),sig->sig_class); rc = GPG_ERR_SIG_CLASS; } - } + } - return rc; + return rc; } ----------------------------------------------------------------------- Summary of changes: g10/sig-check.c | 593 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 309 insertions(+), 284 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 12 19:19:32 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Jan 2016 19:19:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-108-ge2f984b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via e2f984b4afffaa89bdeba2f5d447b5681237177e (commit) from 4619ea8e519215b4ae0685cd3881937ec26c32d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e2f984b4afffaa89bdeba2f5d447b5681237177e Author: Werner Koch Date: Tue Jan 12 19:12:02 2016 +0100 ssh: Accept OpenSSH *cert-v01 key variants. * agent/command-ssh.c (SPEC_FLAG_WITH_CERT): New. (ssh_key_types): Add OpenSSH cert types. (stream_read_string): Allow a dummy read. (ssh_receive_mpint_list): Pass SPEC by reference. (ssh_receive_mpint_list): New arg CERT and use it. (ssh_receive_key): Read certificate into an estream object and modify parser to make use of that object. -- This is a first step to support certificate via the agent. The only effect of this change is the removal of an error message parsing the certificate. Note that ssh-add sends the private key anyway first and only then follows with the certificate+private key. What we need to implement next is a way to store the certificate in the agent and return it on request. Signed-off-by: Werner Koch diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 5f159f1..6e809f6 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -75,6 +75,7 @@ #define SPEC_FLAG_USE_PKCS1V2 (1 << 0) #define SPEC_FLAG_IS_ECDSA (1 << 1) #define SPEC_FLAG_IS_EdDSA (1 << 2) /*(lowercase 'd' on purpose.)*/ +#define SPEC_FLAG_WITH_CERT (1 << 7) /* The name of the control file. */ #define SSH_CONTROL_FILE_NAME "sshcontrol" @@ -302,6 +303,42 @@ static ssh_key_type_spec_t ssh_key_types[] = "ecdsa-sha2-nistp521", "ECDSA", "ecdsa", "qd", "q", "rs", "qd", NULL, ssh_signature_encoder_ecdsa, "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA + }, + { + "ssh-ed25519-cert-v01 at openssh.com", "Ed25519", + "ecc", "qd", "q", "rs", "qd", + NULL, ssh_signature_encoder_eddsa, + "Ed25519", 0, SPEC_FLAG_IS_EdDSA | SPEC_FLAG_WITH_CERT + }, + { + "ssh-rsa-cert-v01 at openssh.com", "RSA", + "rsa", "nedupq", "en", "s", "nedpqu", + ssh_key_modifier_rsa, ssh_signature_encoder_rsa, + NULL, 0, SPEC_FLAG_USE_PKCS1V2 | SPEC_FLAG_WITH_CERT + }, + { + "ssh-dss-cert-v01 at openssh.com", "DSA", + "dsa", "pqgyx", "pqgy", "rs", "pqgyx", + NULL, ssh_signature_encoder_dsa, + NULL, 0, SPEC_FLAG_WITH_CERT | SPEC_FLAG_WITH_CERT + }, + { + "ecdsa-sha2-nistp256-cert-v01 at openssh.com", "ECDSA", + "ecdsa", "qd", "q", "rs", "qd", + NULL, ssh_signature_encoder_ecdsa, + "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT + }, + { + "ecdsa-sha2-nistp384-cert-v01 at openssh.com", "ECDSA", + "ecdsa", "qd", "q", "rs", "qd", + NULL, ssh_signature_encoder_ecdsa, + "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT + }, + { + "ecdsa-sha2-nistp521-cert-v01 at openssh.com", "ECDSA", + "ecdsa", "qd", "q", "rs", "qd", + NULL, ssh_signature_encoder_ecdsa, + "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT } }; @@ -531,7 +568,7 @@ stream_write_data (estream_t stream, const unsigned char *buffer, size_t size) /* Read a binary string from STREAM into STRING, store size of string in STRING_SIZE. Append a hidden nul so that the result may directly be used as a C string. Depending on SECURE use secure - memory for STRING. */ + memory for STRING. If STRING is NULL do only a dummy read. */ static gpg_error_t stream_read_string (estream_t stream, unsigned int secure, unsigned char **string, u32 *string_size) @@ -548,25 +585,35 @@ stream_read_string (estream_t stream, unsigned int secure, if (err) goto out; - /* Allocate space. */ - if (secure) - buffer = xtrymalloc_secure (length + 1); - else - buffer = xtrymalloc (length + 1); - if (! buffer) + if (string) { - err = gpg_error_from_syserror (); - goto out; - } + /* Allocate space. */ + if (secure) + buffer = xtrymalloc_secure (length + 1); + else + buffer = xtrymalloc (length + 1); + if (! buffer) + { + err = gpg_error_from_syserror (); + goto out; + } - /* Read data. */ - err = stream_read_data (stream, buffer, length); - if (err) - goto out; + /* Read data. */ + err = stream_read_data (stream, buffer, length); + if (err) + goto out; + + /* Finalize string object. */ + buffer[length] = 0; + *string = buffer; + } + else /* Dummy read requested. */ + { + err = stream_read_skip (stream, length); + if (err) + goto out; + } - /* Finalize string object. */ - buffer[length] = 0; - *string = buffer; if (string_size) *string_size = length; @@ -1258,31 +1305,38 @@ mpint_list_free (gcry_mpi_t *mpi_list) } /* Receive key material MPIs from STREAM according to KEY_SPEC; - depending on SECRET expect a public key or secret key. The newly + depending on SECRET expect a public key or secret key. CERT is the + certificate blob used if KEY_SPEC indicates the certificate format; + it needs to be positioned to the end of the nonce. The newly allocated list of MPIs is stored in MPI_LIST. Returns usual error code. */ static gpg_error_t ssh_receive_mpint_list (estream_t stream, int secret, - ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list) + ssh_key_type_spec_t *spec, estream_t cert, + gcry_mpi_t **mpi_list) { const char *elems_public; unsigned int elems_n; const char *elems; int elem_is_secret; - gcry_mpi_t *mpis; - gpg_error_t err; + gcry_mpi_t *mpis = NULL; + gpg_error_t err = 0; unsigned int i; - mpis = NULL; - err = 0; - if (secret) - elems = key_spec.elems_key_secret; + elems = spec->elems_key_secret; else - elems = key_spec.elems_key_public; + elems = spec->elems_key_public; elems_n = strlen (elems); + elems_public = spec->elems_key_public; - elems_public = key_spec.elems_key_public; + /* Check that either noth, CERT and the WITH_CERT flag, are given or + none of them. */ + if (!(!!(spec->flags & SPEC_FLAG_WITH_CERT) ^ !cert)) + { + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto out; + } mpis = xtrycalloc (elems_n + 1, sizeof *mpis ); if (!mpis) @@ -1295,18 +1349,20 @@ ssh_receive_mpint_list (estream_t stream, int secret, for (i = 0; i < elems_n; i++) { if (secret) - elem_is_secret = ! strchr (elems_public, elems[i]); - err = stream_read_mpi (stream, elem_is_secret, &mpis[i]); + elem_is_secret = !strchr (elems_public, elems[i]); + + if (cert && !elem_is_secret) + err = stream_read_mpi (cert, elem_is_secret, &mpis[i]); + else + err = stream_read_mpi (stream, elem_is_secret, &mpis[i]); if (err) - break; + goto out; } - if (err) - goto out; *mpi_list = mpis; + mpis = NULL; out: - if (err) mpint_list_free (mpis); @@ -2112,6 +2168,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, gpg_error_t err; char *key_type = NULL; char *comment = NULL; + estream_t cert = NULL; gcry_sexp_t key = NULL; ssh_key_type_spec_t spec; gcry_mpi_t *mpi_list = NULL; @@ -2127,6 +2184,44 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, if (err) goto out; + if ((spec.flags & SPEC_FLAG_WITH_CERT)) + { + /* This is an OpenSSH certificate+private key. The certificate + is an SSH string and which we store in an estream object. */ + unsigned char *buffer; + u32 buflen; + char *cert_key_type; + + err = stream_read_string (stream, 0, &buffer, &buflen); + if (err) + goto out; + cert = es_fopenmem_init (0, "rb", buffer, buflen); + xfree (buffer); + if (!cert) + { + err = gpg_error_from_syserror (); + goto out; + } + + /* Check that the key type matches. */ + err = stream_read_cstring (cert, &cert_key_type); + if (err) + goto out; + if (strcmp (cert_key_type, key_type) ) + { + xfree (cert_key_type); + log_error ("key types in received ssh certificate do not match\n"); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto out; + } + xfree (cert_key_type); + + /* Skip the nonce. */ + err = stream_read_string (cert, 0, NULL, NULL); + if (err) + goto out; + } + if ((spec.flags & SPEC_FLAG_IS_EdDSA)) { /* The format of an EdDSA key is: @@ -2146,7 +2241,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, goto out; } - err = stream_read_blob (stream, 0, &mpi_list[0]); + err = stream_read_blob (cert? cert : stream, 0, &mpi_list[0]); if (err) goto out; if (secret) @@ -2196,12 +2291,14 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, * mpint ecdsa_private * * Note that we use the mpint reader instead of the string - * reader for ecsa_public_key. + * reader for ecsa_public_key. For the certificate variante + * ecdsa_curve_name+ecdsa_public_key are replaced by the + * certificate. */ unsigned char *buffer; const char *mapped; - err = stream_read_string (stream, 0, &buffer, NULL); + err = stream_read_string (cert? cert : stream, 0, &buffer, NULL); if (err) goto out; curve_name = buffer; @@ -2228,13 +2325,13 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, } } - err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list); + err = ssh_receive_mpint_list (stream, secret, &spec, cert, &mpi_list); if (err) goto out; } else { - err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list); + err = ssh_receive_mpint_list (stream, secret, &spec, cert, &mpi_list); if (err) goto out; } @@ -2292,6 +2389,7 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, *key_new = key; out: + es_fclose (cert); mpint_list_free (mpi_list); xfree (curve_name); xfree (key_type); ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 174 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 136 insertions(+), 38 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 13 09:26:45 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 13 Jan 2016 09:26:45 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-109-g96237b9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 96237b9a63a50aed1884cb06f84279b977d6a8fa (commit) from e2f984b4afffaa89bdeba2f5d447b5681237177e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 96237b9a63a50aed1884cb06f84279b977d6a8fa Author: NIIBE Yutaka Date: Wed Jan 13 17:22:37 2016 +0900 Fix to support git worktree. * autogen.sh, Makefile.am, doc/Makefile.am: Use -e for testing .git. -- Signed-off-by: NIIBE Yutaka diff --git a/Makefile.am b/Makefile.am index 8e213f3..8bff2ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -120,7 +120,7 @@ endif gen_start_date = 2011-12-01T06:00:00 .PHONY: gen-ChangeLog gen-ChangeLog: - if test -d $(top_srcdir)/.git; then \ + if test -e $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ --amend=build-aux/git-log-fix \ diff --git a/autogen.sh b/autogen.sh index 3fe24ea..7d843bd 100755 --- a/autogen.sh +++ b/autogen.sh @@ -214,7 +214,7 @@ if [ "$myhost" = "find-version" ]; then esac beta=no - if [ -d .git ]; then + if [ -e .git ]; then ingit=yes tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null) if [ -n "$tmp" ]; then diff --git a/doc/Makefile.am b/doc/Makefile.am index 5449d07..a1a570c 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -136,7 +136,7 @@ dist-hook: defsincdate defsincdate: $(gnupg_TEXINFOS) : >defsincdate ; \ - if test -d $(top_srcdir)/.git; then \ + if test -e $(top_srcdir)/.git; then \ (cd $(srcdir) && git log -1 --format='%ct' \ -- $(gnupg_TEXINFOS) 2>/dev/null) >>defsincdate; \ fi ----------------------------------------------------------------------- Summary of changes: Makefile.am | 2 +- autogen.sh | 2 +- doc/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 13 09:50:09 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 13 Jan 2016 09:50:09 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.29-19-gbaae8d5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via baae8d50d74040bd5a11cd423e04a022af7691e6 (commit) from b508af2b2c40a715ef5ead4455b466954c2943ee (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit baae8d50d74040bd5a11cd423e04a022af7691e6 Author: NIIBE Yutaka Date: Wed Jan 13 17:22:37 2016 +0900 Fix to support git worktree. * Makefile.am: Use -e for testing .git. -- Signed-off-by: NIIBE Yutaka (backport commit of 96237b9a63a50aed1884cb06f84279b977d6a8fa) diff --git a/Makefile.am b/Makefile.am index 892a857..4addcd4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,7 +88,7 @@ gen_start_date = 2011-12-01T06:00:00 .PHONY: gen-ChangeLog gen-ChangeLog: set -e; \ - if test -d $(top_srcdir)/.git; then \ + if test -e $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ --amend=scripts/git-log-fix \ ----------------------------------------------------------------------- Summary of changes: Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 13 09:50:40 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 13 Jan 2016 09:50:40 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-3-ge267067 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via e26706700f6f339891cce924e2a401dfbdba1a0e (commit) from d908e7d2384b5e742d41d468ad079c99f4b0a625 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e26706700f6f339891cce924e2a401dfbdba1a0e Author: NIIBE Yutaka Date: Wed Jan 13 17:22:37 2016 +0900 Fix to support git worktree. * Makefile.am: Use -e for testing .git. -- Signed-off-by: NIIBE Yutaka (backport commit of 96237b9a63a50aed1884cb06f84279b977d6a8fa) diff --git a/Makefile.am b/Makefile.am index 5dca9bd..1c6311b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,7 +82,7 @@ gen_start_date = 2011-12-01T06:00:00 .PHONY: gen-ChangeLog gen-ChangeLog: set -e; \ - if test -d $(top_srcdir)/.git; then \ + if test -e $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ --amend=scripts/git-log-fix \ ----------------------------------------------------------------------- Summary of changes: Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 13 10:51:25 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jan 2016 10:51:25 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-111-g1608629 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 160862978628b07ed5150ec2c8abad6af1656bc3 (commit) via 9dc355ad3ae0026ab04c424dc984d748b8fad393 (commit) from 96237b9a63a50aed1884cb06f84279b977d6a8fa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 160862978628b07ed5150ec2c8abad6af1656bc3 Author: Werner Koch Date: Wed Jan 13 10:16:27 2016 +0100 kbx: Implement keybox_lock for use by gpg. * kbx/keybox-defs.h: Include dotlock.h and logging.h. (CONST_KB_NAME): Remove. Replace usage by KB_NAME. (struct keybox_name): Add field "lockhd". * kbx/keybox-init.c (keybox_register_file): Init LOCKHD. (keybox_lock): Chnage to return gpg_error_t. Implement locking. -- The keybox locking for gpg was not implemented - This needs to be fixed of course. Signed-off-by: Werner Koch diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 6fe9847..6af5448 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -40,6 +40,8 @@ fixme: Better use the LIBOBJ mechnism. */ #include "../common/types.h" #include "../common/stringhelp.h" +#include "../common/dotlock.h" +#include "../common/logging.h" #include "keybox.h" @@ -48,7 +50,6 @@ typedef struct keyboxblob *KEYBOXBLOB; typedef struct keybox_name *KB_NAME; -typedef struct keybox_name const *CONST_KB_NAME; struct keybox_name { /* Link to the next resources, so that we can walk all @@ -58,14 +59,15 @@ struct keybox_name /* True if this is a keybox with secret keys. */ int secret; - /*DOTLOCK lockhd;*/ - /* A table with all the handles accessing this resources. HANDLE_TABLE_SIZE gives the allocated length of this table unused entrues are set to NULL. HANDLE_TABLE may be NULL. */ KEYBOX_HANDLE *handle_table; size_t handle_table_size; + /* The lock handle or NULL it not yet initialized. */ + dotlock_t lockhd; + /* Not yet used. */ int is_locked; @@ -85,7 +87,7 @@ struct keybox_found_s }; struct keybox_handle { - CONST_KB_NAME kb; + KB_NAME kb; int secret; /* this is for a secret keybox */ FILE *fp; int eof; diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index 3ff592e..cfee7b8 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -60,7 +60,7 @@ keybox_register_file (const char *fname, int secret, void **r_token) kr->handle_table = NULL; kr->handle_table_size = 0; - /* kr->lockhd = NULL;*/ + kr->lockhd = NULL; kr->is_locked = 0; kr->did_full_scan = 0; /* keep a list of all issued pointers */ @@ -261,17 +261,55 @@ _keybox_close_file (KEYBOX_HANDLE hd) /* - * Lock the keybox at handle HD, or unlock if YES is false. Note that - * we currently ignore the handle and lock all registered keyboxes. + * Lock the keybox at handle HD, or unlock if YES is false. */ -int +gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes) { - /* FIXME: We need to implement it before we can use it with gpg. - gpgsm does the locking in its local keydb.c driver; this should - be changed as well. */ + gpg_error_t err; + KB_NAME kb = hd->kb; - (void)hd; - (void)yes; - return 0; + if (!keybox_is_writable ((void*)kb)) + return 0; + + /* Make sure the lock handle has been created. */ + if (!kb->lockhd) + { + kb->lockhd = dotlock_create (kb->fname, 0); + if (!kb->lockhd) + { + /* Unfortuntaley dotlock_create does not properly set ERRNO. */ + log_info ("can't allocate lock for '%s'\n", kb->fname ); + return gpg_error (GPG_ERR_GENERAL); + } + } + + if (yes) /* Take the lock. */ + { + if (kb->is_locked) + ; + else if (!dotlock_take (kb->lockhd, -1)) + kb->is_locked = 1; + else + { + /* Unfortuntaley dotlock_take does not properly set ERRNO. */ + log_info ("can't lock '%s'\n", kb->fname ); + err = gpg_error (GPG_ERR_GENERAL); + } + } + else /* Release the lock. */ + { + if (!kb->is_locked) + ; + else if (!dotlock_release (kb->lockhd)) + kb->is_locked = 0; + else + { + /* Unfortuntaley dotlock_release does not properly set ERRNO. */ + log_info ("can't unlock '%s'\n", kb->fname ); + err = gpg_error (GPG_ERR_GENERAL); + } + } + + return err; } diff --git a/kbx/keybox.h b/kbx/keybox.h index acd7a4f..9f91c53 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -76,7 +76,7 @@ void keybox_pop_found_state (KEYBOX_HANDLE hd); const char *keybox_get_resource_name (KEYBOX_HANDLE hd); int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); -int keybox_lock (KEYBOX_HANDLE hd, int yes); +gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes); /*-- keybox-file.c --*/ /* Fixme: This function does not belong here: Provide a better commit 9dc355ad3ae0026ab04c424dc984d748b8fad393 Author: Werner Koch Date: Wed Jan 13 09:29:39 2016 +0100 gpg: Make sure to mark a duplicate registered keybox as primary. * kbx/keybox-init.c (keybox_register_file): Change interface to return the token even if the file has already been registered. * g10/keydb.c (primary_keyring): Rename to primary_keydb. (maybe_create_keyring_or_box): Change return type to gpg_error_t. (keydb_add_resource): Ditto. s/rc/err/. (keydb_add_resource): Mark an already registered as primary. * sm/keydb.c (maybe_create_keybox): Change return type to gpg_error_t. (keydb_add_resource): Ditto. s/rc/err/. (keydb_add_resource): Adjust for changed keybox_register_file. -- This change aligns the registering of keyboxes with those of keyrings. This fixes a potential bug: gpg --keyring foo.kbx --keyring bar.gpg --keyring foo.kbx would have marked bar.gpg as primary resource and thus inserting new keys there. The correct and now fixed behavior is to insert to foo.kbx. Signed-off-by: Werner Koch diff --git a/g10/keydb.c b/g10/keydb.c index e1814fe..3ee9dfd 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -60,7 +60,10 @@ struct resource_item static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; static int used_resources; -static void *primary_keyring=NULL; + +/* A pointer used to check for the primary key database by comparing + to the struct resource_item's TOKEN. */ +static void *primary_keydb; /* This is a simple cache used to return the last result of a @@ -261,7 +264,7 @@ keyblock_cache_clear (struct keydb_handle *hd) the keyring or keybox will be created. Return 0 if it is okay to access the specified file. */ -static int +static gpg_error_t maybe_create_keyring_or_box (char *filename, int is_box, int force_create) { dotlock_t lockhd = NULL; @@ -592,7 +595,7 @@ keydb_add_resource (const char *url, unsigned int flags) int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY); int is_default = !!(flags&KEYDB_RESOURCE_FLAG_DEFAULT); int is_gpgvdef = !!(flags&KEYDB_RESOURCE_FLAG_GPGVDEF); - int rc = 0; + gpg_error_t err = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; void *token; @@ -613,7 +616,7 @@ keydb_add_resource (const char *url, unsigned int flags) else if (strchr (resname, ':')) { log_error ("invalid key resource URL '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ @@ -708,22 +711,22 @@ keydb_add_resource (const char *url, unsigned int flags) { case KEYDB_RESOURCE_TYPE_NONE: log_error ("unknown type of key resource '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; case KEYDB_RESOURCE_TYPE_KEYRING: - rc = maybe_create_keyring_or_box (filename, 0, create); - if (rc) + err = maybe_create_keyring_or_box (filename, 0, create); + if (err) goto leave; if (keyring_register_filename (filename, read_only, &token)) { if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); + err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) - primary_keyring = token; + primary_keydb = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kr = NULL; /* Not used here */ all_resources[used_resources].token = token; @@ -736,26 +739,25 @@ keydb_add_resource (const char *url, unsigned int flags) However, we can still mark it as primary even if it was already registered. */ if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) - primary_keyring = token; + primary_keydb = token; } break; case KEYDB_RESOURCE_TYPE_KEYBOX: { - rc = maybe_create_keyring_or_box (filename, 1, create); - if (rc) + err = maybe_create_keyring_or_box (filename, 1, create); + if (err) goto leave; - /* FIXME: How do we register a read-only keybox? */ - token = keybox_register_file (filename, 0); - if (token) + err = keybox_register_file (filename, 0, &token); + if (!err) { if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); + err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { - /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */ - /* primary_keyring = token; */ + if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) + primary_keydb = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kb = NULL; /* Not used here */ all_resources[used_resources].token = token; @@ -766,32 +768,31 @@ keydb_add_resource (const char *url, unsigned int flags) used_resources++; } } - else + else if (gpg_err_code (err) == GPG_ERR_EEXIST) { /* Already registered. We will mark it as the primary key if requested. */ - /* FIXME: How to do that? Change the keybox interface? */ - /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */ - /* primary_keyring = token; */ + if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) + primary_keydb = token; } } break; default: log_error ("resource type of '%s' not supported\n", url); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } /* fixme: check directory permissions and print a warning */ leave: - if (rc) - log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc)); + if (err) + log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (err)); else any_registered = 1; xfree (filename); - return rc; + return err; } @@ -1685,11 +1686,11 @@ keydb_locate_writable (KEYDB_HANDLE hd) return rc; /* If we have a primary set, try that one first */ - if (primary_keyring) + if (primary_keydb) { for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) { - if(hd->active[hd->current].token==primary_keyring) + if(hd->active[hd->current].token == primary_keydb) { if(keyring_is_writable (hd->active[hd->current].token)) return 0; diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index e91911c..3ff592e 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -30,23 +30,30 @@ static KB_NAME kb_names; -/* Register a filename for plain keybox files. Returns a pointer to - be used to create a handles and so on. Returns NULL to indicate - that FNAME has already been registered. */ -void * -keybox_register_file (const char *fname, int secret) +/* Register a filename for plain keybox files. Returns 0 on success, + * GPG_ERR_EEXIST if it has already been registered, or another error + * code. On success or with error code GPG_ERR_EEXIST a token usable + * to access the keybox handle is stored at R_TOKEN, NULL is stored + * for all other errors. */ +gpg_error_t +keybox_register_file (const char *fname, int secret, void **r_token) { KB_NAME kr; + *r_token = NULL; + for (kr=kb_names; kr; kr = kr->next) { if (same_file_p (kr->fname, fname) ) - return NULL; /* Already registered. */ + { + *r_token = kr; + return gpg_error (GPG_ERR_EEXIST); /* Already registered. */ + } } kr = xtrymalloc (sizeof *kr + strlen (fname)); if (!kr) - return NULL; + return gpg_error_from_syserror (); strcpy (kr->fname, fname); kr->secret = !!secret; @@ -64,7 +71,8 @@ keybox_register_file (const char *fname, int secret) /* if (!kb_offtbl) */ /* kb_offtbl = new_offset_hash_table (); */ - return kr; + *r_token = kr; + return 0; } int diff --git a/kbx/keybox.h b/kbx/keybox.h index 8b75db4..acd7a4f 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -64,7 +64,8 @@ typedef enum /*-- keybox-init.c --*/ -void *keybox_register_file (const char *fname, int secret); +gpg_error_t keybox_register_file (const char *fname, int secret, + void **r_token); int keybox_is_writable (void *token); KEYBOX_HANDLE keybox_new_openpgp (void *token, int secret); diff --git a/sm/keydb.c b/sm/keydb.c index 168cf2c..0ef3c8f 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -107,7 +107,7 @@ try_make_homedir (const char *fname) locked. This lock check does not work if the directory itself is not yet available. If R_CREATED is not NULL it will be set to true if the function created a new keybox. */ -static int +static gpg_error_t maybe_create_keybox (char *filename, int force, int *r_created) { dotlock_t lockhd = NULL; @@ -237,13 +237,13 @@ maybe_create_keybox (char *filename, int force, int *r_created) * does not exist. If AUTO_CREATED is not NULL it will be set to true * if the function has created a new keybox. */ -int +gpg_error_t keydb_add_resource (const char *url, int force, int secret, int *auto_created) { static int any_secret, any_public; const char *resname = url; char *filename = NULL; - int rc = 0; + gpg_error_t err = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; if (auto_created) @@ -264,7 +264,7 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created) else if (strchr (resname, ':')) { log_error ("invalid key resource URL '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ @@ -312,20 +312,24 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created) { case KEYDB_RESOURCE_TYPE_NONE: log_error ("unknown type of key resource '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = maybe_create_keybox (filename, force, auto_created); - if (rc) + err = maybe_create_keybox (filename, force, auto_created); + if (err) goto leave; /* Now register the file */ { - void *token = keybox_register_file (filename, secret); - if (!token) - ; /* already registered - ignore it */ + void *token; + + err = keybox_register_file (filename, secret, &token); + if (gpg_err_code (err) == GPG_ERR_EEXIST) + ; /* Already registered - ignore. */ + else if (err) + ; /* Other error. */ else if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); + err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { all_resources[used_resources].type = rt; @@ -358,21 +362,21 @@ keydb_add_resource (const char *url, int force, int secret, int *auto_created) default: log_error ("resource type of '%s' not supported\n", url); - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); goto leave; } /* fixme: check directory permissions and print a warning */ leave: - if (rc) - log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror(rc)); + if (err) + log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror (err)); else if (secret) any_secret = 1; else any_public = 1; xfree (filename); - return rc; + return err; } diff --git a/sm/keydb.h b/sm/keydb.h index aec31c3..03de1c6 100644 --- a/sm/keydb.h +++ b/sm/keydb.h @@ -31,8 +31,8 @@ typedef struct keydb_handle *KEYDB_HANDLE; /*-- keydb.c --*/ -int keydb_add_resource (const char *url, int force, int secret, - int *auto_created); +gpg_error_t keydb_add_resource (const char *url, int force, int secret, + int *auto_created); KEYDB_HANDLE keydb_new (int secret); void keydb_release (KEYDB_HANDLE hd); int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes); ----------------------------------------------------------------------- Summary of changes: g10/keydb.c | 57 +++++++++++++++++++------------------- kbx/keybox-defs.h | 10 ++++--- kbx/keybox-init.c | 82 +++++++++++++++++++++++++++++++++++++++++++------------ kbx/keybox.h | 5 ++-- sm/keydb.c | 34 +++++++++++++---------- sm/keydb.h | 4 +-- 6 files changed, 123 insertions(+), 69 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 13 14:53:54 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jan 2016 14:53:54 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-114-g9b6c914 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 9b6c91469a804c60289a2ed21334dfd856c294bb (commit) via 8f1368d5e3f7654ad9cb100053535f728dff2344 (commit) via 4aceebf36f103eb380e21d12a1f08b7d6ea7cc8e (commit) from 160862978628b07ed5150ec2c8abad6af1656bc3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9b6c91469a804c60289a2ed21334dfd856c294bb Author: Werner Koch Date: Wed Jan 13 14:48:02 2016 +0100 gpg: Improve error code from lock_all. * g10/keydb.c (lock_all): Do not clobber RC during failur cleanup. Signed-off-by: Werner Koch diff --git a/g10/keydb.c b/g10/keydb.c index 3ee9dfd..cf7b990 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1003,7 +1003,7 @@ lock_all (KEYDB_HANDLE hd) keyring_lock (hd->active[i].u.kr, 0); break; case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_lock (hd->active[i].u.kb, 0); + keybox_lock (hd->active[i].u.kb, 0); break; } } commit 8f1368d5e3f7654ad9cb100053535f728dff2344 Author: Werner Koch Date: Wed Jan 13 14:47:06 2016 +0100 kbx: Improve and fix keybox_lock. * kbx/keybox-init.c (keybox_lock): Make sure ERR is initialized. Get error codes from dotlock functions. Signed-off-by: Werner Koch diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index cfee7b8..01d29f0 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -266,10 +266,10 @@ _keybox_close_file (KEYBOX_HANDLE hd) gpg_error_t keybox_lock (KEYBOX_HANDLE hd, int yes) { - gpg_error_t err; + gpg_error_t err = 0; KB_NAME kb = hd->kb; - if (!keybox_is_writable ((void*)kb)) + if (!keybox_is_writable (kb)) return 0; /* Make sure the lock handle has been created. */ @@ -278,9 +278,9 @@ keybox_lock (KEYBOX_HANDLE hd, int yes) kb->lockhd = dotlock_create (kb->fname, 0); if (!kb->lockhd) { - /* Unfortuntaley dotlock_create does not properly set ERRNO. */ + err = gpg_error_from_syserror (); log_info ("can't allocate lock for '%s'\n", kb->fname ); - return gpg_error (GPG_ERR_GENERAL); + return err; } } @@ -288,28 +288,26 @@ keybox_lock (KEYBOX_HANDLE hd, int yes) { if (kb->is_locked) ; - else if (!dotlock_take (kb->lockhd, -1)) - kb->is_locked = 1; - else + else if (dotlock_take (kb->lockhd, -1)) { - /* Unfortuntaley dotlock_take does not properly set ERRNO. */ + err = gpg_error_from_syserror (); log_info ("can't lock '%s'\n", kb->fname ); - err = gpg_error (GPG_ERR_GENERAL); } + else + kb->is_locked = 1; } else /* Release the lock. */ { if (!kb->is_locked) ; - else if (!dotlock_release (kb->lockhd)) - kb->is_locked = 0; - else + else if (dotlock_release (kb->lockhd)) { - /* Unfortuntaley dotlock_release does not properly set ERRNO. */ + err = gpg_error_from_syserror (); log_info ("can't unlock '%s'\n", kb->fname ); - err = gpg_error (GPG_ERR_GENERAL); } - } + else + kb->is_locked = 0; + } return err; } commit 4aceebf36f103eb380e21d12a1f08b7d6ea7cc8e Author: Werner Koch Date: Wed Jan 13 14:42:12 2016 +0100 common: Make sure dotlock functions set a proper ERRNO. * common/dotlock.c (map_w32_to_errno): New. (read_lockfile): Return a proper ERRNO. (dotlock_create_unix): Do not let log functions clobber ERRNO. (dotlock_take_unix): Ditto. (dotlock_release_unix): Ditto. (dotlock_create_w32): Set proper ERRNO. (dotlock_take_w32): Ditto. (dotlock_release_w32): Ditto. Signed-off-by: Werner Koch diff --git a/common/dotlock.c b/common/dotlock.c index d880859..26005bf 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -412,7 +412,8 @@ struct dotlock_handle /* A list of of all lock handles. The volatile attribute might help - if used in an atexit handler. */ + if used in an atexit handler. Note that [UN]LOCK_all_lockfiles + must not change ERRNO. */ static volatile dotlock_t all_lockfiles; #ifdef DOTLOCK_USE_PTHREAD static pthread_mutex_t all_lockfiles_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -434,6 +435,41 @@ static int never_lock; + +#ifdef HAVE_DOSISH_SYSTEM +static int +map_w32_to_errno (DWORD w32_err) +{ + switch (w32_err) + { + case 0: + return 0; + + case ERROR_FILE_NOT_FOUND: + return ENOENT; + + case ERROR_PATH_NOT_FOUND: + return ENOENT; + + case ERROR_ACCESS_DENIED: + return EPERM; + + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_BLOCK: + return EINVAL; + + case ERROR_NOT_ENOUGH_MEMORY: + return ENOMEM; + + case ERROR_NO_DATA: + case ERROR_BROKEN_PIPE: + return EPIPE; + + default: + return EIO; + } +} +#endif /*HAVE_DOSISH_SYSTEM*/ /* Entirely disable all locking. This function should be called @@ -514,11 +550,12 @@ read_lockfile (dotlock_t h, int *same_node ) continue; if (res < 0) { + int e = errno; my_info_1 ("error reading lockfile '%s'\n", h->lockname ); close (fd); if (buffer != buffer_space) xfree (buffer); - my_set_errno (0); /* Do not return an inappropriate ERRNO. */ + my_set_errno (e); return -1; } p += res; @@ -532,7 +569,7 @@ read_lockfile (dotlock_t h, int *same_node ) my_info_1 ("invalid size of lockfile '%s'\n", h->lockname); if (buffer != buffer_space) xfree (buffer); - my_set_errno (0); /* Better don't return an inappropriate ERRNO. */ + my_set_errno (EINVAL); return -1; } @@ -543,7 +580,7 @@ read_lockfile (dotlock_t h, int *same_node ) my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname); if (buffer != buffer_space) xfree (buffer); - my_set_errno (0); + my_set_errno (EINVAL); return -1; } @@ -664,12 +701,14 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) if ( fd == -1 ) { + int saveerrno = errno; all_lockfiles = h->next; UNLOCK_all_lockfiles (); my_error_2 (_("failed to create temporary file '%s': %s\n"), - h->tname, strerror(errno)); + h->tname, strerror (errno)); xfree (h->tname); xfree (h); + my_set_errno (saveerrno); return NULL; } if ( write (fd, pidstr, 11 ) != 11 ) @@ -696,19 +735,25 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) h->use_o_excl = 1; break; default: - my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n", - h->tname, strerror(errno)); + { + int saveerrno = errno; + my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n" + , h->tname, strerror (saveerrno)); + my_set_errno (saveerrno); + } goto write_failed; } h->lockname = xtrymalloc (strlen (file_to_lock) + 6 ); if (!h->lockname) { + int saveerrno = errno; all_lockfiles = h->next; UNLOCK_all_lockfiles (); unlink (h->tname); xfree (h->tname); xfree (h); + my_set_errno (saveerrno); return NULL; } strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock"); @@ -719,14 +764,18 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) return h; write_failed: - all_lockfiles = h->next; - UNLOCK_all_lockfiles (); - my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno)); - if ( fd != -1 ) - close (fd); - unlink (h->tname); - xfree (h->tname); - xfree (h); + { + int saveerrno = errno; + all_lockfiles = h->next; + UNLOCK_all_lockfiles (); + my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno)); + if ( fd != -1 ) + close (fd); + unlink (h->tname); + xfree (h->tname); + xfree (h); + my_set_errno (saveerrno); + } return NULL; } #endif /*HAVE_POSIX_SYSTEM*/ @@ -784,11 +833,13 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock) } if (h->lockhd == INVALID_HANDLE_VALUE) { + int saveerrno = map_w32_to_errno (GetLastError ()); all_lockfiles = h->next; UNLOCK_all_lockfiles (); my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1)); xfree (h->lockname); xfree (h); + my_set_errno (saveerrno); return NULL; } return h; @@ -911,7 +962,7 @@ dotlock_destroy_w32 (dotlock_t h) #endif /*HAVE_DOSISH_SYSTEM*/ -/* Destroy the locck handle H and release the lock. */ +/* Destroy the lock handle H and release the lock. */ void dotlock_destroy (dotlock_t h) { @@ -962,6 +1013,7 @@ dotlock_take_unix (dotlock_t h, long timeout) int ownerchanged; const char *maybe_dead=""; int same_node; + int saveerrno; again: if (h->use_o_excl) @@ -981,8 +1033,10 @@ dotlock_take_unix (dotlock_t h, long timeout) ; /* Lock held by another process. */ else if (fd == -1) { + saveerrno = errno; my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n", - h->lockname, strerror (errno)); + h->lockname, strerror (saveerrno)); + my_set_errno (saveerrno); return -1; } else @@ -1000,10 +1054,12 @@ dotlock_take_unix (dotlock_t h, long timeout) return 0; } /* Write error. */ + saveerrno = errno; my_error_2 ("lock not made: writing to '%s' failed: %s\n", h->lockname, strerror (errno)); close (fd); unlink (h->lockname); + my_set_errno (saveerrno); return -1; } } @@ -1016,11 +1072,13 @@ dotlock_take_unix (dotlock_t h, long timeout) if (stat (h->tname, &sb)) { + saveerrno = errno; my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n", strerror (errno)); /* In theory this might be a severe error: It is possible that link succeeded but stat failed due to changed permissions. We can't do anything about it, though. */ + my_set_errno (saveerrno); return -1; } @@ -1036,7 +1094,9 @@ dotlock_take_unix (dotlock_t h, long timeout) { if ( errno != ENOENT ) { + saveerrno = errno; my_info_0 ("cannot read lockfile\n"); + my_set_errno (saveerrno); return -1; } my_info_0 ("lockfile disappeared\n"); @@ -1131,6 +1191,7 @@ dotlock_take_w32 (dotlock_t h, long timeout) { my_error_2 (_("lock '%s' not made: %s\n"), h->lockname, w32_strerror (w32err)); + my_set_errno (map_w32_to_errno (w32err)); return -1; } @@ -1161,6 +1222,7 @@ dotlock_take_w32 (dotlock_t h, long timeout) goto again; } + my_set_errno (EACCES); return -1; } #endif /*HAVE_DOSISH_SYSTEM*/ @@ -1200,23 +1262,29 @@ static int dotlock_release_unix (dotlock_t h) { int pid, same_node; + int saveerrno; pid = read_lockfile (h, &same_node); if ( pid == -1 ) { + saveerrno = errno; my_error_0 ("release_dotlock: lockfile error\n"); + my_set_errno (saveerrno); return -1; } if ( pid != getpid() || !same_node ) { my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid); + my_set_errno (EACCES); return -1; } if ( unlink( h->lockname ) ) { + saveerrno = errno; my_error_1 ("release_dotlock: error removing lockfile '%s'\n", h->lockname); + my_set_errno (saveerrno); return -1; } /* Fixme: As an extra check we could check whether the link count is @@ -1236,8 +1304,10 @@ dotlock_release_w32 (dotlock_t h) memset (&ovl, 0, sizeof ovl); if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl)) { + int saveerrno = map_w32_to_errno (GetLastError ()); my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n", h->lockname, w32_strerror (-1)); + my_set_errno (saveerrno); return -1; } ----------------------------------------------------------------------- Summary of changes: common/dotlock.c | 104 +++++++++++++++++++++++++++++++++++++++++++++--------- g10/keydb.c | 2 +- kbx/keybox-init.c | 28 +++++++-------- 3 files changed, 101 insertions(+), 33 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 13 17:56:58 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 13 Jan 2016 17:56:58 +0100 Subject: [git] GnuPG - branch, justus/scm-1, updated. gnupg-2.1.10-122-gb7b74cd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, justus/scm-1 has been updated via b7b74cd0bb0df9ddb3e15df0b61d4a5011e8b931 (commit) from ec94a8fa1c9763ec7254b528dddc76ec55de0e55 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b7b74cd0bb0df9ddb3e15df0b61d4a5011e8b931 Author: Justus Winter Date: Wed Jan 13 17:56:26 2016 +0100 tests/gpgscm: add missing file Signed-off-by: Justus Winter diff --git a/tests/gpgscm/private.h b/tests/gpgscm/private.h new file mode 100644 index 0000000..efa0cb0 --- /dev/null +++ b/tests/gpgscm/private.h @@ -0,0 +1,26 @@ +/* TinyScheme-based test driver. + * + * 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 . + */ + +#ifndef __GPGSCM_PRIVATE_H__ +#define __GPGSCM_PRIVATE_H__ + +extern int verbose; + +#endif /* __GPGSCM_PRIVATE_H__ */ ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/{ffi.h => private.h} | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) copy tests/gpgscm/{ffi.h => private.h} (79%) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 13 21:27:21 2016 From: cvs at cvs.gnupg.org (by Marek Vasut) Date: Wed, 13 Jan 2016 21:27:21 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.21-3-g7137006 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 71370060aae7a83f4d6c3b9c924f204a57cc2538 (commit) from 1814a9bdc15f00bcf6b13ad16857a4f4922fa1d7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 71370060aae7a83f4d6c3b9c924f204a57cc2538 Author: Marek Vasut Date: Wed Jan 13 18:12:58 2016 +0100 Add new lock-obj-pub for NIOS2. src/syscfg/lock-obj-pub.nios2-unknown-linux-gnu.h: New. diff --git a/src/Makefile.am b/src/Makefile.am index e4fe305..8aca7df 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,6 +56,7 @@ lock_obj_pub = \ syscfg/lock-obj-pub.mips-unknown-linux-gnu.h \ syscfg/lock-obj-pub.mips64el-unknown-linux-gnuabi64.h \ syscfg/lock-obj-pub.mipsel-unknown-linux-gnu.h \ + syscfg/lock-obj-pub.nios2-unknown-linux-gnu.h \ syscfg/lock-obj-pub.or1k-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc-unknown-linux-gnu.h \ syscfg/lock-obj-pub.powerpc64-unknown-linux-gnu.h \ diff --git a/src/syscfg/lock-obj-pub.nios2-unknown-linux-gnu.h b/src/syscfg/lock-obj-pub.nios2-unknown-linux-gnu.h new file mode 100644 index 0000000..dbd46da --- /dev/null +++ b/src/syscfg/lock-obj-pub.nios2-unknown-linux-gnu.h @@ -0,0 +1,23 @@ +## lock-obj-pub.nios2-unknown-linux-gnu.h +## File created by gen-posix-lock-obj - DO NOT EDIT +## To be included by mkheader into gpg-error.h + +typedef struct +{ + long _vers; + union { + volatile char _priv[24]; + long _x_align; + long *_xp_align; + } u; +} gpgrt_lock_t; + +#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0}}} +## +## Local Variables: +## mode: c +## buffer-read-only: t +## End: +## ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 1 + ....m68k-unknown-linux-gnu.h => lock-obj-pub.nios2-unknown-linux-gnu.h} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) copy src/syscfg/{lock-obj-pub.m68k-unknown-linux-gnu.h => lock-obj-pub.nios2-unknown-linux-gnu.h} (91%) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 14 11:06:31 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 14 Jan 2016 11:06:31 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-116-g99cdc15 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 99cdc15cf103cace11aa6eec9e13a3a8ecf13004 (commit) via c7ca0f73dbe7c080b79f93f90f00ba2396fc4bd0 (commit) from 9b6c91469a804c60289a2ed21334dfd856c294bb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 99cdc15cf103cace11aa6eec9e13a3a8ecf13004 Author: Werner Koch Date: Thu Jan 14 11:01:14 2016 +0100 doc: Update whats-new-in-2.1 from gnupg-doc. -- diff --git a/doc/whats-new-in-2.1.txt b/doc/whats-new-in-2.1.txt index d20239f..6c46b04 100644 --- a/doc/whats-new-in-2.1.txt +++ b/doc/whats-new-in-2.1.txt @@ -6,7 +6,7 @@ ??????????????????????????? - 2014-11-04 + 2016-01-14 Table of Contents @@ -28,8 +28,9 @@ Table of Contents .. 1.13 Improved card support .. 1.14 New format for key listings .. 1.15 Support for Putty -.. 1.16 Improved X.509 certificate creation -.. 1.17 Scripts to create a Windows installer +.. 1.16 Export of SSH public keys +.. 1.17 Improved X.509 certificate creation +.. 1.18 Scripts to create a Windows installer A possibly revised version of this article can be found at: @@ -91,6 +92,8 @@ https://gnupg.org/faq/whats-new-in-2.1.html possible to export them directly in PKCS#8 and PEM format for use on TLS servers. + ? Export of /ssh/ keys has been integrated. + ? The scripts to create a Windows installer are now part of GnuPG. Now for the detailed description of these new features: @@ -172,7 +175,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html This is best shown with an example: - ????? + ????? ? $ gpg2 --gen-key ? gpg (GnuPG) 2.1.0; Copyright (C) 2014 Free Software Foundation, Inc. ? This is free software: you are free to change and redistribute it. @@ -194,7 +197,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html ? Key fingerprint = 0290 5ABF 17C7 81FB C390 9B00 636A 1BBD 68FD 0088 ? uid [ultimate] Glenn Greenwald ? sub rsa2048/84439DCD 2014-11-03 - ????? + ????? Thus only the name and the mail address are required. For all other parameters the default values are used. Many graphical frontends @@ -212,10 +215,10 @@ https://gnupg.org/faq/whats-new-in-2.1.html options to create an ECC key. For those who want to experiment with ECC or already want to prepare a - key for future use, the command `--gen-full-key' along with the option + key for future use, the command `--full-gen-key' along with the option `--expert' is the enabler: - ????? + ????? ? $ gpg2 --expert --full-gen-key ? gpg (GnuPG) 2.1.0; Copyright (C) 2014 Free Software Foundation, Inc. ? This is free software: you are free to change and redistribute it. @@ -264,7 +267,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html ? Key fingerprint = E630 27CF 3D68 22A7 6FF2 093E D179 9E72 3826 60E3 ? uid [ultimate] Edward Snowden ? sub nistp256/48C9A997 2014-11-03 nistp256 - ????? + ????? In this example we created a primary ECC key for signing and an subkey for encryption. For both we use the NIST P-256 curve. The key may @@ -284,7 +287,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html releases. Recall that an encryption subkey can be added to a key at any time. If you want to create a signing key you may do it this way: - ????? + ????? ? $ gpg2 --expert --full-gen-key ? gpg (GnuPG) 2.1.0; Copyright (C) 2014 Free Software Foundation, Inc. ? This is free software: you are free to change and redistribute it. @@ -335,7 +338,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html ? pub ed25519/5C1AFC2A 2014-11-03 ? Key fingerprint = ED85 4D98 5D8F 502F C6C5 FFB2 AA81 319E 5C1A FC2A ? uid [ultimate] Laura Poitras - ????? + ????? Support for ECC keys is available only on some keyservers but it is expected that this will be fixed over the next few months. @@ -355,17 +358,17 @@ https://gnupg.org/faq/whats-new-in-2.1.html parameter file or interactive prompts for generating a key or to sign a key. This can now be accomplished with a few new commands: - ????? + ????? ? $ gpg2 --batch --quick-gen-key 'Daniel Ellsberg ' ? gpg: key 911B90A9 marked as ultimately trusted - ????? + ????? If a key with that user id already exists, gpg bails out with an error message. You can force creation using the option `--yes'. If you want some more control, you may not use `--batch' and gpg will ask for confirmation and show the resulting key: - ????? + ????? ? $ gpg2 --quick-gen-key 'Daniel Ellsberg ' ? About to create a key for: ? "Daniel Ellsberg " @@ -379,13 +382,13 @@ https://gnupg.org/faq/whats-new-in-2.1.html ? Key fingerprint = 15CB 723E 2000 A1A8 2505 F3B7 CC00 B501 BD19 AC1C ? uid [ultimate] Daniel Ellsberg ? sub rsa2048/72A4D018 2014-11-04 - ????? + ????? Another common operation is to sign a key. /gpg/ can do this directly from the command line by giving the fingerprint of the to-be-signed key: - ????? + ????? ? $ gpg2 --quick-sign-key '15CB 723E 2000 A1A8 2505 F3B7 CC00 B501 BD19 AC1C' ? ? pub rsa2048/BD19AC1C @@ -394,13 +397,13 @@ https://gnupg.org/faq/whats-new-in-2.1.html ? Primary key fingerprint: 15CB 723E 2000 A1A8 2505 F3B7 CC00 B501 BD19 AC1C ? ? Daniel Ellsberg - ????? + ????? In case the key has already been signed, the command prints a note and exits with success. In case you want to check that it really worked, use `=--check-sigs' as usual: - ????? + ????? ? $ gpg2 --check-sigs '15CB 723E 2000 A1A8 2505 F3B7 CC00 B501 BD19 AC1C' ? gpg: checking the trustdb ? gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model @@ -411,7 +414,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html ? sig! 68FD0088 2014-11-04 Glenn Greenwald ? sub rsa2048/72A4D018 2014-11-04 ? sig! BD19AC1C 2014-11-04 Daniel Ellsberg - ????? + ????? The fingerprint may also be given without the spaces in which case @@ -420,6 +423,20 @@ https://gnupg.org/faq/whats-new-in-2.1.html To create a non-exportable key signature, use the command `--quick-lsign-key' instead. + Since version 2.1.4 it possible to directly add another user id to an + existing key: + + ????? + ? $ gpg2 -k 8CFDE12197965A9A + ? pub ed25519/8CFDE12197965A9A 2014-08-19 + ? uid [ unknown] EdDSA sample key 1 + ? $ gpg2 --quick-adduid 8CFDE12197965A9A 'Sample 2 ' + ? $ gpg2 -k 8CFDE12197965A9A + ? pub ed25519/8CFDE12197965A9A 2014-08-19 + ? uid [ unknown] Sample 2 + ? uid [ unknown] EdDSA sample key 1 + ????? + 1.6 Improved Pinentry support ????????????????????????????? @@ -531,10 +548,10 @@ https://gnupg.org/faq/whats-new-in-2.1.html dead so that it won?t be used in future. To interact with the /dirmngr/ the `gpg-connect-agent' tool is used: - ????? + ????? ? $ gpg-connect-agent --dirmngr 'help keyserver' /bye ? $ gpg-connect-agent --dirmngr 'keyserver --hosttable' /bye - ????? + ????? The first command prints a help screen for the keyserver command and the second command prints the current host table. @@ -571,16 +588,23 @@ https://gnupg.org/faq/whats-new-in-2.1.html keybox file. To convert an existing `pubring.gpg' file to the keybox format, you - first rename the file to (for example) `publickeys' so it won?t be - recognized by any GnuPG version and then you run the command - - ????? - ? $ gpg2 --import publickeys - ????? + first backup the ownertrust values, then rename the file to (for + example) `publickeys', so it won?t be recognized by any GnuPG version, + then run import, and finally restore the ownertrust values: + + ????? + ? $ cd ~/.gnupg + ? $ gpg --export-ownertrust >otrust.lst + ? $ mv pubring.gpg publickeys + ? $ gpg2 --import-options import-local-sigs --import publickeys + ? $ gpg2 --import-ownertrust otrust.lst + ????? You may then rename the `publickeys' file back so that it can be used by older GnuPG versions. Remember that in this case you have two - independent copies of the public keys. + independent copies of the public keys. The ownertrust values are kept + by all gpg versions in the file `trustdb.gpg' but the above + precautions need to be taken to keep them over an import. 1.12 Auto-generated revocation certificates @@ -597,14 +621,17 @@ https://gnupg.org/faq/whats-new-in-2.1.html ?????????????????????????? The /scdaemon/, which is responsible for accessing smardcards and - other tokens, has received may updates. In particular plugable USB + other tokens, has received many updates. In particular plugable USB readers with a fixed card now work smoothless and similar to standard - readers. The latest features of the /gnuk/ token are supported. Code - for the HSM smartcard has been added. More card readers with a PIN + readers. The latest features of the [gnuk] token are supported. Code + for the SmartCard-HSM has been added. More card readers with a PIN pad are supported. The internal CCID driver does now also work with certain non-auto configuration equipped readers. + [gnuk] http://www.fsij.org/doc-gnuk/ + + 1.14 New format for key listings ???????????????????????????????? @@ -616,11 +643,11 @@ https://gnupg.org/faq/whats-new-in-2.1.html either use the algorithm name with appended key length or use the name of the curve: - ????? + ????? ? pub 2048D/1E42B367 2007-12-31 [expires: 2018-12-31] ? pub dsa2048/1E42B367 2007-12-31 [expires: 2018-12-31] ? pub ed25519/0AA914C9 2014-10-18 - ????? + ????? The first two lines show the same key in the old format and in the new format. The third line shows an example of an ECC key using the @@ -653,7 +680,18 @@ https://gnupg.org/faq/whats-new-in-2.1.html [Putty] http://www.chiark.greenend.org.uk/~sgtatham/putty/ -1.16 Improved X.509 certificate creation +1.16 Export of SSH public keys +?????????????????????????????? + + The new command `--export-ssh-key' makes it easy to export an /ssh/ + public key in the format used for ssh?s `authorized_keys' file. By + default the command exports the newest subkey with an authorization + usage flags. A special syntax can be used to export other subkeys. + This command is available since 2.1.11 and replaces the former debug + utility /gpgkey2ssh/. + + +1.17 Improved X.509 certificate creation ???????????????????????????????????????? In addition to an improved certificate signing request menu, it is now @@ -673,7 +711,7 @@ https://gnupg.org/faq/whats-new-in-2.1.html and directly exported in a format suitable for OpenSSL based servers. -1.17 Scripts to create a Windows installer +1.18 Scripts to create a Windows installer ?????????????????????????????????????????? GnuPG now comes with the /speedo/ build system which may be used to @@ -686,9 +724,9 @@ https://gnupg.org/faq/whats-new-in-2.1.html and GpgEX as a Windows Explorer extension. GnuPG needs to be unpacked and from the top source directory you run this command - ????? + ????? ? make -f build-aux/speedo.mk w32-installer - ????? + ????? This command downloads all direct dependencies, checks the signatures using the GnuPG version from the build system (all Linux distros @@ -696,12 +734,15 @@ https://gnupg.org/faq/whats-new-in-2.1.html uses NSIS to create the installer. Although this sounds easy, some experience in setting up a development machine is still required. Some versions of the toolchain exhibit bugs and thus your mileage may - vary. Support for keyserver access over TLS is currently not - available but will be added with one of the next point releases. + vary. See the [Wiki] for more info. + + Support for keyserver access over TLS is currently not available but + will be added with one of the next point releases. + [Wiki] https://wiki.gnupg.org/Build2.1_Windows - # Copyright 2014 The GnuPG Project. + # Copyright 2014--2016 The GnuPG Project. # This work is licensed under the Creative Commons # Attribution-ShareAlike 4.0 International License. To view a copy of # this license, visit http://creativecommons.org/licenses/by-sa/4.0/ commit c7ca0f73dbe7c080b79f93f90f00ba2396fc4bd0 Author: Werner Koch Date: Wed Jan 13 15:08:42 2016 +0100 kbx: Change return type of search functions to gpg_error_t. * kbx/keybox-search.c (keybox_search_reset): Change return type to gpg_error_t. (keybox_search): Ditto. Also handle GPG_ERR_EOF. * sm/keydb.c (keydb_search_reset): Ditto. Signed-off-by: Werner Koch diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 1edb4ae..681d5c0 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -732,7 +732,7 @@ release_sn_array (struct sn_array_s *array, size_t size) */ -int +gpg_error_t keybox_search_reset (KEYBOX_HANDLE hd) { if (!hd) @@ -760,12 +760,12 @@ keybox_search_reset (KEYBOX_HANDLE hd) If WANT_BLOBTYPE is not 0 only blobs of this type are considered. The value at R_SKIPPED is updated by the number of skipped long records (counts PGP and X.509). */ -int +gpg_error_t keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, keybox_blobtype_t want_blobtype, size_t *r_descindex, unsigned long *r_skipped) { - int rc; + gpg_error_t rc; size_t n; int need_words, any_skip; KEYBOXBLOB blob = NULL; @@ -1021,7 +1021,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, hd->found.pk_no = pk_no; hd->found.uid_no = uid_no; } - else if (rc == -1) + else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) { _keybox_release_blob (blob); hd->eof = 1; diff --git a/kbx/keybox.h b/kbx/keybox.h index 9f91c53..3c60971 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -91,10 +91,11 @@ int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); #endif /*KEYBOX_WITH_X509*/ int keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value); -int keybox_search_reset (KEYBOX_HANDLE hd); -int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc, - keybox_blobtype_t want_blobtype, - size_t *r_descindex, unsigned long *r_skipped); +gpg_error_t keybox_search_reset (KEYBOX_HANDLE hd); +gpg_error_t keybox_search (KEYBOX_HANDLE hd, + KEYBOX_SEARCH_DESC *desc, size_t ndesc, + keybox_blobtype_t want_blobtype, + size_t *r_descindex, unsigned long *r_skipped); off_t keybox_offset (KEYBOX_HANDLE hd); gpg_error_t keybox_seek (KEYBOX_HANDLE hd, off_t offset); diff --git a/sm/keydb.c b/sm/keydb.c index 0ef3c8f..f5705cb 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -928,10 +928,11 @@ keydb_rebuild_caches (void) /* * Start the next search on this handle right at the beginning */ -int +gpg_error_t keydb_search_reset (KEYDB_HANDLE hd) { - int i, rc = 0; + int i; + gpg_error_t rc = 0; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -950,8 +951,7 @@ keydb_search_reset (KEYDB_HANDLE hd) break; } } - return rc; /* fixme: we need to map error codes or share them with - all modules*/ + return rc; } /* @@ -980,8 +980,10 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) NULL, &skipped); break; } - if (rc == -1) /* EOF -> switch to next resource */ - hd->current++; + if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) + { /* EOF -> switch to next resource */ + hd->current++; + } else if (!rc) hd->found = hd->current; } diff --git a/sm/keydb.h b/sm/keydb.h index 03de1c6..3c0f2d6 100644 --- a/sm/keydb.h +++ b/sm/keydb.h @@ -54,7 +54,7 @@ int keydb_delete (KEYDB_HANDLE hd, int unlock); int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); void keydb_rebuild_caches (void); -int keydb_search_reset (KEYDB_HANDLE hd); +gpg_error_t keydb_search_reset (KEYDB_HANDLE hd); int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); int keydb_search_first (KEYDB_HANDLE hd); int keydb_search_next (KEYDB_HANDLE hd); ----------------------------------------------------------------------- Summary of changes: doc/whats-new-in-2.1.txt | 119 +++++++++++++++++++++++++++++++---------------- kbx/keybox-search.c | 8 ++-- kbx/keybox.h | 9 ++-- sm/keydb.c | 14 +++--- sm/keydb.h | 2 +- 5 files changed, 98 insertions(+), 54 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 14 11:07:43 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 14 Jan 2016 11:07:43 +0100 Subject: [git] gnupg-doc - branch, master, updated. e5c4f51a719b92c0d96744b1fc24531034dc6f89 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via e5c4f51a719b92c0d96744b1fc24531034dc6f89 (commit) from a08b117d893915c75e7bc0c925cbab6ce64947e1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e5c4f51a719b92c0d96744b1fc24531034dc6f89 Author: Werner Koch Date: Thu Jan 14 10:58:12 2016 +0100 faq: Add --export-ssh-key and fix one example. GnuPG-bug-id: 2214 diff --git a/web/faq/whats-new-in-2.1.org b/web/faq/whats-new-in-2.1.org index 9290b2f..410c88b 100644 --- a/web/faq/whats-new-in-2.1.org +++ b/web/faq/whats-new-in-2.1.org @@ -1,7 +1,7 @@ #+TITLE: GnuPG - What?s new in 2.1 #+STARTUP: showall indent #+SETUPFILE: "share/setup.inc" -#+DATE: 2014-11-04 +#+DATE: 2016-01-14 #+macro: more @@html: ⇒@@ #+BEGIN_ASCII @@ -70,6 +70,8 @@ its main components. possible to export them directly in PKCS#8 and PEM format for use on TLS servers.{{{more(x509)}}} +- Export of /ssh/ keys has been integrated.{{{more(sshexport)}}} + - The scripts to create a Windows installer are now part of GnuPG.{{{more(w32inst)}}} @@ -193,7 +195,7 @@ is still very limited. Thus GnuPG 2.1 currently hides the options to create an ECC key. For those who want to experiment with ECC or already want to prepare a -key for future use, the command =--gen-full-key= along with the option +key for future use, the command =--full-gen-key= along with the option =--expert= is the enabler: #+begin_example @@ -656,6 +658,18 @@ act as a replacement for [[http://www.chiark.greenend.org.uk/~sgtatham/putty/][P is the Windows counterpart for the =--enable-ssh-support= option as used on Unix. +** Export of SSH public keys +:PROPERTIES: +:CUSTOM_ID: sshexport +:END: + +The new command =--export-ssh-key= makes it easy to export an /ssh/ +public key in the format used for ssh?s =authorized_keys= file. By +default the command exports the newest subkey with an authorization +usage flags. A special syntax can be used to export other subkeys. +This command is available since 2.1.11 and replaces the former debug +utility /gpgkey2ssh/. + ** Improved X.509 certificate creation :PROPERTIES: :CUSTOM_ID: x509 @@ -710,7 +724,7 @@ will be added with one of the next point releases. #+BEGIN_ASCII -# Copyright 2014 The GnuPG Project. +# Copyright 2014--2016 The GnuPG Project. # This work is licensed under the Creative Commons # Attribution-ShareAlike 4.0 International License. To view a copy of # this license, visit http://creativecommons.org/licenses/by-sa/4.0/ ----------------------------------------------------------------------- Summary of changes: web/faq/whats-new-in-2.1.org | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 14 12:31:15 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 14 Jan 2016 12:31:15 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-117-g360534b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 360534bde770f4845669de223154216d249b954b (commit) from 99cdc15cf103cace11aa6eec9e13a3a8ecf13004 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 360534bde770f4845669de223154216d249b954b Author: Werner Koch Date: Thu Jan 14 12:22:33 2016 +0100 gpg: Make --list-options show-usage the default. * g10/gpg.c (main): Add LIST_SHOW_USAGE. -- The usage flags are often useful and they don't take away much space in a key listing. Thus it is better to have them enabled by default. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 5510d57..4a70856 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -407,9 +407,7 @@ output can directly be added to ssh's @file{authorized_key} file. By specifying the key to export using a key ID or a fingerprint suffixed with an exclamation mark (!), a specific subkey or the primary key can be exported. This does not even require that the key -has the authentication capability flag set. To view the capability -flags of a key use @code{--list-options show-usage} along with a key -listing command. +has the authentication capability flag set. @item --import @itemx --fast-import @@ -1098,7 +1096,7 @@ give the opposite meaning. The options are: Show usage information for keys and subkeys in the standard key listing. This is a list of letters indicating the allowed usage for a key (@code{E}=encryption, @code{S}=signing, @code{C}=certification, - @code{A}=authentication). Defaults to no. + @code{A}=authentication). Defaults to yes. @item show-policy-urls @opindex list-options:show-policy-urls diff --git a/g10/gpg.c b/g10/gpg.c index 4287bda..3532550 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2226,7 +2226,8 @@ main (int argc, char **argv) | VERIFY_SHOW_POLICY_URLS | VERIFY_SHOW_STD_NOTATIONS | VERIFY_SHOW_KEYSERVER_URLS); - opt.list_options = LIST_SHOW_UID_VALIDITY; + opt.list_options = (LIST_SHOW_UID_VALIDITY + | LIST_SHOW_USAGE); #ifdef NO_TRUST_MODELS opt.trust_model = TM_ALWAYS; #else ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 6 ++---- g10/gpg.c | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 14 18:37:13 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Thu, 14 Jan 2016 18:37:13 +0100 Subject: [git] GnuPG - branch, justus/scm-2, created. gnupg-2.1.10-124-gb4ac83f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, justus/scm-2 has been created at b4ac83f6f3352194d54938d5b48c02a7ef97d289 (commit) - Log ----------------------------------------------------------------- commit b4ac83f6f3352194d54938d5b48c02a7ef97d289 Author: Justus Winter Date: Thu Jan 7 17:01:45 2016 +0100 tests/openpgp: Reimplement tests in Scheme. * tests/openpgp/Makefile.am (required_pgms): Add gpgscm. (TESTS_ENVIRONMENT): Make sure gpgscm and the libraries are found. (TESTS): Replace tests with the new Scheme implementations. * tests/openpgp/4gb-packet.scm: New file. * tests/openpgp/clearsig.scm: Likewise. * tests/openpgp/decrypt.scm: Likewise. * tests/openpgp/defs.scm: Likewise. * tests/openpgp/encrypt.scm: Likewise. * tests/openpgp/encryptp.scm: Likewise. * tests/openpgp/mds.scm: Likewise. * tests/openpgp/seat.scm: Likewise. * tests/openpgp/sigs.scm: Likewise. * tests/openpgp/version.scm: Likewise. Signed-off-by: Justus Winter diff --git a/tests/openpgp/4gb-packet.scm b/tests/openpgp/4gb-packet.scm new file mode 100755 index 0000000..09a171e --- /dev/null +++ b/tests/openpgp/4gb-packet.scm @@ -0,0 +1,10 @@ +#!/usr/bin/env gpgscm + +;; GnuPG through 2.1.7 would incorrect mark packets whose size is +;; 2^32-1 as invalid and exit with status code 2. + +(load (in-srcdir "defs.scm")) + +(if (= 0 (call `(,GPG --list-packets ,(in-srcdir "4gb-packet.asc")))) + (info "Can parse 4GB packets.") + (error "Failed to parse 4GB packet.")) diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index bab724b..433cfde 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -22,9 +22,11 @@ # Programs required before we can run these tests. required_pgms = ../../g10/gpg2$(EXEEXT) ../../agent/gpg-agent$(EXEEXT) \ ../../tools/gpg-connect-agent$(EXEEXT) \ - ../../tools/mk-tdata$(EXEEXT) + ../../tools/mk-tdata$(EXEEXT) \ + ../gpgscm/gpgscm$(EXEEXT) -TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO= LC_ALL=C +TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO= LC_ALL=C \ + PATH=../gpgscm:$(PATH) GPGSCM_BASE=$(top_srcdir)/tests/gpgscm if SQLITE3 sqlite3_dependent_tests = tofu.test @@ -34,18 +36,23 @@ endif # Note: version.test needs to be the first test to run and finish.test # the last one -TESTS = version.test mds.test \ - decrypt.test decrypt-dsa.test \ - sigs.test sigs-dsa.test \ - encrypt.test encrypt-dsa.test \ - seat.test clearsig.test encryptp.test detach.test \ +TESTS = version.test \ + version.scm \ + mds.scm \ + decrypt.scm \ + sigs.scm \ + encrypt.scm \ + seat.scm \ + clearsig.scm \ + encryptp.scm \ + detach.test \ armsigs.test armencrypt.test armencryptp.test \ signencrypt.test signencrypt-dsa.test \ armsignencrypt.test armdetach.test \ armdetachm.test detachm.test genkey1024.test \ conventional.test conventional-mdc.test \ multisig.test verify.test armor.test \ - import.test ecc.test 4gb-packet.test \ + import.test ecc.test 4gb-packet.scm \ $(sqlite3_dependent_tests) \ gpgtar.test use-exact-key.test default-key.test \ finish.test diff --git a/tests/openpgp/clearsig.scm b/tests/openpgp/clearsig.scm new file mode 100755 index 0000000..1b4744f --- /dev/null +++ b/tests/openpgp/clearsig.scm @@ -0,0 +1,90 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(define (check-signing args input) + (lambda (source sink) + (lettmp (signed) + (call-popen `(,GPG --output ,signed --yes + , at args ,source) input) + (call-popen `(,GPG --output ,sink --yes ,signed) "")))) + +(for-each-p + "Test signing and verifying plain text messages" + (lambda (source) + ((if (equal? "plain-3" source) + ;; plain-3 does not end in a newline, and gpg will add one. + ;; Therefore, we merely check that the verification is ok. + check-execution + ;; Otherwise, we do check that we recover the original file. + check-identity) + source + (check-signing '(--passphrase-fd "0" --clearsign) usrpass1))) + (append plain-files '("plain-large"))) + +;; The test vectors are lists of length three, containing +;; - a string to be signed, +;; - a flag indicating whether we verify that the exact message is +;; reconstructed (whitespace at the end is normalized for plain text +;; messages), +;; - and a list of arguments to add to gpg when encoding +;; the string. + +(define :string car) +(define :check-equality cadr) +(define :options caddr) + +(define + vectors + '(;; one with long lines + ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyx + +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +" #t ()) + + ;; one with only one long line + ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyx +" #t ()) + + ;; and one with an empty body + ("" #f ()) + + ;; and one with one empty line at the end + ("line 1 +line 2 +line 3 +there is a blank line after this + +" #t ()) + + ;; I think this file will be constructed wrong (gpg 0.9.3) but it + ;; should verify okay anyway. + ("this is a sig test + " #f ()) + + ;; check our special diff mode + ("--- mainproc.c Tue Jun 27 09:28:11 2000 ++++ mainproc.c~ Thu Jun 8 22:50:25 2000 +@@ -1190,16 +1190,13 @@ + md_enable( c->mfx.md, n1->pkt->pkt.signature->digest_algo); + } + /* ask for file and hash it */ +- if( c->sigs_only ) { ++ if( c->sigs_only ) + rc = hash_datafiles( c->mfx.md, NULL, + c->signed_data, c->sigfilename, + n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 ); +" #t (--not-dash-escaped)))) + +(define counter (make-counter)) +(for-each-p' + "Test signing and verifying test vectors" + (lambda (vec) + (lettmp (tmp) + (with-output-to-file tmp (lambda () (display (:string vec)))) + ((if (:check-equality vec) check-identity check-execution) + tmp + (check-signing `(--passphrase-fd "0" --clearsign ,@(:options vec)) + usrpass1)))) + (lambda (vec) (number->string (counter))) + vectors) diff --git a/tests/openpgp/decrypt.scm b/tests/openpgp/decrypt.scm new file mode 100755 index 0000000..8312f49 --- /dev/null +++ b/tests/openpgp/decrypt.scm @@ -0,0 +1,21 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(define (decrypt source sink) + (call-popen `(,GPG --output ,sink --yes ,source) "")) + +(define (check-file plain-name cipher-name) + (lettmp (decrypted-name) + (decrypt cipher-name decrypted-name) + (if (not (file=? plain-name decrypted-name)) + (error "mismatch")))) + +(for-each-p "Checking decryption of supplied files" + (lambda (f) (check-file + f (in-srcdir (string-append f ".asc")))) + plain-files) +(for-each-p "Checking decryption of supplied DSA encrypted file" + (lambda (f) (check-file + f (in-srcdir (string-append f "-pgp.asc")))) + (list (car plain-files))) diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm new file mode 100644 index 0000000..1972f92 --- /dev/null +++ b/tests/openpgp/defs.scm @@ -0,0 +1,60 @@ +;; Common definitions for the OpenPGP 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 . + +;; +;; Constants. +;; + +(define usrname1 "one at example.com") +(define usrpass1 "def") +(define usrname2 "two at example.com") +(define usrpass2 "") +(define usrname3 "three at example.com") +(define usrpass3 "") + +(define dsa-usrname1 "pgp5") +;; we use the sub key because we do not yet have the logic to to derive +;; the first encryption key from a keyblock (I guess) (Well of course +;; we have this by now and the notation below will lookup the primary +;; first and then search for the encryption subkey.) +(define dsa-usrname2 "0xCB879DE9") + +(define plain-files '("plain-1" "plain-2" "plain-3")) +(define data-files '("data-500" "data-9000" "data-32000" "data-80000")) +(define exp-files '()) + +(define GPG "../../g10/gpg2") + +(define (get-config what) + (let* ((config-string + (call-popen `(,GPG --with-colons --list-config ,what) "")) + (config (string-splitn + (filter-whitespace config-string) #\: 2))) + (string-split (caddr config) #\;))) + +(define all-pubkey-algos (get-config "pubkeyname")) +(define all-hash-algos (get-config "digestname")) +(define all-cipher-algos (get-config "ciphername")) + +(define (have-pubkey-algo? x) + (not (null? (memq x all-pubkey-algos)))) +(define (have-hash-algo? x) + (not (null? (memq x all-hash-algos)))) +(define (have-cipher-algo? x) + (not (null? (memq x all-cipher-algos)))) diff --git a/tests/openpgp/encrypt.scm b/tests/openpgp/encrypt.scm new file mode 100755 index 0000000..016110f --- /dev/null +++ b/tests/openpgp/encrypt.scm @@ -0,0 +1,49 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(define (check-encrypt-decrypt args input) + (lambda (source sink) + (lettmp (encrypted) + (call-popen `(,GPG --output ,encrypted --yes --encrypt + --always-trust ;; XXX + , at args ,source) input) + (call-popen `(,GPG --output ,sink --yes ,encrypted) "")))) + +(for-each-p + "Test encryption" + (lambda (source) + (check-identity source (check-encrypt-decrypt + `(--recipient ,usrname2) ""))) + (append plain-files data-files)) + +(for-each-p + "Test encryption using a specific cipher algorithm" + (lambda (cipher) + (for-each-p + "" + (lambda (source) + (check-identity source + (check-encrypt-decrypt + `(--recipient ,usrname2 --cipher-algo ,cipher) ""))) + (append plain-files data-files))) + all-cipher-algos) + +(for-each-p + "Test encryption using DSA" + (lambda (source) + (check-identity source (check-encrypt-decrypt + `(--recipient ,dsa-usrname2) ""))) + (append plain-files data-files)) + +(for-each-p + "Test encryption using DSA and a specific cipher algorithm" + (lambda (cipher) + (for-each-p + "" + (lambda (source) + (check-identity source + (check-encrypt-decrypt + `(--recipient ,dsa-usrname2 --cipher-algo ,cipher) ""))) + (append plain-files data-files))) + all-cipher-algos) diff --git a/tests/openpgp/encryptp.scm b/tests/openpgp/encryptp.scm new file mode 100755 index 0000000..b6fcaf3 --- /dev/null +++ b/tests/openpgp/encryptp.scm @@ -0,0 +1,28 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(define :read-end car) +(define :write-end cadr) + +(define (gpg-pipe args errfd) + (lambda (source sink) + (let* ((p (pipe)) + (task0 (spawn-process-fd + `(,GPG --output - --yes , at args ,source) + -1 (:write-end p) errfd)) + (task1 (spawn-process-fd + `(,GPG --output ,sink --yes -) + (:read-end p) -1 errfd))) + (close (:read-end p)) + (close (:write-end p)) + (wait-processes (list GPG GPG) (list task0 task1) 1)))) + +(for-each-p + "Test encryption and decryption using pipes" + (lambda (source) + (check-identity source + (gpg-pipe `(--always-trust --encrypt + --recipient ,usrname2) + (if *verbose* STDERR_FILENO -1)))) + (append plain-files data-files)) diff --git a/tests/openpgp/mds.scm b/tests/openpgp/mds.scm new file mode 100755 index 0000000..98f05e6 --- /dev/null +++ b/tests/openpgp/mds.scm @@ -0,0 +1,60 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(define empty-string-hashes + `((1 "D41D8CD98F00B204E9800998ECF8427E" "MD5") + (2 "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709" "SHA1") + (3 "9C1185A5C5E9FC54612808977EE8F548B2258D31" "RIPEMD160") + (11 "D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F" "SHA224") + (8 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" "SHA256") + (9 "38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B" "SHA384") + (10 + "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E" + "SHA512"))) + +(define abc-hashes + `((1 "C3FCD3D76192E4007DFB496CCA67E13B" "MD5") + (2 "32D10C7B8CF96570CA04CE37F2A19D84240D3A89" "SHA1") + (3 "F71C27109C692C1B56BBDCEB5B9D2865B3708DBC" "RIPEMD160") + (11 "45A5F72C39C5CFF2522EB3429799E49E5F44B356EF926BCF390DCCC2" "SHA224") + (8 "71C480DF93D6AE2F1EFAD1447C66C9525E316218CF51FC8D9ED832F2DAF18B73" "SHA256") + (9 "FEB67349DF3DB6F5924815D6C3DC133F091809213731FE5C7B5F4999E463479FF2877F5F2936FA63BB43784B12F3EBB4" "SHA384") + (10 "4DBFF86CC2CA1BAE1E16468A05CB9881C97F1753BCE3619034898FAA1AABE429955A1BF8EC483D7421FE3C1646613A59ED5441FB0F321389F77F48A879C7B1F1" "SHA512"))) + +;; Symbolic names for the triples above. +(define :algo car) +(define :value cadr) +(define :name caddr) + +;; Call GPG to obtain the hash sums for the given string S. +(define (gpg-hash-string s) + (map + (lambda (line) + (let ((p (string-split line #\:))) + (list (string->number (cadr p)) (caddr p)))) + (string-split + (call-popen `(,GPG --with-colons --print-mds) s) #\newline))) + +;; Test whether HASH matches REF. +(define (test-hash hash ref) + (unless (eq? #f ref) + (if (not (string=? (:value hash) (:value ref))) + (error "failed")))) + +;; Test whether the hashes computed over S match the REFERENCE set. +(define (test-hashes msg s reference) + (for-each-p' + msg + (lambda (hash) (test-hash hash (assv (:algo hash) reference))) + (lambda (hash) + (let ((ref (assv (:algo hash) reference))) + (if (eq? #f ref) + (string-append "no-ref-for:" (number->string (:algo hash))) + (:name ref)))) + (gpg-hash-string s))) + +(test-hashes "Hashing the empty string" + "" empty-string-hashes) +(test-hashes "Hashing the string \"abcdefghijklmnopqrstuvwxyz\"" + "abcdefghijklmnopqrstuvwxyz" abc-hashes) diff --git a/tests/openpgp/seat.scm b/tests/openpgp/seat.scm new file mode 100755 index 0000000..e95ede8 --- /dev/null +++ b/tests/openpgp/seat.scm @@ -0,0 +1,19 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(define (check-seat args input) + (lambda (source sink) + (lettmp (encrypted) + (call-popen `(,GPG --output ,encrypted --yes -seat + --always-trust ;; XXX + , at args ,source) input) + (call-popen `(,GPG --output ,sink --yes ,encrypted) "")))) + +(for-each-p + "Test encryption, signing, and producing armored output" + (lambda (source) + (check-identity source + (check-seat '(-r two at example.com --passphrase-fd "0") + usrpass1))) + plain-files) diff --git a/tests/openpgp/sigs.scm b/tests/openpgp/sigs.scm new file mode 100755 index 0000000..9eb5704 --- /dev/null +++ b/tests/openpgp/sigs.scm @@ -0,0 +1,48 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(define (check-signature args input) + (lambda (source sink) + (lettmp (signed) + (call-popen `(,GPG --output ,signed --yes --sign + , at args ,source) input) + (call-popen `(,GPG --output ,sink --yes ,signed) "")))) + +(for-each-p + "Test signing with the default hash algorithm" + (lambda (source) (check-identity source (check-signature '() ""))) + (append plain-files data-files)) + +(for-each-p + "Test signing with a specific hash algorithm" + (lambda (hash) + (if (have-pubkey-algo? "RSA") + ;; RSA key, so any hash is okay. + (check-identity (car plain-files) + (check-signature + `(--user ,usrname3 --digest-algo ,hash) ""))) + (if (not (equal? "MD5" hash)) + ;; Using the DSA sig key - only 160 bit or larger hashes + (check-identity (car plain-files) + (check-signature + `(--passphrase-fd "0" --digest-algo ,hash) usrpass1)))) + all-hash-algos) + +(for-each-p + "Test signing using DSA with the default hash algorithm" + (lambda (source) + (check-identity source + (check-signature `(--user ,dsa-usrname1) ""))) + (append plain-files data-files)) + +(define algos (if (have-hash-algo? "RIPEMD160") + '("SHA1" "RIPEMD160") + '("SHA1"))) +(for-each-p + "Test signing using DSA with a specific hash algorithm" + (lambda (hash) + (check-identity (car plain-files) + (check-signature + `(--user ,dsa-usrname1 --digest-algo ,hash) ""))) + algos) diff --git a/tests/openpgp/version.scm b/tests/openpgp/version.scm new file mode 100755 index 0000000..794d88d --- /dev/null +++ b/tests/openpgp/version.scm @@ -0,0 +1,8 @@ +#!/usr/bin/env gpgscm + +(load (in-srcdir "defs.scm")) + +(info "Printing the GPG version") +(assert (= 0 (call `(,GPG --version)))) + +;; fixme: check that the output is as expected commit abb8b14f512c5b79e47ac5b78e0279d332049301 Author: Justus Winter Date: Wed Jan 6 11:55:25 2016 +0100 tests/gpgscm: XXX Signed-off-by: Justus Winter diff --git a/configure.ac b/configure.ac index 266eae5..56a5875 100644 --- a/configure.ac +++ b/configure.ac @@ -1836,6 +1836,7 @@ tools/gpg-zip tools/Makefile doc/Makefile tests/Makefile +tests/gpgscm/Makefile tests/openpgp/Makefile tests/pkits/Makefile g10/gpg.w32-manifest diff --git a/tests/Makefile.am b/tests/Makefile.am index 307d829..e49c283 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,7 +25,7 @@ else openpgp = endif -SUBDIRS = ${openpgp} . pkits +SUBDIRS = gpgscm ${openpgp} . pkits GPGSM = ../sm/gpgsm diff --git a/tests/gpgscm/Makefile.am b/tests/gpgscm/Makefile.am new file mode 100644 index 0000000..c02da3b --- /dev/null +++ b/tests/gpgscm/Makefile.am @@ -0,0 +1,44 @@ +# TinyScheme-based test driver. +# +# 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 . + +EXTRA_DIST = \ + COPYING \ + init.scm + +AM_CPPFLAGS = -I$(top_srcdir)/common +include $(top_srcdir)/am/cmacros.am + +AM_CFLAGS = + +bin_PROGRAMS = gpgscm + +common_libs = ../$(libcommon) +commonpth_libs = ../$(libcommonpth) + +gpgscm_CFLAGS = -imacros scheme-config.h \ + $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) +gpgscm_SOURCES = main.c scheme-config.h ffi.c ffi.h ffi-private.h \ + opdefines.h scheme.c scheme.h scheme-private.h +gpgscm_LDADD = $(LDADD) $(common_libs) \ + $(NETLIBS) $(LIBICONV) $(LIBREADLINE) \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) + +# Make sure that all libs are build before we use them. This is +# important for things like make -j2. +$(PROGRAMS): $(common_libs) diff --git a/tests/gpgscm/ffi-private.h b/tests/gpgscm/ffi-private.h new file mode 100644 index 0000000..dd6f0cc --- /dev/null +++ b/tests/gpgscm/ffi-private.h @@ -0,0 +1,128 @@ +/* FFI interface for TinySCHEME. + * + * 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 . + */ + +#ifndef _GPGSCM_FFI_PRIVATE_H +#define _GPGSCM_FFI_PRIVATE_H + +#include "scheme.h" +#include "scheme-private.h" + +#define SC_FFI_PROLOG() \ + unsigned int __ffi_arg_index __attribute__ ((unused)) = 1; \ + int err __attribute__ ((unused)) = 0 \ + +#define CONVERSION_pointer(SC, X) (void *) ivalue +#define CONVERSION_number(SC, X) ivalue +#define CONVERSION_string(SC, X) string_value +#define CONVERSION_list(SC, X) +#define CONVERSION_path(SC, X) ((SC)->vptr->is_string (X) \ + ? (SC)->vptr->string_value \ + : (SC)->vptr->symname) + +#define IS_A_pointer(SC, X) (SC)->vptr->is_number (X) +#define IS_A_number(SC, X) (SC)->vptr->is_number (X) +#define IS_A_string(SC, X) (SC)->vptr->is_string (X) +#define IS_A_list(SC, X) (SC)->vptr->is_list (SC, X) +#define IS_A_path(SC, X) ((SC)->vptr->is_string (X) \ + || (SC)->vptr->is_symbol (X)) + +#define SC_ARG(SC, CTYPE, TARGET, WANT, ARGS) \ + ({ \ + if ((ARGS) == (SC)->NIL) \ + return (SC)->vptr->mk_string ((SC), \ + "too few arguments: want " \ + #TARGET "("#WANT"/"#CTYPE")\n"); \ + if (! IS_A_##WANT ((SC), pair_car (ARGS))) { \ + char __ffi_error_message[256]; \ + snprintf (__ffi_error_message, sizeof __ffi_error_message, \ + "argument %d must be: " #WANT "\n", __ffi_arg_index); \ + return (SC)->vptr->mk_string ((SC), __ffi_error_message); \ + } \ + TARGET = CONVERSION_##WANT (SC, pair_car (ARGS)) (pair_car (ARGS)); \ + ARGS = pair_cdr (ARGS); \ + __ffi_arg_index += 1; \ + }) + +#define SC_ARGS_DONE(SC, ARGS) \ + ({ \ + if ((ARGS) != (SC)->NIL) \ + return (SC)->vptr->mk_string ((SC), "too many arguments"); \ + }) + +#define SC_RETURN_ERR(SC, ERR) \ + return _cons ((SC), mk_integer ((SC), (ERR)), (SC)->NIL, 1) + +#define SC_RETURN(SC) SC_RETURN_ERR (SC, err) + +#define SC_RETURN_POINTER(SC, X) \ + return _cons ((SC), mk_integer ((SC), err), \ + _cons ((SC), (X), (SC)->NIL, 1), 1) +#define SC_RETURN_INT(SC, X) \ + SC_RETURN_POINTER ((SC), mk_integer ((SC), (X))) +#define SC_RETURN_STRING(SC, X) \ + SC_RETURN_POINTER ((SC), mk_string ((SC), (X))) + +const char *schemify_name (const char *s, int macro); + +void ffi_scheme_eval (scheme *sc, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); + +#define define_function(S, F) \ + define_function_name ((S), schemify_name (#F, 0), F) + +#define define_function_name(S, NAME, F) \ + ({ \ + scheme_define ((S), \ + (S)->global_env, \ + mk_symbol ((S), schemify_name ("_" #F, 0)), \ + mk_foreign_func ((S), (do_##F))); \ + ffi_scheme_eval ((S), \ + "(define (%s . a) (ffi-apply \"%s\" %s a))", \ + (NAME), (NAME), schemify_name ("_" #F, 0)); \ + }) + +#define define_constant(S, C) \ + scheme_define ((S), \ + (S)->global_env, \ + mk_symbol ((S), schemify_name (#C, 1)), \ + mk_integer ((S), (C))) + +#define define_(S, SYM, EXP) \ + scheme_define ((S), (S)->global_env, mk_symbol ((S), (SYM)), EXP) + +#define define_variable(S, C) \ + scheme_define ((S), \ + (S)->global_env, \ + mk_symbol ((S), schemify_name (#C, 0)), \ + mk_integer ((S), (C))) + +#define define_variable_pointer(S, C, P) \ + scheme_define ((S), \ + (S)->global_env, \ + mk_symbol ((S), schemify_name (#C, 0)), \ + (P)) + +#define define_variable_string(S, C) \ + define_variable_pointer (S, C, (S)->vptr->mk_string (S, C ?: "")) + +void ffi_list2argv (scheme *sc, pointer list, char ***argv); +gpg_error_t ffi_list2intv (scheme *sc, pointer list, int **intv, size_t *len); + +#endif /* _GPGSCM_FFI_PRIVATE_H */ diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c new file mode 100644 index 0000000..acd45be --- /dev/null +++ b/tests/gpgscm/ffi.c @@ -0,0 +1,691 @@ +/* FFI interface for TinySCHEME. + * + * 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 . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_LIBREADLINE +#include +#include +#endif + +#include "../../common/exechelp.h" + +#include "private.h" +#include "ffi.h" +#include "ffi-private.h" + +static pointer +do_logand (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + unsigned int v, acc = ~0; + while (args != sc->NIL) + { + SC_ARG (sc, unsigned int, v, number, args); + acc &= v; + } + SC_RETURN_INT (sc, acc); +} + +static pointer +do_logior (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + unsigned int v, acc = 0; + while (args != sc->NIL) + { + SC_ARG (sc, unsigned int, v, number, args); + acc |= v; + } + SC_RETURN_INT (sc, acc); +} + +static pointer +do_logxor (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + unsigned int v, acc = 0; + while (args != sc->NIL) + { + SC_ARG (sc, unsigned int, v, number, args); + acc ^= v; + } + SC_RETURN_INT (sc, acc); +} + +static pointer +do_lognot (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + unsigned int v; + SC_ARG (sc, unsigned int, v, number, args); + SC_ARGS_DONE (sc, args); + SC_RETURN_INT (sc, ~v); +} + +/* User interface. */ + +int use_libreadline; + +/* Read a string, and return a pointer to it. Returns NULL on EOF. */ +char * +rl_gets (const char *prompt) +{ + static char *line = NULL; + char *p; + free (line); + +#if HAVE_LIBREADLINE + if (use_libreadline) + { + line = readline (prompt); + if (line && *line) + add_history (line); + } + else +#endif + { + size_t max_size = 0xff; + printf ("%s", prompt); + fflush (stdout); + line = malloc (max_size); + if (line != NULL) + fgets (line, max_size, stdin); + } + + /* Strip trailing whitespace. */ + if (line && strlen (line) > 0) + for (p = &line[strlen (line) - 1]; isspace (*p); p--) + *p = 0; + + return line; +} + +static pointer +do_enable_readline (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + SC_ARGS_DONE (sc, args); + use_libreadline = 1; + SC_RETURN (sc); +} + +static pointer +do_prompt (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + const char *prompt; + const char *line; + SC_ARG (sc, const char *, prompt, string, args); + SC_ARGS_DONE (sc, args); + line = rl_gets (prompt); + ffi_update (sc); + if (! line) + SC_RETURN_POINTER (sc, sc->EOF_OBJ); + + SC_RETURN_STRING (sc, line); +} + +static pointer +do_sleep (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + unsigned int seconds; + SC_ARG (sc, unsigned int, seconds, number, args); + SC_ARGS_DONE (sc, args); + sleep (seconds); + ffi_update (sc); + SC_RETURN (sc); +} + +static pointer +do_usleep (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + useconds_t microseconds; + SC_ARG (sc, useconds_t, microseconds, number, args); + SC_ARGS_DONE (sc, args); + usleep (microseconds); + ffi_update (sc); + SC_RETURN (sc); +} + +static pointer +do_chdir (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + char *name; + SC_ARG (sc, char *, name, path, args); + SC_ARGS_DONE (sc, args); + if (chdir (name)) + SC_RETURN_ERR (sc, errno); + SC_RETURN (sc); +} + +static pointer +do_strerror (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + int error; + SC_ARG (sc, int, error, number, args); + SC_ARGS_DONE (sc, args); + SC_RETURN_STRING (sc, gpg_strerror (error)); +} + +static pointer +do_getenv (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + char *name; + SC_ARG (sc, char *, name, string, args); + SC_ARGS_DONE (sc, args); + SC_RETURN_STRING (sc, getenv (name) ?: ""); +} + +static pointer +do_exit (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + int retcode; + SC_ARG (sc, int, retcode, number, args); + SC_ARGS_DONE (sc, args); + exit (retcode); +} + +static pointer +do_close (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + int fd; + SC_ARG (sc, int, fd, number, args); + SC_ARGS_DONE (sc, args); + SC_RETURN_ERR (sc, close (fd) == 0 ? 0 : gpg_error_from_syserror ()); +} + +static pointer +do_mktemp (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + char *template; + char buffer[128]; + SC_ARG (sc, char *, template, string, args); + SC_ARGS_DONE (sc, args); + + if (strlen (template) > sizeof buffer - 1) + SC_RETURN_ERR (sc, EINVAL); + strncpy (buffer, template, sizeof buffer); + + SC_RETURN_STRING (sc, mktemp (buffer)); +} + +static pointer +do_unlink (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + char *name; + SC_ARG (sc, char *, name, string, args); + SC_ARGS_DONE (sc, args); + if (unlink (name) == -1) + SC_RETURN_ERR (sc, gpg_error_from_syserror ()); + SC_RETURN (sc); +} + +/* Process handling. */ + +static pointer +do_spawn_process (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + pointer arguments; + char **argv; + unsigned int flags; + + estream_t infp; + estream_t outfp; + estream_t errfp; + pid_t pid; + + SC_ARG (sc, pointer, arguments, list, args); + SC_ARG (sc, unsigned int, flags, number, args); + SC_ARGS_DONE (sc, args); + + ffi_list2argv (sc, arguments, &argv); + if (argv == NULL) + SC_RETURN_ERR (sc, errno); + + err = gnupg_spawn_process (argv[0], (const char **) &argv[1], + GPG_ERR_SOURCE_DEFAULT, /* XXX */ + NULL, /* XXX */ + flags, + &infp, &outfp, &errfp, &pid); + free (argv); +#define IMC(A, B) \ + _cons (sc, sc->vptr->mk_integer (sc, (unsigned long) (A)), (B), 1) + SC_RETURN_POINTER (sc, IMC (infp, + IMC (outfp, + IMC (errfp, + IMC (pid, sc->NIL))))); +#undef IMC +} + +static pointer +do_spawn_process_fd (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + pointer arguments; + char **argv; + int infd, outfd, errfd; + + pid_t pid; + + SC_ARG (sc, pointer, arguments, list, args); + SC_ARG (sc, int, infd, number, args); + SC_ARG (sc, int, outfd, number, args); + SC_ARG (sc, int, errfd, number, args); + SC_ARGS_DONE (sc, args); + + ffi_list2argv (sc, arguments, &argv); + if (argv == NULL) + SC_RETURN_ERR (sc, errno); + + err = gnupg_spawn_process_fd (argv[0], (const char **) &argv[1], + infd, outfd, errfd, + &pid); + free (argv); + SC_RETURN_INT (sc, pid); +} + +static pointer +do_wait_process (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + const char *name; + pid_t pid; + int hang; + + int retcode; + + SC_ARG (sc, const char *, name, string, args); + SC_ARG (sc, pid_t, pid, number, args); + SC_ARG (sc, int, hang, number, args); + SC_ARGS_DONE (sc, args); + err = gnupg_wait_process (name, pid, hang, &retcode); + if (err == GPG_ERR_GENERAL) + err = 0; /* Let the return code speak for itself. */ + + ffi_update (sc); + SC_RETURN_INT (sc, retcode); +} + + +static pointer +do_wait_processes (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + pointer list_names; + char **names; + pointer list_pids; + size_t count; + pid_t *pids; + int hang; + + SC_ARG (sc, pointer, list_names, list, args); + SC_ARG (sc, pointer, list_pids, list, args); + SC_ARG (sc, int, hang, number, args); + SC_ARGS_DONE (sc, args); + + if (sc->vptr->list_length (sc, list_names) + != sc->vptr->list_length (sc, list_pids)) + return + sc->vptr->mk_string (sc, "length of first two arguments must match"); + + ffi_list2argv (sc, list_names, &names); + if (names == NULL) + SC_RETURN_ERR (sc, gpg_error_from_syserror ()); + + err = ffi_list2intv (sc, list_pids, (int **) &pids, &count); + if (err) + SC_RETURN (sc); + + err = gnupg_wait_processes (names, pids, count, hang, NULL); + + SC_RETURN_INT (sc, 0 /* XXX */); +} + + +static pointer +do_pipe (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + int filedes[2]; + SC_ARGS_DONE (sc, args); + err = gnupg_create_pipe (filedes); +#define IMC(A, B) \ + _cons (sc, sc->vptr->mk_integer (sc, (unsigned long) (A)), (B), 1) + SC_RETURN_POINTER (sc, IMC (filedes[0], + IMC (filedes[1], sc->NIL))); +#undef IMC +} + + + +/* estream functions. */ +static pointer +do_es_fclose (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + estream_t stream; + SC_ARG (sc, estream_t, stream, pointer, args); + SC_ARGS_DONE (sc, args); + SC_RETURN_ERR (sc, es_fclose (stream)); +} + +static pointer +do_es_read (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + estream_t stream; + size_t bytes_to_read; + + pointer result; + void *buffer; + size_t bytes_read; + + SC_ARG (sc, estream_t, stream, pointer, args); + SC_ARG (sc, size_t, bytes_to_read, number, args); + SC_ARGS_DONE (sc, args); + + buffer = malloc (bytes_to_read); + if (buffer == NULL) + SC_RETURN_ERR (sc, ENOMEM); + + err = es_read (stream, buffer, bytes_to_read, &bytes_read); + if (err) + SC_RETURN_ERR (sc, err); + + result = sc->vptr->mk_counted_string (sc, buffer, bytes_read); + free (buffer); + SC_RETURN_POINTER (sc, result); +} + +static pointer +do_es_feof (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + estream_t stream; + SC_ARG (sc, estream_t, stream, pointer, args); + SC_ARGS_DONE (sc, args); + + SC_RETURN_POINTER (sc, es_feof (stream) ? sc->T : sc->F); +} + +static pointer +do_es_write (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + estream_t stream; + const char *buffer; + size_t bytes_to_write, bytes_written; + + SC_ARG (sc, estream_t, stream, pointer, args); + /* XXX how to get the length of the string buffer? scheme strings + may contain \0. */ + SC_ARG (sc, const char *, buffer, string, args); + SC_ARGS_DONE (sc, args); + + bytes_to_write = strlen (buffer); + while (bytes_to_write > 0) + { + err = es_write (stream, buffer, bytes_to_write, &bytes_written); + if (err) + break; + bytes_to_write -= bytes_written; + buffer += bytes_written; + } + + SC_RETURN (sc); +} + +/* Test helper functions. */ +static pointer +do_file_equal (scheme *sc, pointer args) +{ + SC_FFI_PROLOG (); + pointer result = sc->F; + char *a_name, *b_name; + FILE *a_stream = NULL, *b_stream = NULL; + struct stat a_stat, b_stat; +#define BUFFER_SIZE 1024 + char a_buf[BUFFER_SIZE], b_buf[BUFFER_SIZE]; +#undef BUFFER_SIZE + size_t size, chunk; + + SC_ARG (sc, char *, a_name, string, args); + SC_ARG (sc, char *, b_name, string, args); + SC_ARGS_DONE (sc, args); + + a_stream = fopen (a_name, "rb"); + if (a_stream == NULL) + goto errout; + + b_stream = fopen (b_name, "rb"); + if (b_stream == NULL) + goto errout; + + if (fstat (fileno (a_stream), &a_stat) < 0) + goto errout; + + if (fstat (fileno (b_stream), &b_stat) < 0) + goto errout; + + if (a_stat.st_size != b_stat.st_size) + goto out; + + for (size = a_stat.st_size; size > 0; size -= chunk) + { + chunk = size; + if (chunk > sizeof a_buf) + chunk = sizeof a_buf; + + if (fread (a_buf, 1, chunk, a_stream) < chunk) + goto errout; + if (fread (b_buf, 1, chunk, b_stream) < chunk) + goto errout; + if (memcmp (a_buf, b_buf, chunk) != 0) + goto out; + } + + /* They match. */ + result = sc->T; + + out: + if (a_stream) + fclose (a_stream); + if (b_stream) + fclose (b_stream); + SC_RETURN_POINTER (sc, result); + errout: + err = gpg_error_from_syserror (); + goto out; +} + +void +ffi_list2argv (scheme *sc, pointer list, char ***argv) +{ + int i, length; + + length = sc->vptr->list_length (sc, list); + *argv = calloc (length + 1, sizeof **argv); + if (*argv == NULL) + return; + + for (i = 0; sc->vptr->is_pair (list); list = sc->vptr->pair_cdr (list)) + { + if (sc->vptr->is_string (sc->vptr->pair_car (list))) + (*argv)[i++] = sc->vptr->string_value (sc->vptr->pair_car (list)); + else if (sc->vptr->is_symbol (sc->vptr->pair_car (list))) + (*argv)[i++] = sc->vptr->symname (sc->vptr->pair_car (list)); + else + continue; /* XXX this just silently drops values */ + } + (*argv)[i] = NULL; +} + +gpg_error_t +ffi_list2intv (scheme *sc, pointer list, int **intv, size_t *len) +{ + int i; + + *len = sc->vptr->list_length (sc, list); + *intv = calloc (*len, sizeof *intv); + if (*intv == NULL) + return gpg_error_from_syserror (); + + for (i = 0; sc->vptr->is_pair (list); list = sc->vptr->pair_cdr (list)) + { + if (sc->vptr->is_number (sc->vptr->pair_car (list))) + (*intv)[i++] = sc->vptr->ivalue (sc->vptr->pair_car (list)); + else + return GPG_ERR_INV_ARG; + } + + return 0; +} + + +const char * +schemify_name (const char *s, int macro) +{ + char *n = strdup (s), *p; + if (n == NULL) + return s; + for (p = n; *p; p++) + { + *p = (char) tolower (*p); + /* We convert _ to - in identifiers. We allow, however, for + function names to start with a leading _. The functions in + this namespace are not yet finalized and might change or + vanish without warning. Use them with care. */ + if (! macro + && p != n + && *p == '_') + *p = '-'; + } + return n; +} + +void +ffi_scheme_eval (scheme *sc, const char *format, ...) +{ + va_list listp; + char *expression; + int size, written; + + va_start (listp, format); + size = vsnprintf (NULL, 0, format, listp); + va_end (listp); + + expression = malloc (size + 1); + if (expression == NULL) + return; + + va_start (listp, format); + written = vsnprintf (expression, size + 1, format, listp); + va_end (listp); + + assert (size == written); + + sc->vptr->load_string (sc, expression); + free (expression); +} + +void +ffi_init (scheme *sc) +{ + /* bitwise arithmetic */ + define_function (sc, logand); + define_function (sc, logior); + define_function (sc, logxor); + define_function (sc, lognot); + + /* libc. */ + define_constant (sc, O_RDONLY); + define_constant (sc, O_WRONLY); + define_constant (sc, O_RDWR); + define_constant (sc, O_CREAT); + define_constant (sc, STDIN_FILENO); + define_constant (sc, STDOUT_FILENO); + define_constant (sc, STDERR_FILENO); + + define_function (sc, sleep); + define_function (sc, usleep); + define_function (sc, chdir); + define_function (sc, strerror); + define_function (sc, getenv); + define_function (sc, exit); + define_function (sc, close); + define_function (sc, mktemp); + define_function (sc, unlink); + + /* Process management. */ + define_function_name (sc, "spawn-process'", spawn_process); + define_function (sc, spawn_process_fd); + define_function (sc, wait_process); + define_function (sc, wait_processes); + define_function (sc, pipe); + + /* estream functions. */ + define_function_name (sc, "es-fclose", es_fclose); + define_function_name (sc, "es-read", es_read); + define_function_name (sc, "es-feof", es_feof); + define_function_name (sc, "es-write", es_write); + + /* Test helper functions. */ + define_function_name (sc, "file=?", file_equal); + + /* User interface. */ + define_function (sc, enable_readline); + define_function (sc, prompt); + + /* Configuration. */ + ffi_scheme_eval (sc, "(define *verbose* %s)", verbose ? "#t" : "#f"); + + ffi_update (sc); +} + +void +ffi_update (scheme *sc) +{ + /* XXX it is not clear whether that is even possible to get right. */ + (void) sc; +} diff --git a/tests/gpgscm/ffi.h b/tests/gpgscm/ffi.h new file mode 100644 index 0000000..49dad5a --- /dev/null +++ b/tests/gpgscm/ffi.h @@ -0,0 +1,29 @@ +/* FFI interface for TinySCHEME. + * + * 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 . + */ + +#ifndef _GPGSCM_FFI_H +#define _GPGSCM_FFI_H + +#include "scheme.h" + +void ffi_init (scheme *sc); +void ffi_update (scheme *sc); + +#endif /* _GPGSCM_FFI_H */ diff --git a/tests/gpgscm/ffi.scm b/tests/gpgscm/ffi.scm new file mode 100644 index 0000000..d0b8a99 --- /dev/null +++ b/tests/gpgscm/ffi.scm @@ -0,0 +1,40 @@ +;; FFI interface for TinySCHEME. +;; +;; 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 . + +;; Foreign function wrapper. Expects F to return a list with the +;; first element being the `error_t' value returned by the foreign +;; function. The error is thrown, or the cdr of the result is +;; returned. +(define (ffi-apply name f args) + (let ((result (apply f args))) + (cond + ((string? result) + (ffi-fail name args result)) + ((not (= (car result) 0)) + (ffi-fail name args (strerror (car result)))) + ((and (= (car result) 0) (pair? (cdr result))) (cadr result)) + ((= (car result) 0) '()) + (else + (throw (list "Result violates FFI calling convention: " result)))))) + +(define (ffi-fail name args message) + (let ((args' (open-output-string))) + (write (cons (string->symbol name) args) args') + (throw (string-append + (get-output-string args') ": " message)))) diff --git a/tests/gpgscm/lib.scm b/tests/gpgscm/lib.scm new file mode 100644 index 0000000..d0057f9 --- /dev/null +++ b/tests/gpgscm/lib.scm @@ -0,0 +1,96 @@ +;; Additional library functions for TinySCHEME. +;; +;; 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 . + +(define (filter pred lst) + (cond ((null? lst) '()) + ((pred (car lst)) + (cons (car lst) (filter pred (cdr lst)))) + (else (filter pred (cdr lst))))) + +(define (any p l) + (cond ((null? l) #f) + ((p (car l)) #t) + (else (any p (cdr l))))) + +;; Is s1 a prefix of s2 ? +(define (string-prefix? s1 s2) + (and (>= (string-length s2) (string-length s1)) + (string=? s1 (substring s2 0 (string-length s1))))) + +;; Given a list of prefixes, does s start with any of them ? +(define (string-prefix-any? lp s) + (any (lambda (p) (string-prefix? p s)) lp)) + +;; Locate the first occurrence of needle in haystack. +(define (string-index haystack needle) + (define (index i haystack needle) + (if (= (length haystack) 0) + #f + (if (char=? (car haystack) needle) + i + (index (+ i 1) (cdr haystack) needle)))) + (index 0 (string->list haystack) needle)) + +;; Split haystack at delimiter at most n times. +(define (string-splitn haystack delimiter n) + (define (split acc haystack delimiter n) + (if (= (string-length haystack) 0) + (reverse acc) + (let ((i (string-index haystack delimiter))) + (if (not (or (eq? i #f) (= 0 n))) + (split (cons (substring haystack 0 i) acc) + (substring haystack (+ i 1) (string-length haystack)) + delimiter (- n 1)) + (split (cons haystack acc) "" delimiter 0) + )))) + (split '() haystack delimiter n)) + +;; Split haystack at delimiter. +(define (string-split haystack delimiter) + (string-splitn haystack delimiter -1)) + +;; Drop whitespace. +(define (filter-whitespace s) + (list->string (filter (lambda (c) (not (char=? #\newline c))) (string->list s)))) + +(define (echo . msg) + (for-each (lambda (x) (display x) (display " ")) msg) + (newline)) + +;; Read a word from port P. +(define (read-word p) + (list->string + (let f () + (let ((c (peek-char p))) + (cond + ((eof-object? c) '()) + ((char-alphabetic? c) + (read-char p) + (cons c (f))) + (else '())))))) + +;; Read everything from port P. +(define (read-all p) + (list->string + (let f () + (let ((c (peek-char p))) + (cond + ((eof-object? c) '()) + (else (read-char p) + (cons c (f)))))))) diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c new file mode 100644 index 0000000..e7cc3e3 --- /dev/null +++ b/tests/gpgscm/main.c @@ -0,0 +1,219 @@ +/* TinyScheme-based test driver. + * + * 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 . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "private.h" +#include "scheme.h" +#include "ffi.h" +#include "i18n.h" +#include "../../common/argparse.h" +#include "../../common/init.h" +#include "../../common/logging.h" +#include "../../common/strlist.h" + +/* The TinyScheme banner. Unfortunately, it isn't in the header + file. */ +#define ts_banner "TinyScheme 1.41" + +int verbose; + + + +/* Constants to identify the commands and options. */ +enum cmd_and_opt_values + { + aNull = 0, + oVerbose = 'v', + oBase = 500, + }; + +/* The list of commands and options. */ +static ARGPARSE_OPTS opts[] = + { + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), + ARGPARSE_s_s (oBase, "base", "base directory (containing 'init.scm')"), + ARGPARSE_end (), + }; + +const char *basedir = "../tests/gpgscm"; + +/* Command line parsing. */ +static void +parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts) +{ + int no_more_options = 0; + + while (!no_more_options && optfile_parse (NULL, NULL, NULL, pargs, popts)) + { + switch (pargs->r_opt) + { + case oVerbose: + verbose++; + break; + + case oBase: + basedir = pargs->r.ret_str; + break; + + default: + pargs->err = 2; + break; + } + } +} + +/* Print usage information and and provide strings for help. */ +static const char * +my_strusage( int level ) +{ + const char *p; + + switch (level) + { + case 11: p = "gpgscm (@GNUPG@)"; + break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + + case 1: + case 40: + p = _("Usage: gpgscm [options] [file] (-h for help)"); + break; + case 41: + p = _("Syntax: gpgscm [options] [file]\n" + "Execute the given Scheme program, or spawn interactive shell.\n"); + break; + + default: p = NULL; break; + } + return p; +} + + +/* Load the Scheme program from FILE_NAME. If FILE_NAME is not an + absolute path, and PATH is not NULL, then it is qualified with + PATH. */ +void +load (scheme *sc, const char *path, const char *file_name) +{ + char *qualified_name; + FILE *h; + + if (path != NULL && file_name[0] != '/') + { + if (asprintf (&qualified_name, "%s/%s", path, file_name) < 0) + { + fprintf (stderr, "asprintf: %s\n", strerror (errno)); + exit (EXIT_FAILURE); + } + } + else + qualified_name = (char *) file_name; + + if (verbose) + fprintf (stderr, "Loading %s...\n", qualified_name); + h = fopen (qualified_name, "r"); + if (! h) + { + fprintf (stderr, "Could not read %s: %s.\n" + "Consider using --base to specify the location of the " + "Scheme library.\n", qualified_name, strerror (errno)); + exit (EXIT_FAILURE); + } + + scheme_load_named_file (sc, h, qualified_name); + fclose (h); + + if (file_name != qualified_name) + free (qualified_name); +} + + + +int +main (int argc, char **argv) +{ + ARGPARSE_ARGS pargs; + scheme *sc; + + if (getenv ("GPGSCM_BASE")) + basedir = getenv ("GPGSCM_BASE"); + + set_strusage (my_strusage); + log_set_prefix ("gpgscm", 1); + + /* Make sure that our subsystems are ready. */ + i18n_init (); + init_common_subsystems (&argc, &argv); + + if (!gcry_check_version (GCRYPT_VERSION)) + { + fputs ("libgcrypt version mismatch\n", stderr); + exit (2); + } + + /* Parse the command line. */ + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags = 0; + parse_arguments (&pargs, opts); + + if (log_get_errorcount (0)) + exit (2); + + sc = scheme_init_new (); + if (! sc) { + fprintf (stderr, "Could not initialize TinyScheme!\n"); + return 2; + } + scheme_set_input_port_file (sc, stdin); + scheme_set_output_port_file (sc, stderr); + + load (sc, basedir, "init.scm"); + load (sc, basedir, "ffi.scm"); + ffi_init (sc); + load (sc, basedir, "lib.scm"); + load (sc, basedir, "tests.scm"); + + if (argc == 0) + { + /* Interactive shell. */ + fprintf (stderr, "gpgscm/"ts_banner".\n"); + scheme_load_named_file (sc, stdin, 0); + } + else + load (sc, NULL, argv[0]); + + scheme_deinit (sc); + return EXIT_SUCCESS; +} diff --git a/tests/gpgscm/private.h b/tests/gpgscm/private.h new file mode 100644 index 0000000..efa0cb0 --- /dev/null +++ b/tests/gpgscm/private.h @@ -0,0 +1,26 @@ +/* TinyScheme-based test driver. + * + * 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 . + */ + +#ifndef __GPGSCM_PRIVATE_H__ +#define __GPGSCM_PRIVATE_H__ + +extern int verbose; + +#endif /* __GPGSCM_PRIVATE_H__ */ diff --git a/tests/gpgscm/scheme-config.h b/tests/gpgscm/scheme-config.h new file mode 100644 index 0000000..b2b4db0 --- /dev/null +++ b/tests/gpgscm/scheme-config.h @@ -0,0 +1,38 @@ +/* TinyScheme configuration. + * + * 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 . + */ + +#define STANDALONE 0 +#define USE_MATH 0 +#define USE_CHAR_CLASSIFIERS 1 +#define USE_ASCII_NAMES 1 +#define USE_STRING_PORTS 1 +#define USE_ERROR_HOOK 1 +#define USE_TRACING 1 +#define USE_COLON_HOOK 0 +#define USE_DL 0 +#define USE_PLIST 0 +#define USE_INTERFACE 1 +#define SHOW_ERROR_LINE 1 + +#define STRBUFFSIZE 4096 + +#if __MINGW32__ +# define USE_STRLWR 0 +#endif /* __MINGW32__ */ diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm new file mode 100644 index 0000000..439cf87 --- /dev/null +++ b/tests/gpgscm/tests.scm @@ -0,0 +1,155 @@ +;; Common definitions for writing tests. +;; +;; 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 . + +(define (trace x) + (display x) + (newline) + x) + +;; Reporting. +(define (info msg) + (display msg) + (newline)) + +(define (error msg) + (display msg) + (newline) + (exit 1)) + +(define (skip msg) + (display msg) + (newline) + (exit 77)) + +(define (make-counter) + (let ((c 0)) + (lambda () + (let ((r c)) + (set! c (+ 1 c)) + r)))) + +(macro (assert form) + `(if (not ,(cadr form)) + (error (list "Assertion failed:" (quote ,(cadr form)))))) +(assert #t) + +(define *progress-nesting* 0) + +(define (call-with-progress msg what) + (set! *progress-nesting* (+ 1 *progress-nesting*)) + (if (= 1 *progress-nesting*) + (begin + (display msg) + (newline) + (display " > ") + (what (lambda (item) + (display item) + (display " "))) + (display "< ") + (newline)) + (begin + (what (lambda (item) (display "."))) + (display " "))) + (set! *progress-nesting* (- *progress-nesting* 1))) + +(define (for-each-p msg proc lst) + (for-each-p' msg proc (lambda (x) x) lst)) + +(define (for-each-p' msg proc fmt lst) + (call-with-progress + msg + (lambda (progress) + (for-each (lambda (a) + (progress (fmt a)) + (proc a)) + lst)))) + +;; Process management. +(define (call what) + (wait-process (car what) (spawn-process-fd what -1 -1 2) 1)) + +;; Accessor functions for the results of +(define :stdin car) +(define :stdout cadr) +(define :stderr caddr) +(define :pid cadddr) + +(define (call-with-io what in) + (if *verbose* + (echo "Calling" what)) + (let ((h (spawn-process' what 0))) + (es-write (:stdin h) in) + (es-fclose (:stdin h)) + (let ((out (es-read-all (:stdout h))) + (err (es-read (:stderr h) 1024))) + (es-fclose (:stdout h)) + (es-fclose (:stderr h)) + ;; maybe wait earlier?? + (list (wait-process (car what) (:pid h) 1) out err)))) + +(define :retcode car) + +(define (call-popen command input-string) + (let ((result (call-with-io command input-string))) + (if (= 0 (:retcode result)) + (:stdout result) + (throw (:stderr result))))) + +;; +;; estream helpers. +;; + +(define (es-read-all stream) + (let loop + ((acc "")) + (if (es-feof stream) + acc + (loop (string-append acc (es-read stream 4096)))))) + +;; File management. +(define (in-srcdir what) + (string-append (getenv "srcdir") "/" what)) + + +;; let-like macro that manages temporary files. +;; +;; (lettmp ) +;; +;; Bind all variables given in , initialize each of them to +;; a string representing an unique path in the filesystem, and delete +;; them after evaluting . +(macro (lettmp form) + (let ((result-sym (gensym))) + `((lambda (,(caadr form)) + (let ((,result-sym + ,(if (= 1 (length (cadr form))) + `(begin ,@(cddr form)) + `(lettmp ,(cdadr form) ,@(cddr form))))) + (catch #t (unlink ,(caadr form))) + ,result-sym)) (mktemp "gpgscm-XXXXXX")))) + +(define (check-execution source transformer) + (lettmp (sink) + (transformer source sink))) + +(define (check-identity source transformer) + (lettmp (sink) + (transformer source sink) + (if (not (file=? source sink)) + (error "mismatch")))) commit 412149bc67b2666f68048ccd7011114ee338de88 Author: Justus Winter Date: Thu Jan 14 18:20:14 2016 +0100 common/exechelp: Provide a way to wait for multiple processes. * common/exechelp-posix.c (gnupg_wait_process): Generalize to 'gnupg_wait_processes'. * common/exechelp-w32.c (gnupg_wait_process): Likewise. * common/exechelp-w32ce.c (gnupg_wait_process): New function stub. * common/exechelp.h (gnupg_wait_process): New prototype. Signed-off-by: Justus Winter diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 37abf55..307e2d7 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -522,60 +522,94 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], } -/* See exechelp.h for the description. */ +/* See exechelp.h for a description. */ gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) { - gpg_err_code_t ec; - int i, status; + return gnupg_wait_processes (&pgmname, &pid, 1, hang, + r_exitcode ? &r_exitcode : NULL); +} - if (r_exitcode) - *r_exitcode = -1; +/* See exechelp.h for a description. */ +gpg_error_t +gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, + int hang, int **r_exitcodes) +{ + gpg_err_code_t ec = 0; + size_t i, left; - if (pid == (pid_t)(-1)) - return gpg_error (GPG_ERR_INV_VALUE); + for (i = 0; i < count; i++) + { + if (r_exitcodes) + (*r_exitcodes)[i] = -1; + + if (pids[i] == (pid_t)(-1)) + return gpg_error (GPG_ERR_INV_VALUE); + } + + left = count; + while (left > 0 && ec == 0) + { + pid_t pid; + int status; #ifdef USE_NPTH - i = npth_waitpid (pid, &status, hang? 0:WNOHANG); + pid = npth_waitpid (-1, &status, hang ? 0 : WNOHANG); #else - while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1) - && errno == EINTR); + while ((pid = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1) + && errno == EINTR); #endif - if (i == (pid_t)(-1)) - { - ec = gpg_err_code_from_errno (errno); - log_error (_("waiting for process %d to terminate failed: %s\n"), - (int)pid, strerror (errno)); - } - else if (!i) - { - ec = GPG_ERR_TIMEOUT; /* Still running. */ - } - else if (WIFEXITED (status) && WEXITSTATUS (status) == 127) - { - log_error (_("error running '%s': probably not installed\n"), pgmname); - ec = GPG_ERR_CONFIGURATION; - } - else if (WIFEXITED (status) && WEXITSTATUS (status)) - { - if (!r_exitcode) - log_error (_("error running '%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); + if (pid == (pid_t)(-1)) + { + ec = gpg_err_code_from_errno (errno); + log_error (_("waiting for processes to terminate failed: %s\n"), + strerror (errno)); + } + else if (!pid) + { + ec = GPG_ERR_TIMEOUT; /* Still running. */ + } else - *r_exitcode = WEXITSTATUS (status); - ec = GPG_ERR_GENERAL; - } - else if (!WIFEXITED (status)) - { - log_error (_("error running '%s': terminated\n"), pgmname); - ec = GPG_ERR_GENERAL; - } - else - { - if (r_exitcode) - *r_exitcode = 0; - ec = 0; + { + for (i = 0; i < count; i++) + if (pid == pids[i]) + break; + + if (i == count) + /* No match, ignore this pid. */ + continue; + + /* Process PIDS[i] died. */ + left -= 1; + + if (WIFEXITED (status) && WEXITSTATUS (status) == 127) + { + log_error (_("error running '%s': probably not installed\n"), + pgmnames[i]); + ec = GPG_ERR_CONFIGURATION; + } + else if (WIFEXITED (status) && WEXITSTATUS (status)) + { + if (!r_exitcodes) + log_error (_("error running '%s': exit status %d\n"), + pgmnames[i], WEXITSTATUS (status)); + else + (*r_exitcodes)[i] = WEXITSTATUS (status); + ec = GPG_ERR_GENERAL; + } + else if (!WIFEXITED (status)) + { + log_error (_("error running '%s': terminated\n"), pgmnames[i]); + ec = GPG_ERR_GENERAL; + } + else + { + if (r_exitcodes) + (*r_exitcodes)[i] = 0; + ec = 0; + } + } } return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index d81c445..05573f8 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -701,21 +701,39 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) { - gpg_err_code_t ec; - HANDLE proc = fd_to_handle (pid); + return gnupg_wait_processes (&pgmname, &pid, 1, hang, + r_exitcode ? &r_exitcode : NULL); +} + +/* See exechelp.h for a description. */ +gpg_error_t +gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, + int hang, int **r_exitcodes) +{ + gpg_err_code_t ec = 0; + size_t i; + HANDLE *procs; int code; - DWORD exc; - if (r_exitcode) - *r_exitcode = -1; + procs = xtrycalloc (count, sizeof *procs); + if (procs == NULL) + return gpg_error_from_syserror (); + + for (i = 0; i < count; i++) + { + if (r_exitcodes) + (*r_exitcodes)[i] = -1; + + if (pids[i] == (pid_t)(-1)) + return gpg_error (GPG_ERR_INV_VALUE); - if (pid == (pid_t)(-1)) - return gpg_error (GPG_ERR_INV_VALUE); + procs[i] = fd_to_handle (pids[i]); + } /* FIXME: We should do a pth_waitpid here. However this has not yet been implemented. A special W32 pth system call would even be better. */ - code = WaitForSingleObject (proc, hang? INFINITE : 0); + code = WaitForMultipleObjects (count, procs, TRUE, hang? INFINITE : 0); switch (code) { case WAIT_TIMEOUT: @@ -723,37 +741,42 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) break; case WAIT_FAILED: - log_error (_("waiting for process %d to terminate failed: %s\n"), - (int)pid, w32_strerror (-1)); + log_error (_("waiting for processes to terminate failed: %s\n"), + w32_strerror (-1)); ec = GPG_ERR_GENERAL; break; case WAIT_OBJECT_0: - if (!GetExitCodeProcess (proc, &exc)) - { - log_error (_("error getting exit code of process %d: %s\n"), - (int)pid, w32_strerror (-1) ); - ec = GPG_ERR_GENERAL; - } - else if (exc) + for (i = 0; i < count && ec == 0; i++) { - log_error (_("error running '%s': exit status %d\n"), - pgmname, (int)exc ); - if (r_exitcode) - *r_exitcode = (int)exc; - ec = GPG_ERR_GENERAL; - } - else - { - if (r_exitcode) - *r_exitcode = 0; - ec = 0; + DWORD exc; + + if (! GetExitCodeProcess (procs[i], &exc)) + { + log_error (_("error getting exit code of process %d: %s\n"), + (int) pids[i], w32_strerror (-1) ); + ec = GPG_ERR_GENERAL; + } + else if (exc) + { + log_error (_("error running '%s': exit status %d\n"), + pgmnames[i], (int)exc ); + if (r_exitcodes) + (*r_exitcodes)[i] = (int)exc; + ec = GPG_ERR_GENERAL; + } + else + { + if (r_exitcodes) + (*r_exitcodes)[i] = 0; + ec = 0; + } } break; default: - log_error ("WaitForSingleObject returned unexpected " - "code %d for pid %d\n", code, (int)pid ); + log_error ("WaitForMultipleObjects returned unexpected " + "code %d\n", code); ec = GPG_ERR_GENERAL; break; } diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c index 710c828..f1a80a2 100644 --- a/common/exechelp-w32ce.c +++ b/common/exechelp-w32ce.c @@ -796,6 +796,15 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *exitcode) } +/* See exechelp.h for a description. */ +gpg_error_t +gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, + int hang, int **r_exitcodes) +{ + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} + + void gnupg_release_process (pid_t pid) { diff --git a/common/exechelp.h b/common/exechelp.h index cdee300..e6bf93f 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -161,6 +161,10 @@ gpg_error_t gnupg_spawn_process_fd (const char *pgmname, gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode); +/* Like gnupg_wait_process, but for COUNT processes. */ +gpg_error_t gnupg_wait_processes (const char **pgmnames, pid_t *pids, + size_t count, int hang, int **r_exitcodes); + /* Kill a process; that is send an appropriate signal to the process. gnupg_wait_process must be called to actually remove the process commit 58e772e90715b75e6f3054ecd23b7912fdc2274b Author: Justus Winter Date: Thu Jan 14 14:14:25 2016 +0100 common/exechelp: Add general pipe function. * common/exechelp-posix.c (gnupg_create_pipe): New function. * common/exechelp-w32.c (duplicate_function): New function. (INHERIT_{READ,WRITE,BOTH}): New macros. (create_inheritable_pipe): Generalize so that both ends can be inherited. (do_create_pipe): Rename argument accordingly. (gnupg_create_{in,out}bound_pipe): Use new flags. (gnupg_create_pipe): New function. * common/exechelp-w32ce.c (gnupg_create_pipe): New stub. * common/exechelp.h (gnupg_create_pipe): New prototype. Signed-off-by: Justus Winter diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 5706dbe..37abf55 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -310,6 +310,15 @@ gnupg_create_outbound_pipe (int filedes[2]) } +/* Portable function to create a pipe. Under Windows both ends are + inheritable. */ +gpg_error_t +gnupg_create_pipe (int filedes[2]) +{ + return do_create_pipe (filedes); +} + + static gpg_error_t create_pipe_and_estream (int filedes[2], estream_t *r_fp, diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index bc9b5b4..d81c445 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -233,12 +233,34 @@ build_w32_commandline (const char *pgmname, const char * const *argv, } -/* Create pipe where one end is inheritable: With an INHERIT_IDX of 0 - the read end is inheritable, with 1 the write end is inheritable. */ +static BOOL +duplicate_handle (HANDLE source, HANDLE *target) +{ + BOOL ok; + HANDLE new; + + ok = DuplicateHandle (GetCurrentProcess (), source, + GetCurrentProcess (), &new, + 0, /* access */ + TRUE, /* inherit? */ + DUPLICATE_SAME_ACCESS); + if (ok) + { + CloseHandle (source); + *target = new; + } + return ok; +} + +#define INHERIT_READ 1 +#define INHERIT_WRITE 2 +#define INHERIT_BOTH (INHERIT_READ|INHERIT_WRITE) + +/* Create pipe. FLAGS indicates which ends are inheritable. */ static int -create_inheritable_pipe (HANDLE filedes[2], int inherit_idx) +create_inheritable_pipe (HANDLE filedes[2], int flags) { - HANDLE r, w, h; + HANDLE r, w; SECURITY_ATTRIBUTES sec_attr; memset (&sec_attr, 0, sizeof sec_attr ); @@ -248,30 +270,23 @@ create_inheritable_pipe (HANDLE filedes[2], int inherit_idx) if (!CreatePipe (&r, &w, &sec_attr, 0)) return -1; - if (!DuplicateHandle (GetCurrentProcess(), inherit_idx? w : r, - GetCurrentProcess(), &h, 0, - TRUE, DUPLICATE_SAME_ACCESS )) - { - log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1)); - CloseHandle (r); - CloseHandle (w); - return -1; - } + if (flags & INHERIT_READ) + if (! duplicate_handle (r, &r)) + goto fail; - if (inherit_idx) - { - CloseHandle (w); - w = h; - } - else - { - CloseHandle (r); - r = h; - } + if (flags & INHERIT_WRITE) + if (! duplicate_handle (r, &r)) + goto fail; filedes[0] = r; filedes[1] = w; return 0; + + fail: + log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1)); + CloseHandle (r); + CloseHandle (w); + return -1; } @@ -291,14 +306,14 @@ w32_open_null (int for_write) static gpg_error_t -do_create_pipe (int filedes[2], int inherit_idx) +do_create_pipe (int filedes[2], int flags) { gpg_error_t err = 0; HANDLE fds[2]; filedes[0] = filedes[1] = -1; err = gpg_error (GPG_ERR_GENERAL); - if (!create_inheritable_pipe (fds, inherit_idx)) + if (!create_inheritable_pipe (fds, flags)) { filedes[0] = _open_osfhandle (handle_to_fd (fds[0]), 0); if (filedes[0] == -1) @@ -328,7 +343,7 @@ do_create_pipe (int filedes[2], int inherit_idx) gpg_error_t gnupg_create_inbound_pipe (int filedes[2]) { - return do_create_pipe (filedes, 1); + return do_create_pipe (filedes, INHERIT_WRITE); } @@ -337,7 +352,16 @@ gnupg_create_inbound_pipe (int filedes[2]) gpg_error_t gnupg_create_outbound_pipe (int filedes[2]) { - return do_create_pipe (filedes, 0); + return do_create_pipe (filedes, INHERIT_READ); +} + + +/* Portable function to create a pipe. Under Windows both ends are + inheritable. */ +gpg_error_t +gnupg_create_pipe (int filedes[2]) +{ + return do_create_pipe (filedes, INHERIT_BOTH); } diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c index 49ccdbb..710c828 100644 --- a/common/exechelp-w32ce.c +++ b/common/exechelp-w32ce.c @@ -465,6 +465,15 @@ gnupg_create_outbound_pipe (int filedes[2]) } +/* Portable function to create a pipe. Under Windows both ends are + inheritable. */ +gpg_error_t +gnupg_create_pipe (int filedes[2]) +{ + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} + + static int create_process (const char *pgmname, const char *cmdline, PROCESS_INFORMATION *pi) diff --git a/common/exechelp.h b/common/exechelp.h index 9088342..cdee300 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -59,6 +59,11 @@ gpg_error_t gnupg_create_inbound_pipe (int filedes[2]); inheritable. */ gpg_error_t gnupg_create_outbound_pipe (int filedes[2]); +/* Portable function to create a pipe. Under Windows both ends are + inheritable. */ +gpg_error_t gnupg_create_pipe (int filedes[2]); + + #define GNUPG_SPAWN_NONBLOCK 16 #define GNUPG_SPAWN_RUN_ASFW 64 #define GNUPG_SPAWN_DETACHED 128 commit 10ffd84981692bc004ee5ae59415cc42271adfbf Author: Justus Winter Date: Thu Jan 14 13:58:30 2016 +0100 tests/gpgscm: Make various limits configurable. * tests/gpgscm/scheme-private.h: Make various limits configurable. Signed-off-by: Justus Winter diff --git a/tests/gpgscm/scheme-private.h b/tests/gpgscm/scheme-private.h index 3395328..404243e 100644 --- a/tests/gpgscm/scheme-private.h +++ b/tests/gpgscm/scheme-private.h @@ -68,8 +68,12 @@ int retcode; int tracing; +#ifndef CELL_SEGSIZE #define CELL_SEGSIZE 5000 /* # of cells in one segment */ +#endif +#ifndef CELL_NSEGMENT #define CELL_NSEGMENT 10 /* # of segments for cells */ +#endif char *alloc_seg[CELL_NSEGMENT]; pointer cell_seg[CELL_NSEGMENT]; int last_cell_seg; @@ -117,7 +121,9 @@ pointer outport; pointer save_inport; pointer loadport; +#ifndef MAXFIL #define MAXFIL 64 +#endif port load_stack[MAXFIL]; /* Stack of open files for port -1 (LOADing) */ int nesting_stack[MAXFIL]; int file_i; @@ -126,9 +132,13 @@ int nesting; char gc_verbose; /* if gc_verbose is not zero, print gc status */ char no_memory; /* Whether mem. alloc. has failed */ +#ifndef LINESIZE #define LINESIZE 1024 +#endif char linebuff[LINESIZE]; +#ifndef STRBUFFSIZE #define STRBUFFSIZE 256 +#endif char strbuff[STRBUFFSIZE]; FILE *tmpfp; ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 14 20:57:43 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 14 Jan 2016 20:57:43 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-121-g663c5d1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 663c5d129a8f400cc6eb8ab7b91772d6e578152d (commit) via 3b1248e007a6bf830a3230ee2d9cc548205ec31a (commit) via 8241ed59d05e06252647b26477ed5c2f84895a26 (commit) via f5cceef115f0307664956d01c48b1b397fdad4b3 (commit) from 360534bde770f4845669de223154216d249b954b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 663c5d129a8f400cc6eb8ab7b91772d6e578152d Author: Werner Koch Date: Thu Jan 14 20:45:33 2016 +0100 w32: Fix deadlock introduced by keybox_file_rename. * g10/keyring.c (keyring_lock) [W32]: Flush the close cache before locking. * kbx/keybox-init.c (keybox_lock) [W32]: Close the file before locking. Signed-off-by: Werner Koch diff --git a/g10/keyring.c b/g10/keyring.c index 7ae50a3..ca9a698 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -328,8 +328,20 @@ keyring_lock (KEYRING_HANDLE hd, int yes) if (!keyring_is_writable(kr)) continue; if (kr->is_locked) - ; - else if (dotlock_take (kr->lockhd, -1) ) { + continue; + +#ifdef HAVE_W32_SYSTEM + /* Under Windows we need to CloseHandle the file before we + * try to lock it. This is because another process might + * have taken the lock and is using keybox_file_rename to + * rename the base file. How if our dotlock_take below is + * waiting for the lock but we have the base file still + * open, keybox_file_rename will never succeed as we are + * in a deadlock. */ + iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, + (char*)kr->fname); +#endif /*HAVE_W32_SYSTEM*/ + if (dotlock_take (kr->lockhd, -1) ) { log_info ("can't lock '%s'\n", kr->fname ); rc = GPG_ERR_GENERAL; } @@ -343,8 +355,9 @@ keyring_lock (KEYRING_HANDLE hd, int yes) if (!keyring_is_writable(kr)) continue; if (!kr->is_locked) - ; - else if (dotlock_release (kr->lockhd)) + continue; + + if (dotlock_release (kr->lockhd)) log_info ("can't unlock '%s'\n", kr->fname ); else kr->is_locked = 0; diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index 01d29f0..3b53cd5 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -286,27 +286,43 @@ keybox_lock (KEYBOX_HANDLE hd, int yes) if (yes) /* Take the lock. */ { - if (kb->is_locked) - ; - else if (dotlock_take (kb->lockhd, -1)) + if (!kb->is_locked) { - err = gpg_error_from_syserror (); - log_info ("can't lock '%s'\n", kb->fname ); +#ifdef HAVE_W32_SYSTEM + /* Under Windows we need to close the file before we try + * to lock it. This is because another process might have + * taken the lock and is using keybox_file_rename to + * rename the base file. How if our dotlock_take below is + * waiting for the lock but we have the base file still + * open, keybox_file_rename will never succeed as we are + * in a deadlock. */ + if (hd->fp) + { + fclose (hd->fp); + hd->fp = NULL; + } +#endif /*HAVE_W32_SYSTEM*/ + if (dotlock_take (kb->lockhd, -1)) + { + err = gpg_error_from_syserror (); + log_info ("can't lock '%s'\n", kb->fname ); + } + else + kb->is_locked = 1; } - else - kb->is_locked = 1; } else /* Release the lock. */ { - if (!kb->is_locked) - ; - else if (dotlock_release (kb->lockhd)) + if (kb->is_locked) { - err = gpg_error_from_syserror (); - log_info ("can't unlock '%s'\n", kb->fname ); + if (dotlock_release (kb->lockhd)) + { + err = gpg_error_from_syserror (); + log_info ("can't unlock '%s'\n", kb->fname ); + } + else + kb->is_locked = 0; } - else - kb->is_locked = 0; } return err; commit 3b1248e007a6bf830a3230ee2d9cc548205ec31a Author: Werner Koch Date: Thu Jan 14 18:29:26 2016 +0100 gpg: Detect race between pubring.gpg and pubring.kbx use. * g10/keydb.c (maybe_create_keyring_or_box): Detect race condition. Signed-off-by: Werner Koch diff --git a/g10/keydb.c b/g10/keydb.c index cf7b990..9604807 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -272,6 +272,8 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create) int rc; mode_t oldmask; char *last_slash_in_filename; + char *bak_fname = NULL; + char *tmp_fname = NULL; int save_slash; /* A quick test whether the filename already exists. */ @@ -350,11 +352,39 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create) } /* Now the real test while we are locked. */ + + /* Gpg either uses pubring.gpg or pubring.kbx and thus different + * lock files. Now, when one gpg process is updating a pubring.gpg + * and thus holding the corresponding lock, a second gpg process may + * get to here at the time between the two rename operation used by + * the first process to update pubring.gpg. The lock taken above + * may not protect the second process if it tries to create a + * pubring.kbx file which would be protected by a different lock + * file. + * + * We can detect this case by checking that the two temporary files + * used by the update code exist at the same time. In that case we + * do not create a new file but act as if FORCE_CREATE has not been + * given. Obviously there is a race between our two checks but the + * worst thing is that we won't create a new file, which is better + * than to accidentally creating one. */ + rc = keybox_tmp_names (filename, is_box, &bak_fname, &tmp_fname); + if (rc) + goto leave; + if (!access (filename, F_OK)) { rc = 0; /* Okay, we may access the file now. */ goto leave; } + if (!access (bak_fname, F_OK) && !access (tmp_fname, F_OK)) + { + /* Very likely another process is updating a pubring.gpg and we + should not create a pubring.kbx. */ + rc = gpg_error (GPG_ERR_ENOENT); + goto leave; + } + /* The file does not yet exist, create it now. */ oldmask = umask (077); @@ -422,6 +452,8 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create) dotlock_release (lockhd); dotlock_destroy (lockhd); } + xfree (bak_fname); + xfree (tmp_fname); return rc; } commit 8241ed59d05e06252647b26477ed5c2f84895a26 Author: Werner Koch Date: Thu Jan 14 16:50:15 2016 +0100 kbx: New function keybox_file_rename to replace rename. * kbx/keybox-util.c: Include windows.h. (keybox_file_rename): New. * kbx/keybox-update.c (rename_tmp_file): Replace remove+rename by keybox_file_rename. * g10/keyring.c (rename_tmp_file): Ditto. Signed-off-by: Werner Koch diff --git a/g10/keyring.c b/g10/keyring.c index 535dd2b..7ae50a3 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1337,32 +1337,19 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname) iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname ); /* First make a backup file. */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - gnupg_remove (bakfname); -#endif - if (rename (fname, bakfname) ) - { - rc = gpg_error_from_syserror (); - log_error ("renaming '%s' to '%s' failed: %s\n", - fname, bakfname, strerror(errno) ); - return rc; - } + rc = keybox_file_rename (fname, bakfname); + if (rc) + goto fail; /* then rename the file */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - gnupg_remove( fname ); -#endif - if (rename (tmpfname, fname) ) + rc = keybox_file_rename (tmpfname, fname); + if (rc) { - rc = gpg_error_from_syserror (); - log_error (_("renaming '%s' to '%s' failed: %s\n"), - tmpfname, fname, strerror(errno) ); register_secured_file (fname); goto fail; } /* Now make sure the file has the same permissions as the original */ - #ifndef HAVE_DOSISH_SYSTEM { struct stat statbuf; diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index eebcfca..ff65904 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -119,22 +119,15 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, /* First make a backup file except for secret keyboxes. */ if (!secret) { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - gnupg_remove (bakfname); -#endif - if (rename (fname, bakfname) ) - { - return gpg_error_from_syserror (); - } + rc = keybox_file_rename (fname, bakfname); + if (rc) + return rc; } /* Then rename the file. */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - gnupg_remove (fname); -#endif - if (rename (tmpfname, fname) ) + rc = keybox_file_rename (tmpfname, fname); + if (rc) { - rc = gpg_error_from_syserror (); if (secret) { /* log_info ("WARNING: 2 files with confidential" */ diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c index f7efd1a..740ea73 100644 --- a/kbx/keybox-util.c +++ b/kbx/keybox-util.c @@ -21,6 +21,10 @@ #include #include #include +#ifdef HAVE_DOSISH_SYSTEM +# define WIN32_LEAN_AND_MEAN /* We only need the OS core stuff. */ +# include +#endif #include "keybox-defs.h" @@ -141,3 +145,64 @@ keybox_tmp_names (const char *filename, int for_keyring, *r_tmpname = tmp_name; return 0; } + + +/* Wrapper for rename(2) to handle Windows peculiarities. */ +gpg_error_t +keybox_file_rename (const char *oldname, const char *newname) +{ + gpg_error_t err = 0; + +#ifdef HAVE_DOSISH_SYSTEM + int wtime = 0; + + gnupg_remove (newname); + again: + if (rename (oldname, newname)) + { + if (GetLastError () == ERROR_SHARING_VIOLATION) + { + /* Another process has the file open. We do not use a lock + * for read but instead we wait until the other process has + * closed the file. This may take long but that would also + * be the case with a dotlock approach for read and write. + * Note that we don't need this on Unix due to the inode + * concept. + * + * So let's wait until the rename has worked. We use the + * same retry intervals as used by dotlock.c, namely 50ms, + * 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s. */ + if (!wtime) + wtime = 50; + else if (wtime < 800) + wtime *= 2; + else if (wtime == 800) + wtime = 2000; + else if (wtime < 8000) + wtime *= 2; + + if (wtime >= 800) + log_info ("waiting for file '%s' to become accessible ...\n", + oldname); + + Sleep (wtime); + goto again; + } + err = gpg_error_from_syserror (); + } + +#else /* Unix */ + +#ifdef __riscos__ + gnupg_remove (newname); +#endif + if (rename (oldname, newname) ) + err = gpg_error_from_syserror (); + +#endif /* Unix */ + + if (err) + log_error ("renaming '%s' to '%s' failed: %s\n", + oldname, newname, gpg_strerror (err)); + return err; +} diff --git a/kbx/keybox.h b/kbx/keybox.h index 4d556c5..bfc3586 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -134,6 +134,7 @@ void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), gpg_error_t keybox_tmp_names (const char *filename, int for_keyring, char **r_bakname, char **r_tmpname); +gpg_error_t keybox_file_rename (const char *oldname, const char *newname); #ifdef __cplusplus commit f5cceef115f0307664956d01c48b1b397fdad4b3 Author: Werner Koch Date: Thu Jan 14 16:29:45 2016 +0100 kbx: Add function keybox_tmp_names to avoid code duplication. * kbx/keybox-update.c (create_tmp_file): Move some code to... * kbx/keybox-util.c (keybox_tmp_names): new. * g10/keyring.c: Include keybox.h. (create_tmp_file): Replace parts by keybox_tmp_names. -- Signed-off-by: Werner Koch diff --git a/g10/keyring.c b/g10/keyring.c index a0b7a0e..535dd2b 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -36,6 +36,8 @@ #include "options.h" #include "main.h" /*for check_key_signature()*/ #include "i18n.h" +#include "../kbx/keybox.h" + typedef struct keyring_resource *KR_RESOURCE; struct keyring_resource @@ -1287,69 +1289,36 @@ static int create_tmp_file (const char *template, char **r_bakfname, char **r_tmpfname, IOBUF *r_fp) { - char *bakfname, *tmpfname; + gpg_error_t err; mode_t oldmask; - *r_bakfname = NULL; - *r_tmpfname = NULL; - -# ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you can't rename("pubring.gpg.tmp", "pubring.gpg"); - * but rename("pubring.gpg.tmp", "pubring.aaa"); - * works. So we replace .gpg by .bak or .tmp - */ - if (strlen (template) > 4 - && !strcmp (template+strlen(template)-4, EXTSEP_S GPGEXT_GPG) ) - { - bakfname = xmalloc (strlen (template) + 1); - strcpy (bakfname, template); - strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak"); + err = keybox_tmp_names (template, 1, r_bakfname, r_tmpfname); + if (err) + return err; - tmpfname = xmalloc (strlen( template ) + 1 ); - strcpy (tmpfname,template); - strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp"); + /* Create the temp file with limited access. Note that the umask + call is not anymore needed because iobuf_create now takes care of + it. However, it does not harm and thus we keep it. */ + oldmask = umask (077); + if (is_secured_filename (*r_tmpfname)) + { + *r_fp = NULL; + gpg_err_set_errno (EPERM); } - else - { /* file does not end with gpg; hmmm */ - bakfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(bakfname, template), EXTSEP_S "bak"); - - tmpfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp"); + else + *r_fp = iobuf_create (*r_tmpfname, 1); + umask (oldmask); + if (!*r_fp) + { + err = gpg_error_from_syserror (); + log_error (_("can't create '%s': %s\n"), *r_tmpfname, gpg_strerror (err)); + xfree (*r_tmpfname); + *r_tmpfname = NULL; + xfree (*r_bakfname); + *r_bakfname = NULL; } -# else /* Posix file names */ - bakfname = xmalloc (strlen( template ) + 2); - strcpy (stpcpy (bakfname,template),"~"); - - tmpfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp"); -# endif /* Posix filename */ - - /* Create the temp file with limited access. Note that the umask - call is not anymore needed because iobuf_create now takes care - of it. However, it does not harm and thus we keep it. */ - oldmask=umask(077); - if (is_secured_filename (tmpfname)) - { - *r_fp = NULL; - gpg_err_set_errno (EPERM); - } - else - *r_fp = iobuf_create (tmpfname, 1); - umask(oldmask); - if (!*r_fp) - { - int rc = gpg_error_from_syserror (); - log_error(_("can't create '%s': %s\n"), tmpfname, strerror(errno) ); - xfree (tmpfname); - xfree (bakfname); - return rc; - } - *r_bakfname = bakfname; - *r_tmpfname = tmpfname; - return 0; + return err; } diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index aa80865..eebcfca 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -68,88 +68,27 @@ fseeko (FILE * stream, off_t newpos, int whence) #endif /* !defined(HAVE_FSEEKO) && !defined(fseeko) */ - static int create_tmp_file (const char *template, char **r_bakfname, char **r_tmpfname, FILE **r_fp) { - char *bakfname, *tmpfname; - - *r_bakfname = NULL; - *r_tmpfname = NULL; - -# ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you can't rename("pubring.kbx.tmp", "pubring.kbx"); - * but rename("pubring.kbx.tmp", "pubring.aaa"); - * works. So we replace ".kbx" by ".kb_" or ".k__". Note that we - * can't use ".bak" and ".tmp", because these suffixes are used by - * gpg and would lead to a sharing violation or data corruption. - */ - if (strlen (template) > 4 - && !strcmp (template+strlen(template)-4, EXTSEP_S "kbx") ) - { - bakfname = xtrymalloc (strlen (template) + 1); - if (!bakfname) - return gpg_error_from_syserror (); - strcpy (bakfname, template); - strcpy (bakfname+strlen(template)-4, EXTSEP_S "kb_"); - - tmpfname = xtrymalloc (strlen (template) + 1); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error_from_syserror (); - xfree (bakfname); - return tmperr; - } - strcpy (tmpfname,template); - strcpy (tmpfname + strlen (template)-4, EXTSEP_S "k__"); - } - else - { /* File does not end with kbx, thus we hope we are working on a - modern file system and appending a suffix works. */ - bakfname = xtrymalloc ( strlen (template) + 5); - if (!bakfname) - return gpg_error_from_syserror (); - strcpy (stpcpy (bakfname, template), EXTSEP_S "kb_"); + gpg_error_t err; - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) + err = keybox_tmp_names (template, 0, r_bakfname, r_tmpfname); + if (!err) + { + *r_fp = fopen (*r_tmpfname, "wb"); + if (!*r_fp) { - gpg_error_t tmperr = gpg_error_from_syserror (); - xfree (bakfname); - return tmperr; + err = gpg_error_from_syserror (); + xfree (*r_tmpfname); + *r_tmpfname = NULL; + xfree (*r_bakfname); + *r_bakfname = NULL; } - strcpy (stpcpy (tmpfname, template), EXTSEP_S "k__"); - } -# else /* Posix file names */ - bakfname = xtrymalloc (strlen (template) + 2); - if (!bakfname) - return gpg_error_from_syserror (); - strcpy (stpcpy (bakfname,template),"~"); - - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error_from_syserror (); - xfree (bakfname); - return tmperr; } - strcpy (stpcpy (tmpfname,template), EXTSEP_S "tmp"); -# endif /* Posix filename */ - *r_fp = fopen (tmpfname, "wb"); - if (!*r_fp) - { - gpg_error_t tmperr = gpg_error_from_syserror (); - xfree (tmpfname); - xfree (bakfname); - return tmperr; - } - - *r_bakfname = bakfname; - *r_tmpfname = tmpfname; - return 0; + return err; } diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c index 9fe9290..f7efd1a 100644 --- a/kbx/keybox-util.c +++ b/kbx/keybox-util.c @@ -68,3 +68,76 @@ _keybox_free (void *p) if (p) free_func (p); } + + +/* Store the two malloced temporary file names used for keybox updates + of file FILENAME at R_BAKNAME and R_TMPNAME. On error an error + code is returned and NULL stored at R_BAKNAME and R_TMPNAME. If + FOR_KEYRING is true the returned names match those used by GnuPG's + keyring code. */ +gpg_error_t +keybox_tmp_names (const char *filename, int for_keyring, + char **r_bakname, char **r_tmpname) +{ + gpg_error_t err; + char *bak_name, *tmp_name; + + *r_bakname = NULL; + *r_tmpname = NULL; + +# ifdef USE_ONLY_8DOT3 + /* Here is another Windoze bug?: + * you can't rename("pubring.kbx.tmp", "pubring.kbx"); + * but rename("pubring.kbx.tmp", "pubring.aaa"); + * works. So we replace ".kbx" by ".kb_" or ".k__". Note that we + * can't use ".bak" and ".tmp", because these suffixes are used by + * gpg's keyrings and would lead to a sharing violation or data + * corruption. If the name does not end in ".kbx" we assume working + * on a modern file system and append the suffix. */ + { + const char *ext = for_keyring? EXTSEP_S GPGEXT_GPG : EXTSEP_S "kbx"; + const char *b_ext = for_keyring? EXTSEP_S "bak" : EXTSEP_S "kb_"; + const char *t_ext = for_keyring? EXTSEP_S "tmp" : EXTSEP_S "k__"; + int repl; + + if (strlen (ext) != 4 || strlen (b_ext) != 4) + BUG (); + repl = (strlen (filename) > 4 + && !strcmp (filename + strlen (filename) - 4, ext)); + bak_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1); + if (!bak_name) + return gpg_error_from_syserror (); + strcpy (bak_name, filename); + strcpy (bak_name + strlen (filename) - (repl?4:0), b_ext); + + tmp_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1); + if (!tmp_name) + { + err = gpg_error_from_syserror (); + xfree (bak_name); + return err; + } + strcpy (tmp_name, filename); + strcpy (tmp_name + strlen (filename) - (repl?4:0), t_ext); + } +# else /* Posix file names */ + (void)for_keyring; + bak_name = xtrymalloc (strlen (filename) + 2); + if (!bak_name) + return gpg_error_from_syserror (); + strcpy (stpcpy (bak_name, filename), "~"); + + tmp_name = xtrymalloc (strlen (filename) + 5); + if (!tmp_name) + { + err = gpg_error_from_syserror (); + xfree (bak_name); + return err; + } + strcpy (stpcpy (tmp_name,filename), EXTSEP_S "tmp"); +# endif /* Posix filename */ + + *r_bakname = bak_name; + *r_tmpname = tmp_name; + return 0; +} diff --git a/kbx/keybox.h b/kbx/keybox.h index 3c60971..4d556c5 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -132,6 +132,9 @@ void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), void *(*new_realloc_func)(void *p, size_t n), void (*new_free_func)(void*) ); +gpg_error_t keybox_tmp_names (const char *filename, int for_keyring, + char **r_bakname, char **r_tmpname); + #ifdef __cplusplus } ----------------------------------------------------------------------- Summary of changes: g10/keydb.c | 32 ++++++++++++ g10/keyring.c | 127 ++++++++++++++++++----------------------------- kbx/keybox-init.c | 44 +++++++++++------ kbx/keybox-update.c | 102 +++++++------------------------------- kbx/keybox-util.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++ kbx/keybox.h | 4 ++ 6 files changed, 269 insertions(+), 178 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 15 08:20:46 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 15 Jan 2016 08:20:46 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-122-g3cccd5a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3cccd5a83b96e4558642dcdf5d974f64ebdb9817 (commit) from 663c5d129a8f400cc6eb8ab7b91772d6e578152d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3cccd5a83b96e4558642dcdf5d974f64ebdb9817 Author: Werner Koch Date: Fri Jan 15 08:15:40 2016 +0100 kbx,w32: Use shorter retry intervals for keybox_file_rename. * kbx/keybox-util.c (keybox_file_rename): Restart retry intervals after 800ms. -- The common use case is that the process waiting for a rename does an import while another process does a key listing with only short lock periods. Thus it does not make sense to set the final backoff time to 8s. It would actually be okay to retry every 100ms but that would spill the console with "waiting..." messages. This change prints the waiting message only every 1.5s. Signed-off-by: Werner Koch diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c index 740ea73..13fedb3 100644 --- a/kbx/keybox-util.c +++ b/kbx/keybox-util.c @@ -169,16 +169,11 @@ keybox_file_rename (const char *oldname, const char *newname) * Note that we don't need this on Unix due to the inode * concept. * - * So let's wait until the rename has worked. We use the - * same retry intervals as used by dotlock.c, namely 50ms, - * 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s. */ - if (!wtime) + * So let's wait until the rename has worked. The retry + * intervals are 50, 100, 200, 400, 800, 50ms, ... */ + if (!wtime || wtime >= 800) wtime = 50; - else if (wtime < 800) - wtime *= 2; - else if (wtime == 800) - wtime = 2000; - else if (wtime < 8000) + else wtime *= 2; if (wtime >= 800) ----------------------------------------------------------------------- Summary of changes: kbx/keybox-util.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 15 15:22:57 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 15 Jan 2016 15:22:57 +0100 Subject: [git] Assuan - branch, master, updated. libassuan-2.4.2-2-g7101fcb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via 7101fcbb662220326f2fc786219c1853f27a5298 (commit) from d271ed79fe690818b1412568417275cc92183143 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7101fcbb662220326f2fc786219c1853f27a5298 Author: Werner Koch Date: Fri Jan 15 15:17:26 2016 +0100 Improve getting of max. number of open fds. * configure.ac (AC_CHECK_FUNCS): Add getrlimit. * src/assuan-pipe-connect.c (MAX_OPEN_FDS): Remove non-used macro. * src/system.c (MAX_OPEN_FDS): Remove non-used macro. * src/system-posix.c: Include stdint.h, sys/time.h, sys/resource.h. (MAX_OPEN_FDS): Remove non-used macro. (get_max_fds): New. Taken from gnupg/common/exechelp-posix.c. (__assuan_spawn): Use it here. -- This is related to GnuPG-bug-id: 2071 Changing of get_max_fds from LPGLv3+ to LGPLv2+ approved by me as sole author or that code. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index cd1a80d..755a55c 100644 --- a/configure.ac +++ b/configure.ac @@ -360,7 +360,8 @@ AM_PATH_GPG_ERROR(1.17,, AC_MSG_ERROR([libgpg-error was not found])) # # Checks for library functions. # -AC_CHECK_FUNCS([flockfile funlockfile inet_pton stat getaddrinfo]) +AC_CHECK_FUNCS([flockfile funlockfile inet_pton stat getaddrinfo \ + getrlimit ]) # On some systems (e.g. Solaris) nanosleep requires linking to librl. # Given that we use nanosleep only as an optimization over a select diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c index edc8dbb..e5d2a38 100644 --- a/src/assuan-pipe-connect.c +++ b/src/assuan-pipe-connect.c @@ -65,13 +65,6 @@ #endif -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - /* This should be called to make sure that SIGPIPE gets ignored. */ static void fix_signals (void) diff --git a/src/system-posix.c b/src/system-posix.c index 5bdc676..8ca27e6 100644 --- a/src/system-posix.c +++ b/src/system-posix.c @@ -24,21 +24,23 @@ #include #include +#ifdef HAVE_STDINT_H +# include +#endif /* Solaris 8 needs sys/types.h before time.h. */ #include #include #include #include +#ifdef HAVE_GETRLIMIT +# include +# include +#endif /*HAVE_GETRLIMIT*/ + #include "assuan-defs.h" #include "debug.h" -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - @@ -168,6 +170,61 @@ writen (int fd, const char *buffer, size_t length) } +/* Return the maximum number of currently allowed open file + * descriptors. */ +static int +get_max_fds (void) +{ + int max_fds = -1; + +#ifdef HAVE_GETRLIMIT + struct rlimit rl; + +# ifdef RLIMIT_NOFILE + if (!getrlimit (RLIMIT_NOFILE, &rl)) + max_fds = rl.rlim_max; +# endif + +# ifdef RLIMIT_OFILE + if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl)) + max_fds = rl.rlim_max; + +# endif +#endif /*HAVE_GETRLIMIT*/ + +#ifdef _SC_OPEN_MAX + if (max_fds == -1) + { + long int scres = sysconf (_SC_OPEN_MAX); + if (scres >= 0) + max_fds = scres; + } +#endif + +#ifdef _POSIX_OPEN_MAX + if (max_fds == -1) + max_fds = _POSIX_OPEN_MAX; +#endif + +#ifdef OPEN_MAX + if (max_fds == -1) + max_fds = OPEN_MAX; +#endif + + if (max_fds == -1) + max_fds = 256; /* Arbitrary limit. */ + + /* AIX returns INT32_MAX instead of a proper value. We assume that + this is always an error and use a more reasonable limit. */ +#ifdef INT32_MAX + if (max_fds == INT32_MAX) + max_fds = 256; +#endif + + return max_fds; +} + + int __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, const char **argv, @@ -246,9 +303,7 @@ __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, /* Close all files which will not be duped and are not in the fd_child_list. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; + n = get_max_fds (); for (i = 0; i < n; i++) { if (i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO) diff --git a/src/system.c b/src/system.c index 1fca056..ddb99fb 100644 --- a/src/system.c +++ b/src/system.c @@ -36,12 +36,6 @@ #include "assuan-defs.h" #include "debug.h" -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - #define DEBUG_SYSIO 0 @@ -66,11 +60,11 @@ _assuan_calloc (assuan_context_t ctx, size_t cnt, size_t elsize) { void *ptr; size_t nbytes; - + nbytes = cnt * elsize; /* Check for overflow. */ - if (elsize && nbytes / elsize != cnt) + if (elsize && nbytes / elsize != cnt) { gpg_err_set_errno (ENOMEM); return NULL; @@ -111,7 +105,7 @@ _assuan_system_hooks_copy (assuan_system_hooks_t dst, /* Reset the defaults. */ if (dst != &_assuan_system_hooks) memcpy (dst, &_assuan_system_hooks, sizeof (*dst)); - + dst->version = ASSUAN_SYSTEM_HOOKS_VERSION; if (src->version >= 1) { @@ -164,7 +158,7 @@ _assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx) if (err) return TRACE_SYSRES (err); - return TRACE_SUC2 ("read=0x%x, write=0x%x", fd[0], fd[1]); + return TRACE_SUC2 ("read=0x%x, write=0x%x", fd[0], fd[1]); } @@ -257,7 +251,7 @@ _assuan_recvmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg, cmptr->cmsg_len - (((char *)data) - ((char *)cmptr)), cmptr->cmsg_level, cmptr->cmsg_type, *(int *)data); } - } + } return TRACE_SYSRES (res); #else return (ctx->system.recvmsg) (ctx, fd, msg, flags); @@ -280,7 +274,7 @@ _assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg, TRACE_LOG2 ("msg->iov[0] = { iov_base=%p, iov_len=%i }", msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len); TRACE_LOGBUF (msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len); - + cmptr = CMSG_FIRSTHDR (msg); if (cmptr) { @@ -358,7 +352,7 @@ _assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, /* FIXME: Add some sort of waitpid function that covers GPGME and gpg-agent's use of assuan. */ -pid_t +pid_t _assuan_waitpid (assuan_context_t ctx, pid_t pid, int action, int *status, int options) { @@ -384,7 +378,7 @@ _assuan_socketpair (assuan_context_t ctx, int namespace, int style, TRACE_BEG4 (ctx, ASSUAN_LOG_SYSIO, "_assuan_socketpair", ctx, "namespace=%i,style=%i,protocol=%i,filedes=%p", namespace, style, protocol, filedes); - + res = (ctx->system.socketpair) (ctx, namespace, style, protocol, filedes); if (res == 0) TRACE_LOG2 ("filedes = { 0x%x, 0x%x }", filedes[0], filedes[1]); @@ -401,7 +395,7 @@ _assuan_socket (assuan_context_t ctx, int namespace, int style, int protocol) TRACE_BEG3 (ctx, ASSUAN_LOG_SYSIO, "_assuan_socket", ctx, "namespace=%i,style=%i,protocol=%i", namespace, style, protocol); - + res = (ctx->system.socket) (ctx, namespace, style, protocol); return TRACE_SYSRES (res); } @@ -413,7 +407,7 @@ _assuan_connect (assuan_context_t ctx, int sock, struct sockaddr *addr, socklen_ int res; TRACE_BEG3 (ctx, ASSUAN_LOG_SYSIO, "_assuan_connect", ctx, "socket=%i,addr=%p,length=%i", sock, addr, length); - + res = (ctx->system.connect) (ctx, sock, addr, length); return TRACE_SYSRES (res); } ----------------------------------------------------------------------- Summary of changes: configure.ac | 3 +- src/assuan-pipe-connect.c | 7 ----- src/system-posix.c | 73 +++++++++++++++++++++++++++++++++++++++++------ src/system.c | 26 +++++++---------- 4 files changed, 76 insertions(+), 33 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 15 15:43:03 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 15 Jan 2016 15:43:03 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.29-20-g776bee6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via 776bee6d370602ff95e93a4aea6a70005dff9ae6 (commit) from baae8d50d74040bd5a11cd423e04a022af7691e6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 776bee6d370602ff95e93a4aea6a70005dff9ae6 Author: Werner Koch Date: Fri Jan 15 15:32:18 2016 +0100 common: Cope with AIX problem on number of open files. * common/exechelp.c: Limit returned value for too hight values. -- GnuPG-bug-id: 1778 (backport from master commit 987532b038a2d9b9e76c0de425ee036ca2bffa1b) Signed-off-by: Werner Koch diff --git a/common/exechelp.c b/common/exechelp.c index cd9ba7b..6d60b07 100644 --- a/common/exechelp.c +++ b/common/exechelp.c @@ -21,11 +21,14 @@ #include #include +#ifdef HAVE_STDINT_H +# include +#endif #include #include #include #include -#include +#include #include #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ @@ -33,7 +36,7 @@ #undef USE_GNU_PTH #endif -#ifdef USE_GNU_PTH +#ifdef USE_GNU_PTH #include #endif #ifndef HAVE_W32_SYSTEM @@ -63,7 +66,7 @@ and some are not. However we want to use pth_fork and pth_waitpid here. Using a weak symbol works but is not portable - we should provide a an explicit dummy pth module instead of using the - pragma. */ + pragma. */ #ifndef _WIN32 #pragma weak pth_fork #pragma weak pth_waitpid @@ -134,6 +137,13 @@ get_max_fds (void) if (max_fds == -1) max_fds = 256; /* Arbitrary limit. */ + /* AIX returns INT32_MAX instead of a proper value. We assume that + this is always an error and use an arbitrary limit. */ +#ifdef INT32_MAX + if (max_fds == INT32_MAX) + max_fds = 256; +#endif + return max_fds; } @@ -202,7 +212,7 @@ get_all_open_fds (void) array = calloc (narray, sizeof *array); if (!array) return NULL; - + /* Note: The list we return is ordered. */ for (idx=0, fd=0; fd < max_fd; fd++) if (!(fstat (fd, &statbuf) == -1 && errno == EBADF)) @@ -261,7 +271,7 @@ build_w32_commandline_copy (char *buffer, const char *string) /* Build a command line for use with W32's CreateProcess. On success CMDLINE gets the address of a newly allocated string. */ static gpg_error_t -build_w32_commandline (const char *pgmname, const char * const *argv, +build_w32_commandline (const char *pgmname, const char * const *argv, char **cmdline) { int i, n; @@ -289,7 +299,7 @@ build_w32_commandline (const char *pgmname, const char * const *argv, return gpg_error_from_syserror (); p = build_w32_commandline_copy (p, pgmname); - for (i=0; argv[i]; i++) + for (i=0; argv[i]; i++) { *p++ = ' '; p = build_w32_commandline_copy (p, argv[i]); @@ -312,7 +322,7 @@ create_inheritable_pipe (int filedes[2]) memset (&sec_attr, 0, sizeof sec_attr ); sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; - + if (!CreatePipe (&r, &w, &sec_attr, 0)) return -1; @@ -404,7 +414,7 @@ do_exec (const char *pgmname, const char *argv[], /* Close all other files. */ close_all_fds (3, NULL); - + if (preexec) preexec (); execv (pgmname, arg_list); @@ -433,7 +443,7 @@ gnupg_create_inbound_pipe (int filedes[2]) log_error ("failed to translate osfhandle %p\n", (void*)fds[0]); CloseHandle (fd_to_handle (fds[1])); } - else + else { filedes[1] = _open_osfhandle (fds[1], 1); if (filedes[1] == -1) @@ -472,7 +482,7 @@ gnupg_create_inbound_pipe (int filedes[2]) This flag is only useful under W32 systems, so that no new console is created and pops up a console window when starting the server - + Bit 6: On W32 run AllowSetForegroundWindow for the child. Due to error problems this actually allows SetForegroundWindow for childs of this process. @@ -487,7 +497,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], #ifdef HAVE_W32_SYSTEM gpg_error_t err; SECURITY_ATTRIBUTES sec_attr; - PROCESS_INFORMATION pi = + PROCESS_INFORMATION pi = { NULL, /* Returns process handle. */ 0, /* Returns primary thread handle. */ @@ -515,11 +525,11 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], memset (&sec_attr, 0, sizeof sec_attr ); sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; - + /* Build the command line. */ err = build_w32_commandline (pgmname, argv, &cmdline); if (err) - return err; + return err; /* Create a pipe. */ if (create_inheritable_pipe (rp)) @@ -529,7 +539,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], xfree (cmdline); return err; } - + /* Start the process. Note that we can't run the PREEXEC function because this would change our own environment. */ memset (&si, 0, sizeof si); @@ -543,7 +553,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], cr_flags = (CREATE_DEFAULT_ERROR_MODE | ((flags & 128)? DETACHED_PROCESS : 0) | GetPriorityClass (GetCurrentProcess ()) - | CREATE_SUSPENDED); + | CREATE_SUSPENDED); /* log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */ if (!CreateProcess (pgmname, /* Program to start. */ cmdline, /* Command line arguments. */ @@ -568,12 +578,12 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], /* Close the other end of the pipe. */ CloseHandle (fd_to_handle (rp[1])); - + /* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ /* " dwProcessID=%d dwThreadId=%d\n", */ /* pi.hProcess, pi.hThread, */ /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - + /* Fixme: For unknown reasons AllowSetForegroundWindow returns an invalid argument error if we pass the correct processID to it. As a workaround we use -1 (ASFW_ANY). */ @@ -582,7 +592,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); - CloseHandle (pi.hThread); + CloseHandle (pi.hThread); { int x; @@ -590,7 +600,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], x = _open_osfhandle (rp[0], 0); if (x == -1) log_error ("failed to translate osfhandle %p\n", (void*)rp[0] ); - else + else *statusfile = fdopen (x, "r"); } if (!*statusfile) @@ -626,7 +636,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], return err; } -#ifdef USE_GNU_PTH +#ifdef USE_GNU_PTH *pid = pth_fork? pth_fork () : fork (); #else *pid = fork (); @@ -641,7 +651,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], } if (!*pid) - { + { gcry_control (GCRYCTL_TERM_SECMEM); /* Run child. */ do_exec (pgmname, argv, fd, fdout, rp[1], preexec); @@ -695,11 +705,11 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], memset (&sec_attr, 0, sizeof sec_attr ); sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; - + /* Build the command line. */ err = build_w32_commandline (pgmname, argv, &cmdline); if (err) - return err; + return err; memset (&si, 0, sizeof si); si.cb = sizeof (si); @@ -746,7 +756,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); - CloseHandle (pi.hThread); + CloseHandle (pi.hThread); *pid = handle_to_pid (pi.hProcess); return 0; @@ -754,7 +764,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], #else /* !HAVE_W32_SYSTEM */ gpg_error_t err; -#ifdef USE_GNU_PTH +#ifdef USE_GNU_PTH *pid = pth_fork? pth_fork () : fork (); #else *pid = fork (); @@ -767,7 +777,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], } if (!*pid) - { + { gcry_control (GCRYCTL_TERM_SECMEM); /* Run child. */ do_exec (pgmname, argv, infd, outfd, errfd, NULL); @@ -805,7 +815,7 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode) been implemented. A special W32 pth system call would even be better. */ code = WaitForSingleObject (proc, INFINITE); - switch (code) + switch (code) { case WAIT_FAILED: log_error (_("waiting for process %d to terminate failed: %s\n"), @@ -872,7 +882,7 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode) } else if (WIFEXITED (status) && WEXITSTATUS (status)) { - + if (!exitcode) log_error (_("error running `%s': exit status %d\n"), pgmname, WEXITSTATUS (status)); @@ -885,7 +895,7 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode) log_error (_("error running `%s': terminated\n"), pgmname); ec = GPG_ERR_GENERAL; } - else + else { if (exitcode) *exitcode = 0; @@ -911,7 +921,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], #ifdef HAVE_W32_SYSTEM gpg_error_t err; SECURITY_ATTRIBUTES sec_attr; - PROCESS_INFORMATION pi = + PROCESS_INFORMATION pi = { NULL, /* Returns process handle. */ 0, /* Returns primary thread handle. */ @@ -936,11 +946,11 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], memset (&sec_attr, 0, sizeof sec_attr ); sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; - + /* Build the command line. */ err = build_w32_commandline (pgmname, argv, &cmdline); if (err) - return err; + return err; /* Start the process. */ memset (&si, 0, sizeof si); @@ -951,7 +961,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], cr_flags = (CREATE_DEFAULT_ERROR_MODE | GetPriorityClass (GetCurrentProcess ()) | CREATE_NEW_PROCESS_GROUP - | DETACHED_PROCESS); + | DETACHED_PROCESS); /* log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", */ /* pgmname, cmdline); */ if (!CreateProcess (pgmname, /* Program to start. */ @@ -978,7 +988,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], /* pi.hProcess, pi.hThread, */ /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - CloseHandle (pi.hThread); + CloseHandle (pi.hThread); return 0; @@ -992,7 +1002,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], if (access (pgmname, X_OK)) return gpg_error_from_syserror (); -#ifdef USE_GNU_PTH +#ifdef USE_GNU_PTH pid = pth_fork? pth_fork () : fork (); #else pid = fork (); @@ -1004,7 +1014,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], } if (!pid) { - pid_t pid2; + pid_t pid2; gcry_control (GCRYCTL_TERM_SECMEM); if (setsid() == -1 || chdir ("/")) @@ -1018,12 +1028,12 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], if (envp) for (i=0; envp[i]; i++) putenv (xstrdup (envp[i])); - + do_exec (pgmname, argv, -1, -1, -1, NULL); /*NOTREACHED*/ } - + if (waitpid (pid, NULL, 0) == -1) log_error ("waitpid failed in gnupg_spawn_process_detached: %s", strerror (errno)); ----------------------------------------------------------------------- Summary of changes: common/exechelp.c | 86 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 38 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 15 15:57:14 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 15 Jan 2016 15:57:14 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-4-ga38dffd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via a38dffde7b19bd4881afcd87c23aac2daa5bd52a (commit) from e26706700f6f339891cce924e2a401dfbdba1a0e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a38dffde7b19bd4881afcd87c23aac2daa5bd52a Author: Werner Koch Date: Fri Jan 15 15:51:37 2016 +0100 Fix possible AIX problem with sysconf in rndunix. * cipher/rndunix.c [HAVE_STDINT_H]: Include stdint.h. (start_gatherer): Detect misbehaving sysconf. -- See GnuPG-bug-id: 1778 for the reason of this patch. There is no concrete bug report but this chnage should not harm. Signed-off-by: Werner Koch diff --git a/cipher/rndunix.c b/cipher/rndunix.c index 72905e6..5cf2b9e 100644 --- a/cipher/rndunix.c +++ b/cipher/rndunix.c @@ -50,6 +50,9 @@ #include #include #include +#ifdef HAVE_STDINT_H +# include +#endif #include #include @@ -700,12 +703,18 @@ start_gatherer( int pipefd ) { int nmax, n1, i; #ifdef _SC_OPEN_MAX if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) { -#ifdef _POSIX_OPEN_MAX +# ifdef _POSIX_OPEN_MAX nmax = _POSIX_OPEN_MAX; -#else +# else nmax = 20; /* assume a reasonable value */ -#endif +# endif } + /* AIX returns INT32_MAX instead of a proper value. We assume that + * this is always an error and use a reasonable value. */ +# ifdef INT32_MAX + if (nmax == INT32_MAX) + nmax = 20; +# endif #else nmax = 20; /* assume a reasonable value */ #endif ----------------------------------------------------------------------- Summary of changes: cipher/rndunix.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 15 16:19:04 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 15 Jan 2016 16:19:04 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-302-g191c2e4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 191c2e4fe2dc0e00f61aa44e011a9596887e6ce1 (commit) via 6303b0e83856ee89374b447e710f0ab2af61caec (commit) from 5a78e7f15e0dd96a8bf64e2bb142880bf8ea6965 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 191c2e4fe2dc0e00f61aa44e011a9596887e6ce1 Author: Werner Koch Date: Fri Jan 15 16:10:34 2016 +0100 Fix build problem for rndegd.c * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Test all RND modules. * random/rndegd.c (_gcry_rndegd_connect_socket) (my_make_filename): Use functions with '_' prefix. Signed-off-by: Werner Koch diff --git a/Makefile.am b/Makefile.am index 4c2c509..2e7abc4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,7 +18,8 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ACLOCAL_AMFLAGS = -I m4 -DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon --enable-doc +DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon --enable-doc \ + --enable-random=auto # (A suitable gitlog-to-changelog script can be found in GnuPG master.) GITLOG_TO_CHANGELOG=gitlog-to-changelog diff --git a/random/rndegd.c b/random/rndegd.c index d43fcbc..b87115f 100644 --- a/random/rndegd.c +++ b/random/rndegd.c @@ -62,7 +62,7 @@ my_make_filename (const char *first_part, const char *second_part) && (home = getenv("HOME")) && *home ) n += strlen(home); - name = gcry_xmalloc(n); + name = _gcry_xmalloc(n); p = (home ? stpcpy (stpcpy (name, home), first_part+1 ) : stpcpy (name, first_part) ); @@ -161,7 +161,7 @@ _gcry_rndegd_connect_socket (int nofail) #endif if (user_socket_name) { - name = gcry_strdup (user_socket_name); + name = _gcry_strdup (user_socket_name); if (!name) { if (!nofail) commit 6303b0e83856ee89374b447e710f0ab2af61caec Author: Werner Koch Date: Fri Jan 15 16:01:35 2016 +0100 random: Fix possible AIX problem with sysconf in rndunix. * random/rndunix.c [HAVE_STDINT_H]: Include stdint.h. (start_gatherer): Detect misbehaving sysconf. -- See GnuPG-bug-id: 1778 for the reason of this patch. There is no concrete bug report but this change should not harm. Signed-off-by: Werner Koch diff --git a/random/rndunix.c b/random/rndunix.c index 315906b..2e13298 100644 --- a/random/rndunix.c +++ b/random/rndunix.c @@ -86,6 +86,9 @@ #include #include #include +#ifdef HAVE_STDINT_H +# include +#endif #include /* OS-specific includes */ @@ -726,12 +729,18 @@ start_gatherer( int pipefd ) { int nmax, n1, n2, i; #ifdef _SC_OPEN_MAX if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) { -#ifdef _POSIX_OPEN_MAX +# ifdef _POSIX_OPEN_MAX nmax = _POSIX_OPEN_MAX; -#else +# else nmax = 20; /* assume a reasonable value */ -#endif +# endif } + /* AIX returns INT32_MAX instead of a proper value. We assume that + * this is always an error and use a reasonable value. */ +# ifdef INT32_MAX + if (nmax == INT32_MAX) + nmax = 20; +# endif #else /*!_SC_OPEN_MAX*/ nmax = 20; /* assume a reasonable value */ #endif /*!_SC_OPEN_MAX*/ ----------------------------------------------------------------------- Summary of changes: Makefile.am | 3 ++- random/rndegd.c | 4 ++-- random/rndunix.c | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 15 16:21:22 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 15 Jan 2016 16:21:22 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.6.0-13-ge791994 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via e79199468ac54ce4fe919603ff7bada97267174f (commit) from 83415dffaea53611dbce77b50d8ddfb2a50aed2e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e79199468ac54ce4fe919603ff7bada97267174f Author: Werner Koch Date: Fri Jan 15 16:16:38 2016 +0100 Fix possible _SC_OPEN_MAX max problem on AIX. * src/posix-io.c [HAVE_STDINT_H]: Include stdint.h. (get_max_fds): Limit returned value for too high values. -- Signed-off-by: Werner Koch diff --git a/src/posix-io.c b/src/posix-io.c index ac823fc..e49c71e 100644 --- a/src/posix-io.c +++ b/src/posix-io.c @@ -23,6 +23,9 @@ #endif #include #include +#ifdef HAVE_STDINT_H +# include +#endif #include #include #include @@ -331,6 +334,16 @@ get_max_fds (void) fds = 1024; } + /* AIX returns INT32_MAX instead of a proper value. We assume that + * this is always an error and use a more reasonable limit. */ +#ifdef INT32_MAX + if (fds == INT32_MAX) + { + source = "aix-fix"; + fds = 1024; + } +#endif + TRACE2 (DEBUG_SYSIO, "gpgme:max_fds", 0, "max fds=%i (%s)", fds, source); return fds; } ----------------------------------------------------------------------- Summary of changes: src/posix-io.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 18 09:10:47 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Jan 2016 09:10:47 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-123-g56275e4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 56275e4392a7b38abe5fdd84fe9d67599cf5e6d1 (commit) from 3cccd5a83b96e4558642dcdf5d974f64ebdb9817 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 56275e4392a7b38abe5fdd84fe9d67599cf5e6d1 Author: Werner Koch Date: Mon Jan 18 08:33:55 2016 +0100 doc: Fix description of --s2k-* options to match gpg 2.1. -- GnuPG-bug-id: 2220 diff --git a/doc/gpg.texi b/doc/gpg.texi index 4a70856..e0374d4 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -185,7 +185,7 @@ passphrase). @item --store @opindex store -Store only (make a simple RFC1991 literal data packet). +Store only (make a simple literal data packet). @item --decrypt @itemx -d @@ -2268,33 +2268,32 @@ to consider (e.g. @option{--symmetric}). @item --s2k-cipher-algo @code{name} @opindex s2k-cipher-algo -Use @code{name} as the cipher algorithm used to protect secret keys. -The default cipher is @value{GPGSYMENCALGO}. This cipher is also used -for symmetric encryption with a passphrase if - at option{--personal-cipher-preferences} and @option{--cipher-algo} is -not given. +Use @code{name} as the cipher algorithm for symmetric encryption with +a passphrase if @option{--personal-cipher-preferences} and + at option{--cipher-algo} are not given. The default is @value{GPGSYMENCALGO}. @item --s2k-digest-algo @code{name} @opindex s2k-digest-algo -Use @code{name} as the digest algorithm used to mangle the passphrases. -The default algorithm is SHA-1. +Use @code{name} as the digest algorithm used to mangle the passphrases +for symmetric encryption. The defaulte is SHA-1. @item --s2k-mode @code{n} @opindex s2k-mode -Selects how passphrases are mangled. If @code{n} is 0 a plain -passphrase (which is not recommended) will be used, a 1 adds a salt to -the passphrase and a 3 (the default) iterates the whole process a -number of times (see --s2k-count). Unless @option{--rfc1991} is used, -this mode is also used for symmetric encryption with a passphrase. +Selects how passphrases for symmetric encryption are mangled. If + at code{n} is 0 a plain passphrase (which is in general not recommended) +will be used, a 1 adds a salt (which should not be used) to the +passphrase and a 3 (the default) iterates the whole process a number +of times (see @option{--s2k-count}). @item --s2k-count @code{n} @opindex s2k-count -Specify how many times the passphrase mangling is repeated. This -value may range between 1024 and 65011712 inclusive. The default is -inquired from gpg-agent. Note that not all values in the -1024-65011712 range are legal and if an illegal value is selected, -GnuPG will round up to the nearest legal value. This option is only -meaningful if @option{--s2k-mode} is 3. +Specify how many times the passphrases mangling for symmetric +encryption is repeated. This value may range between 1024 and +65011712 inclusive. The default is inquired from gpg-agent. Note +that not all values in the 1024-65011712 range are legal and if an +illegal value is selected, GnuPG will round up to the nearest legal +value. This option is only meaningful if @option{--s2k-mode} is set +to the default of 3. @end table @@ -2340,32 +2339,6 @@ behavior. Note that this is currently the same thing as Reset all packet, cipher and digest options to strict RFC-2440 behavior. - at ifclear gpgtowone - at item --rfc1991 - at opindex rfc1991 -Try to be more RFC-1991 (PGP 2.x) compliant. This option is -deprecated will be removed in GnuPG 2.1. - - at item --pgp2 - at opindex pgp2 -Set up all options to be as PGP 2.x compliant as possible, and warn if -an action is taken (e.g. encrypting to a non-RSA key) that will create -a message that PGP 2.x will not be able to handle. Note that `PGP -2.x' here means `MIT PGP 2.6.2'. There are other versions of PGP 2.x -available, but the MIT release is a good common baseline. - -This option implies - at option{--rfc1991 --disable-mdc --no-force-v4-certs - --escape-from-lines --force-v3-sigs --allow-weak-digest-algos - --cipher-algo IDEA --digest-algo MD5 --compress-algo ZIP}. -It also disables @option{--textmode} when encrypting. - -This option is deprecated will be removed in GnuPG 2.1. The reason -for dropping PGP-2 support is that the PGP 2 format is not anymore -considered safe (for example due to the use of the broken MD5 algorithm). -Note that the decryption of PGP-2 created messages will continue to work. - at end ifclear - @item --pgp6 @opindex pgp6 Set up all options to be as PGP 6 compliant as possible. This ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 63 +++++++++++++++++------------------------------------------- 1 file changed, 18 insertions(+), 45 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 18 11:43:29 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Jan 2016 11:43:29 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-125-g9309bda Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 9309bda9581715d304305c8c5116f2cbb31aec77 (commit) via 437965e5622612941ed0fa55584811c65069242e (commit) from 56275e4392a7b38abe5fdd84fe9d67599cf5e6d1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9309bda9581715d304305c8c5116f2cbb31aec77 Author: Werner Koch Date: Mon Jan 18 11:35:26 2016 +0100 gpg: Use "days" in "...newer than..." diagnostics. * g10/sig-check.c (check_signature_metadata_validity): Use days if useful. -- Using days instead of a high number of seconds is for the majority of users a better measurement. Signed-off-by: Werner Koch diff --git a/g10/sig-check.c b/g10/sig-check.c index 8f976ba..292adb9 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -268,10 +268,23 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig, if( pk->timestamp > sig->timestamp ) { ulong d = pk->timestamp - sig->timestamp; - log_info - (ngettext("public key %s is %lu second newer than the signature\n", - "public key %s is %lu seconds newer than the signature\n", - d), keystr_from_pk (pk), d); + if ( d < 86400 ) + { + log_info + (ngettext + ("public key %s is %lu second newer than the signature\n", + "public key %s is %lu seconds newer than the signature\n", + d), keystr_from_pk (pk), d); + } + else + { + d /= 86400; + log_info + (ngettext + ("public key %s is %lu day newer than the signature\n", + "public key %s is %lu days newer than the signature\n", + d), keystr_from_pk (pk), d); + } if (!opt.ignore_time_conflict) return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature. */ } @@ -280,12 +293,24 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig, if( pk->timestamp > cur_time ) { ulong d = pk->timestamp - cur_time; - log_info (ngettext("key %s was created %lu second" - " in the future (time warp or clock problem)\n", - "key %s was created %lu seconds" - " in the future (time warp or clock problem)\n", - d), keystr_from_pk (pk), d); - if( !opt.ignore_time_conflict ) + if (d < 86400) + { + log_info (ngettext("key %s was created %lu second" + " in the future (time warp or clock problem)\n", + "key %s was created %lu seconds" + " in the future (time warp or clock problem)\n", + d), keystr_from_pk (pk), d); + } + else + { + d /= 86400; + log_info (ngettext("key %s was created %lu day" + " in the future (time warp or clock problem)\n", + "key %s was created %lu days" + " in the future (time warp or clock problem)\n", + d), keystr_from_pk (pk), d); + } + if (!opt.ignore_time_conflict) return GPG_ERR_TIME_CONFLICT; } commit 437965e5622612941ed0fa55584811c65069242e Author: Werner Koch Date: Mon Jan 18 11:20:15 2016 +0100 Use ngettext for some strings. * scd/app-openpgp.c (build_enter_admin_pin_prompt): Use ngettext for some diagnostics. (do_genkey): Ditto. * g10/keyedit.c (check_all_keysigs, menu_delsig, menu_clean): Ditto. * g10/keylist.c (print_signature_stats): Ditto. * g10/keyserver.c (keyserver_refresh): Ditto. * g10/sig-check.c (check_signature_metadata_validity): Ditto. * g10/sign.c (do_sign): Ditto. * g10/trustdb.c (reset_trust_records): Ditto. (validate_keys): Use a table like diagnostic output. -- Suggested-by: Ineiev Signed-off-by: Werner Koch diff --git a/g10/keyedit.c b/g10/keyedit.c index 497fd1b..30f52a4 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -382,23 +382,25 @@ check_all_keysigs (KBNODE keyblock, int only_selected, int only_selfsigs) } if (!has_selfsig) mis_selfsig++; - if (inv_sigs == 1) - tty_printf (_("1 bad signature\n")); - else if (inv_sigs) - tty_printf (_("%d bad signatures\n"), inv_sigs); - if (no_key == 1) - tty_printf (_("1 signature not checked due to a missing key\n")); - else if (no_key) - tty_printf (_("%d signatures not checked due to missing keys\n"), no_key); - if (oth_err == 1) - tty_printf (_("1 signature not checked due to an error\n")); - else if (oth_err) - tty_printf (_("%d signatures not checked due to errors\n"), oth_err); - if (mis_selfsig == 1) - tty_printf (_("1 user ID without valid self-signature detected\n")); - else if (mis_selfsig) - tty_printf (_("%d user IDs without valid self-signatures detected\n"), - mis_selfsig); + + if (inv_sigs) + tty_printf (ngettext("%d bad signature\n", + "%d bad signatures\n", inv_sigs), inv_sigs); + + if (no_key) + tty_printf (ngettext("%d signature not checked due to a missing key\n", + "%d signatures not checked due to missing keys\n", + no_key), no_key); + + if (oth_err) + tty_printf (ngettext("%d signature not checked due to an error\n", + "%d signatures not checked due to errors\n", + oth_err), oth_err); + + if (mis_selfsig) + tty_printf (ngettext("%d user ID without valid self-signature detected\n", + "%d user IDs without valid self-signatures detected\n", + mis_selfsig), mis_selfsig); return inv_sigs || no_key || oth_err || mis_selfsig; } @@ -3722,8 +3724,8 @@ menu_delsig (KBNODE pub_keyblock) if (changed) { commit_kbnode (&pub_keyblock); - tty_printf (changed == 1 ? _("Deleted %d signature.\n") - : _("Deleted %d signatures.\n"), changed); + tty_printf (ngettext("Deleted %d signature.\n", + "Deleted %d signatures.\n", changed), changed); } else tty_printf (_("Nothing deleted.\n")); @@ -3769,11 +3771,9 @@ menu_clean (KBNODE keyblock, int self_only) } else if (sigs) { - tty_printf (sigs == 1 ? - _("User ID \"%s\": %d signature removed\n") : - _("User ID \"%s\": %d signatures removed\n"), - user, sigs); - + tty_printf (ngettext("User ID \"%s\": %d signature removed\n", + "User ID \"%s\": %d signatures removed\n", + sigs), user, sigs); modified = 1; } else diff --git a/g10/keylist.c b/g10/keylist.c index b2836e8..d71bf4f 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -464,25 +464,23 @@ print_signature_stats (struct keylist_context *s) if (!s->check_sigs) return; /* Signature checking was not requested. */ - if (s->good_sigs == 1) - log_info (_("1 good signature\n")); - else if (s->good_sigs) - log_info (_("%d good signatures\n"), s->good_sigs); - - if (s->inv_sigs == 1) - log_info (_("1 bad signature\n")); - else if (s->inv_sigs) - log_info (_("%d bad signatures\n"), s->inv_sigs); - - if (s->no_key == 1) - log_info (_("1 signature not checked due to a missing key\n")); - else if (s->no_key) - log_info (_("%d signatures not checked due to missing keys\n"), s->no_key); - - if (s->oth_err == 1) - log_info (_("1 signature not checked due to an error\n")); - else if (s->oth_err) - log_info (_("%d signatures not checked due to errors\n"), s->oth_err); + if (s->good_sigs) + log_info (ngettext("%d good signature\n", + "%d good signatures\n", s->good_sigs), s->good_sigs); + + if (s->inv_sigs) + log_info (ngettext("%d bad signature\n", + "%d bad signatures\n", s->inv_sigs), s->inv_sigs); + + if (s->no_key) + log_info (ngettext("%d signature not checked due to a missing key\n", + "%d signatures not checked due to missing keys\n", + s->no_key), s->no_key); + + if (s->oth_err) + log_info (ngettext("%d signature not checked due to an error\n", + "%d signatures not checked due to errors\n", + s->oth_err), s->oth_err); } @@ -562,7 +560,9 @@ list_all (ctrl_t ctrl, int secret, int mark_secret) if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); if (keydb_get_skipped_counter (hd)) - log_info (_("Warning: %lu key(s) skipped due to their large size\n"), + log_info (ngettext("Warning: %lu key skipped due to its large size\n", + "Warning: %lu keys skipped due to their large sizes\n", + keydb_get_skipped_counter (hd)), keydb_get_skipped_counter (hd)); if (opt.check_sigs && !opt.with_colons) diff --git a/g10/keyring.c b/g10/keyring.c index ca9a698..7c7b355 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1564,8 +1564,10 @@ keyring_rebuild_cache (void *token,int noisy) goto leave; if ( !(++count % 50) && noisy && !opt.quiet) - log_info(_("%lu keys cached so far (%lu signatures)\n"), - count, sigcount ); + log_info (ngettext("%lu keys cached so far (%lu signature)\n", + "%lu keys cached so far (%lu signatures)\n", + sigcount), + count, sigcount); } } /* end main loop */ if (rc == -1) @@ -1575,8 +1577,15 @@ keyring_rebuild_cache (void *token,int noisy) log_error ("keyring_search failed: %s\n", gpg_strerror (rc)); goto leave; } - if(noisy || opt.verbose) - log_info(_("%lu keys cached (%lu signatures)\n"), count, sigcount ); + + if (noisy || opt.verbose) + { + log_info (ngettext("%lu key cached", + "%lu keys cached", count), count); + log_printf (ngettext(" (%lu signature)\n", + " (%lu signatures)\n", sigcount), sigcount); + } + if (tmpfp) { if (iobuf_close (tmpfp)) diff --git a/g10/keyserver.c b/g10/keyserver.c index bb7c105..b0af63d 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1403,7 +1403,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users) struct keyserver_spec *keyserver=desc[i].skipfncvalue; if (!opt.quiet) - log_info (_("refreshing 1 key from %s\n"), keyserver->uri); + log_info (_("refreshing %d key from %s\n"), 1, keyserver->uri); /* We use the keyserver structure we parsed out before. Note that a preferred keyserver without a scheme:// @@ -1436,10 +1436,9 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users) { if (!opt.quiet) { - if(count==1) - log_info(_("refreshing 1 key from %s\n"), tmpuri); - else - log_info(_("refreshing %d keys from %s\n"), count, tmpuri); + log_info (ngettext("refreshing %d key from %s\n", + "refreshing %d keys from %s\n", + count), count, tmpuri); } xfree (tmpuri); diff --git a/g10/sig-check.c b/g10/sig-check.c index bcf46f8..8f976ba 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -268,11 +268,11 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig, if( pk->timestamp > sig->timestamp ) { ulong d = pk->timestamp - sig->timestamp; - log_info(d==1 - ?_("public key %s is %lu second newer than the signature\n") - :_("public key %s is %lu seconds newer than the signature\n"), - keystr_from_pk(pk),d ); - if( !opt.ignore_time_conflict ) + log_info + (ngettext("public key %s is %lu second newer than the signature\n", + "public key %s is %lu seconds newer than the signature\n", + d), keystr_from_pk (pk), d); + if (!opt.ignore_time_conflict) return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature. */ } @@ -280,12 +280,11 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig, if( pk->timestamp > cur_time ) { ulong d = pk->timestamp - cur_time; - log_info( d==1 - ? _("key %s was created %lu second" - " in the future (time warp or clock problem)\n") - : _("key %s was created %lu seconds" - " in the future (time warp or clock problem)\n"), - keystr_from_pk(pk),d ); + log_info (ngettext("key %s was created %lu second" + " in the future (time warp or clock problem)\n", + "key %s was created %lu seconds" + " in the future (time warp or clock problem)\n", + d), keystr_from_pk (pk), d); if( !opt.ignore_time_conflict ) return GPG_ERR_TIME_CONFLICT; } diff --git a/g10/sign.c b/g10/sign.c index 081bd99..c3ae028 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -235,15 +235,15 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig, if (pksk->timestamp > sig->timestamp ) { ulong d = pksk->timestamp - sig->timestamp; - log_info (d==1 ? _("key has been created %lu second " - "in future (time warp or clock problem)\n") - : _("key has been created %lu seconds " - "in future (time warp or clock problem)\n"), d ); + log_info (ngettext("key %s was created %lu second" + " in the future (time warp or clock problem)\n", + "key %s was created %lu seconds" + " in the future (time warp or clock problem)\n", + d), keystr_from_pk (pksk), d); if (!opt.ignore_time_conflict) return gpg_error (GPG_ERR_TIME_CONFLICT); } - print_pubkey_algo_note (pksk->pubkey_algo); if (!mdalgo) diff --git a/g10/trustdb.c b/g10/trustdb.c index cb2b5b9..d3a186f 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1842,8 +1842,14 @@ reset_trust_records(void) } if (opt.verbose) - log_info (_("%d keys processed (%d validity counts cleared)\n"), - count, nreset); + { + log_info (ngettext("%d key processed", + "%d keys processed", + count), count); + log_printf (ngettext(" (%d validity count cleared)\n", + " (%d validity counts cleared)\n", + nreset), nreset); + } } /* @@ -1952,8 +1958,8 @@ validate_keys (int interactive) klist = utk_list; - log_info(_("%d marginal(s) needed, %d complete(s) needed, %s trust model\n"), - opt.marginals_needed,opt.completes_needed,trust_model_string()); + log_info ("marginals needed: %d completes needed: %d trust model: %s\n", + opt.marginals_needed, opt.completes_needed, trust_model_string ()); for (depth=0; depth < opt.max_cert_depth; depth++) { diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 92330ec..7dd1566 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1874,8 +1874,11 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt) remaining = value[6]; xfree (relptr); - log_info(_("%d Admin PIN attempts remaining before card" - " is permanently locked\n"), remaining); + log_info (ngettext("%d Admin PIN attempt remaining before card" + " is permanently locked\n", + "%d Admin PIN attempts remaining before card" + " is permanently locked\n", + remaining), remaining); if (remaining < 3) { @@ -3587,8 +3590,13 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, log_error (_("generating key failed\n")); goto leave; } - log_info (_("key generation completed (%d seconds)\n"), - (int)(time (NULL) - start_at)); + + { + int nsecs = (int)(time (NULL) - start_at); + log_info (ngettext("key generation completed (%d second)\n", + "key generation completed (%d seconds)\n", + nsecs), nsecs); + } keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); if (!keydata) ----------------------------------------------------------------------- Summary of changes: g10/keyedit.c | 48 ++++++++++++++++++++++++------------------------ g10/keylist.c | 40 ++++++++++++++++++++-------------------- g10/keyring.c | 17 +++++++++++++---- g10/keyserver.c | 9 ++++----- g10/sig-check.c | 48 ++++++++++++++++++++++++++++++++++++------------ g10/sign.c | 10 +++++----- g10/trustdb.c | 14 ++++++++++---- scd/app-openpgp.c | 16 ++++++++++++---- 8 files changed, 124 insertions(+), 78 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 18 11:49:29 2016 From: cvs at cvs.gnupg.org (by Oleg Gurevich) Date: Mon, 18 Jan 2016 11:49:29 +0100 Subject: [git] Scute - branch, master, updated. scute-1.3.0-51-g086b72a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PKCS#11 token on top of gpg-agent". The branch, master has been updated via 086b72ab07016778fea1ffeb8e5cc340d2116f6a (commit) from 4983f77cfbc810795f24e7452363413597bbe2e4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 086b72ab07016778fea1ffeb8e5cc340d2116f6a Author: Oleg Gurevich Date: Mon Jan 18 11:39:07 2016 +0100 Set configure options for cross-compilation. * autogen.rc: Set configure options for cross-compilation based on 'myhost'. Signed-off-by: Justus Winter diff --git a/autogen.rc b/autogen.rc index 881f658..f5856c8 100644 --- a/autogen.rc +++ b/autogen.rc @@ -1,4 +1,19 @@ # autogen.sh configuration for Scute -*- sh -*- +case "$myhost" in + w32) + configure_opts=" + --with-gpg-error-prefix=@SYSROOT@ + --with-libassuan-prefix=@SYSROOT@ + " + ;; + + amd64) + configure_opts=" + --with-gpg-error-prefix=@SYSROOT@ + --with-libassuan-prefix=@SYSROOT@ + " + ;; +esac extra_aclocal_flags="" final_info="./configure --enable-maintainer-mode && make" ----------------------------------------------------------------------- Summary of changes: autogen.rc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 18 17:57:43 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Jan 2016 17:57:43 +0100 Subject: [git] gnupg-doc - branch, master, updated. 398b0954d0ab932603ba470b07ef8424dbf22c39 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 398b0954d0ab932603ba470b07ef8424dbf22c39 (commit) via 1dd86025940fc4230e277a4a57798f58c93056c8 (commit) from e5c4f51a719b92c0d96744b1fc24531034dc6f89 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 398b0954d0ab932603ba470b07ef8424dbf22c39 Author: Werner Koch Date: Mon Jan 18 17:52:30 2016 +0100 web: Remove soon to be decommissioned sunet mirrors. diff --git a/web/download/mirrors.org b/web/download/mirrors.org index 6dec2b0..5075dbc 100644 --- a/web/download/mirrors.org +++ b/web/download/mirrors.org @@ -39,7 +39,6 @@ web site mirrors, please consult the [[../mirrors.html][WWW mirror page]] . | | [[http://www.surfnet.nl/][SurfNet]] | [[ftp://ftp.surfnet.nl/pub/security/gnupg/][ftp]] | | | Portugal | [[http://5coluna.com][5? Coluna]] | [[http://dist.gnupg.pt/][http]] | 2/day | | Romania | [[http://www.iasi.roedu.net/][Romanian Edu., Iasi Branch]] | [[ftp://ftp.iasi.roedu.net/pub/mirrors/ftp.gnupg.org/][ftp]] | | - | Sweden | [[http://archive.sunet.se/][Sunet]] | [[ftp://ftp.sunet.se/pub/security/gnupg/][ftp]] | | | Switzerland | [[http://mirror.switch.ch/][SWITCHmirror]] | [[ftp://mirror.switch.ch/mirror/gnupg/][ftp]] | | | United Kingdom | [[http://gnupg.org.favoritelinks.net/][favoritelinks]] | [[http://gnupg.org.favoritelinks.net/][http]] | daily | | | [[http://mirror.tje.me.uk/][mirror.tje.me.uk]] | [[ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org][ftp]] [[http://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/][http]] | 4/day | diff --git a/web/mirrors.org b/web/mirrors.org index 87633c5..99d7727 100644 --- a/web/mirrors.org +++ b/web/mirrors.org @@ -34,7 +34,6 @@ are seeking mirrors for source or binary packages, please consult the | France | [[http://mirror.cict.fr/][CICT Mirror, Toulouse]] | [[http://gnupg.cict.fr/][http]] | daily | | Hungary | [[http://www.crysys.hu/][CrySyS Lab., Bute]] | [[http://gnupg.mirrors.crysys.hu/][http]] | daily | | Portugal | [[http://5coluna.com][5? Coluna]] | [[http://mirror.gnupg.pt/][http]] | 2/day | - | Sweden | [[http://archive.sunet.se/][Sunet]] | [[http://gnupg.archive.sunet.se/][http]] | | | United Kingdom | [[http://mirror.tje.me.uk/][mirror.tje.me.uk]] | [[http://mirror.tje.me.uk/pub/mirrors/www.gnupg.org/][http]] [[ftp://mirror.tje.me.uk/pub/mirrors/www.gnupg.org][ftp]] | 4/day | | | [[http://www.mirrorservice.org/][UK Mirror Service]] | [[http://www.mirrorservice.org/sites/www.gnupg.org/][http]] | | | | | | | commit 1dd86025940fc4230e277a4a57798f58c93056c8 Author: Werner Koch Date: Mon Jan 18 17:51:34 2016 +0100 web: Change address of BTS to bugs.gnupg.org The bugs.g10code.com alias is not included in the certificate and thus some people get confused. We may want to use a redirection instead. diff --git a/web/documentation/bts.org b/web/documentation/bts.org index 6e6d8f9..cc1eabf 100644 --- a/web/documentation/bts.org +++ b/web/documentation/bts.org @@ -4,16 +4,14 @@ * Bug Tracking System - Our bug tracking system can be found at [[https://bugs.g10code.com/gnupg/index][bugs.g10code.com]]. Please, + Our bug tracking system can be found at [[https://bugs.gnupg.org/gnupg/index][bugs.gnupg.org]]. Please, query the database before you create a new bug report. You need to create an account to file a bug or edit existing bugs. See the - [[http://bugs.g10code.com/index.html#intro][Introduction to the BTS]]. Bug reports need to be written in English + [[http://bugs.gnupg.org/index.html#intro][Introduction to the BTS]]. Bug reports need to be written in English If you can fix one of these bugs/limitations, we will certainly be - glad to receive a patch. Please note that we need a disclaimer if - your patches are longer than about 10 lines; but it may help anyway - to show us where we have to fix it. Do an ?info standards? or see - [[http://www.gnu.org/copyleft/why-assign.html][this article]] to find out why a disclaimer is needed for GNU. + glad to receive a patch via the gnupg-devel mailing list. If the + patch is non-trivial please read the file [[http://git.gnupg.org/cgi-bin/gitweb.cgi?p%3Dgnupg.git%3Ba%3Dblob%3Bf%3Ddoc/HACKING][doc/HACKING]] first. ** GnuPG.org @@ -21,7 +19,3 @@ The *Bug Tracking System* can also be used to report problems related to GnuPG.org site. Simply, follow the instructions given above and set the "category" field to *gpgweb*. - - If you want to interact directly with us for questions, mistakes, - change requests, advices, and compliments, you can write an e-mail - to [[mailto:webmaster at gnupg.org][webmaster at gnupg.org]] . ----------------------------------------------------------------------- Summary of changes: web/documentation/bts.org | 14 ++++---------- web/download/mirrors.org | 1 - web/mirrors.org | 1 - 3 files changed, 4 insertions(+), 12 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 18 18:19:42 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Jan 2016 18:19:42 +0100 Subject: [git] gnupg-doc - branch, master, updated. 0345f3a7feae4c2a4ad27ab0bd385666372e9fbd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 0345f3a7feae4c2a4ad27ab0bd385666372e9fbd (commit) from 398b0954d0ab932603ba470b07ef8424dbf22c39 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0345f3a7feae4c2a4ad27ab0bd385666372e9fbd Author: Werner Koch Date: Mon Jan 18 18:14:47 2016 +0100 web: Add file faq/HACKING.org and adjust bts.org diff --git a/web/documentation/bts.org b/web/documentation/bts.org index cc1eabf..c8808cc 100644 --- a/web/documentation/bts.org +++ b/web/documentation/bts.org @@ -11,7 +11,7 @@ If you can fix one of these bugs/limitations, we will certainly be glad to receive a patch via the gnupg-devel mailing list. If the - patch is non-trivial please read the file [[http://git.gnupg.org/cgi-bin/gitweb.cgi?p%3Dgnupg.git%3Ba%3Dblob%3Bf%3Ddoc/HACKING][doc/HACKING]] first. + patch is non-trivial please read the file [[https://www.gnupg.org/faq/HACKING.html][doc/HACKING]] first. ** GnuPG.org diff --git a/web/faq/HACKING.org b/web/faq/HACKING.org new file mode 100644 index 0000000..fb71a91 --- /dev/null +++ b/web/faq/HACKING.org @@ -0,0 +1,384 @@ +# HACKING -*- org -*- +#+TITLE: A Hacker's Guide to GnuPG +#+TEXT: Some notes on GnuPG internals +#+STARTUP: showall +#+OPTIONS: ^:{} +# Note: This is a copy from GIT master: gnupg/doc/ + +* How to contribute + + The following stuff explains some basic procedures you need to + follow if you want to contribute code or documentation. + +** No more ChangeLog files + +Do not modify any of the ChangeLog files in GnuPG. Starting on +December 1st, 2011 we put change information only in the GIT commit +log, and generate a top-level ChangeLog file from logs at "make dist" +time. As such, there are strict requirements on the form of the +commit log messages. The old ChangeLog files have all be renamed to +ChangeLog-2011 + +** Commit log requirements + +Your commit log should always start with a one-line summary, the +second line should be blank, and the remaining lines are usually +ChangeLog-style entries for all affected files. However, it's fine +--- even recommended --- to write a few lines of prose describing the +change, when the summary and ChangeLog entries don't give enough of +the big picture. Omit the leading TABs that you are seeing in a +"real" ChangeLog file, but keep the maximum line length at 72 or +smaller, so that the generated ChangeLog lines, each with its leading +TAB, will not exceed 80 columns. If you want to add text which shall +not be copied to the ChangeLog, separate it by a line consisting of +two dashes at the begin of a line. + +The one-line summary usually starts with a keyword to identify the +mainly affected subsystem. If more than one keyword is required the +are delimited by a comma (e.g. =scd,w32:=). Commonly found keywords +are + + - agent :: The gpg-agent component + - ssh :: The ssh-agent part of the agent + - common :: Code in common + - iobuf :: The IOBUF system in common + - gpg :: The gpg or gpgv components + - gpgsm :: The gpgsm component + - scd :: The scdaemon component + - ccid :: The CCID driver in scdaemon + - dirmngr :: The dirmngr component + - w32 :: Windows related code + - po :: Translations + - build :: Changes to the build system + - speedo :: Speedo build system specific changes + - doc :: Documentation changes + +Typo fixes and documentation updates don't need a ChangeLog entry; +thus you would use a commit message like + +#+begin_example +Fix typo in a comment + +-- +#+end_example + +The marker line here is important; without it the first line would +appear in the ChangeLog. + +If you exceptionally need to have longer lines in a commit log you may +do this after this scissor line: +#+begin_example +# ------------------------ >8 ------------------------ +#+end_example +(hash, blank, 24 dashes, blank, scissor, blank, 24 dashes). +Note that such a comment will be removed if the git commit option +=--cleanup=scissor= is used. + + +** License policy + + GnuPG is licensed under the GPLv3+ with some files under a mixed + LGPLv3+/GPLv2+ license. It is thus important, that all contributed + code allows for an update of the license; for example we can't + accept code under the GPLv2(only). + + GnuPG used to have a strict policy of requiring copyright + assignments to the FSF. To avoid this major organizational overhead + and to allow inclusion of code, not copyrighted by the FSF, this + policy has been relaxed on 2013-03-29. It is now also possible to + contribute code by asserting that the contribution is in accordance + to the "Libgcrypt Developer's Certificate of Origin" as found in the + file "DCO". (Except for a slight wording change, this DCO is + identical to the one used by the Linux kernel.) + + If you want to contribute code or documentation to GnuPG and you + didn't sign a copyright assignment with the FSF in the past, you + need to take these simple steps: + + - Decide which mail address you want to use. Please have your real + name in the address and not a pseudonym. Anonymous contributions + can only be done if you find a proxy who certifies for you. + + - If your employer or school might claim ownership of code written + by you; you need to talk to them to make sure that you have the + right to contribute under the DCO. + + - Send an OpenPGP signed mail to the gnupg-devel at gnupg.org mailing + list from your mail address. Include a copy of the DCO as found + in the official master branch. Insert your name and email address + into the DCO in the same way you want to use it later. Example: + + Signed-off-by: Joe R. Hacker + + (If you really need it, you may perform simple transformations of + the mail address: Replacing "@" by " at " or "." by " dot ".) + + - That's it. From now on you only need to add a "Signed-off-by:" + line with your name and mail address to the commit message. It is + recommended to send the patches using a PGP/MIME signed mail. + +** Coding standards + + Please follow the GNU coding standards. If you are in doubt consult + the existing code as an example. Do no re-indent code without a + need. If you really need to do it, use a separate commit for such a + change. + + - Only certain C99 features may be used (see below); in general + stick to C90. + - Please do not use C++ =//= style comments. + - Try to fit lines into 80 columns. + - Ignore signed/unsigned pointer mismatches + - No arithmetic on void pointers; cast to char* first. + - We use our own printf style functions like =es_printf=, and + =es_asprintf= which implement most C99 features with the exception + of =wchar_t= (which should anyway not be used). Please always use + them and do not resort to those provided by libc. The rationale + for using them is that we know that the format specifiers work on + all platforms and that we do not need to chase platform dependent + bugs. + - It is common to have a label named "leave" for a function's + cleanup and return code. This helps with freeing memory and is a + convenient location to set a breakpoint for debugging. + - Always use xfree() instead of free(). If it is not easy to see + that the freed variable is not anymore used, explicitly set the + variable to NULL. + - Init function local variables only if needed so that the compiler + can do a better job in detecting uninitialized variables which may + indicate a problem with the code. + - Never init static or file local variables to 0 to make sure they + end up in BSS. + - Use --enable-maintainer-mode with configure. + +** C99 language features + + In GnuPG 2.x, but *not in 1.4* and not in most libraries, a limited + set of C99 features may be used: + + - Variadic macros: + : #define foo(a,...) bar(a, __VA_ARGS__) + + - The predefined macro =__func__=: + : log_debug ("%s: Problem with foo\n", __func__); + + - Variable declaration inside a for(): + : for (int i = 0; i < 5; ++) + : bar (i); + + Although we usually make use of the =u16=, =u32=, and =u64= types, + it is also possible to include == and use =int16_t=, + =int32_t=, =int64_t=, =uint16_t=, =uint32_t=, and =uint64_t=. But do + not use =int8_t= or =uint8_t=. + +** Commit log keywords + + - GnuPG-bug-id :: Values are comma or space delimited bug numbers + from bug.gnupg.org pertaining to this commit. + - Debian-bug-id :: Same as above but from the Debian bug tracker. + - CVE-id :: CVE id number pertaining to this commit. + - Regression-due-to :: Commit id of the regression fixed by this commit. + - Fixes-commit :: Commit id this commit fixes. + - Reported-by :: Value is a name or mail address of a bug reporte. + - Suggested-by :: Value is a name or mail address of someone how + suggested this change. + - Co-authored-by :: Name or mail address of a co-author + - Some-comments-by :: Name or mail address of the author of + additional comments (commit log or code). + - Proofread-by :: Sometimes used by translation commits. + - Signed-off-by :: Name or mail address of the developer + +* Windows +** How to build an installer for Windows + + Your best bet is to use a decent Debian System for development. + You need to install a long list of tools for building. This list + still needs to be compiled. However, the build process will stop + if a tool is missing. GNU make is required (on non GNU systems + often installed as "gmake"). The installer requires a couple of + extra software to be available either as tarballs or as local git + repositories. In case this file here is part of a gnupg-w32-2.*.xz + complete tarball as distributed from the same place as a binary + installer, all such tarballs are already included. + + Cd to the GnuPG source directory and use one of one of these + command: + + - If sources are included (gnupg-w32-*.tar.xz) + + make -f build-aux/speedo.mk WHAT=this installer + + - To build from tarballs + + make -f build-aux/speedo.mk WHAT=release TARBALLS=TARDIR installer + + - To build from local GIT repos + + make -f build-aux/speedo.mk WHAT=git TARBALLS=TARDIR installer + + Note that also you need to supply tarballs with supporting + libraries even if you build from git. The makefile expects only + the core GnuPG software to be available as local GIT repositories. + speedo.mk has the versions of the tarballs and the branch names of + the git repositories. In case of problems, don't hesitate to ask + on the gnupg-devel mailing for help. + +* Debug hints + + See the manual for some hints. + +* Standards +** RFCs + +1423 Privacy Enhancement for Internet Electronic Mail: + Part III: Algorithms, Modes, and Identifiers. + +1489 Registration of a Cyrillic Character Set. + +1750 Randomness Recommendations for Security. + +1991 PGP Message Exchange Formats (obsolete) + +2144 The CAST-128 Encryption Algorithm. + +2279 UTF-8, a transformation format of ISO 10646. + +2440 OpenPGP (obsolete). + +3156 MIME Security with Pretty Good Privacy (PGP). + +4880 Current OpenPGP specification. + +6337 Elliptic Curve Cryptography (ECC) in OpenPGP + +* Various information + +** Directory Layout + + - ./ :: Readme, configure + - ./agent :: Gpg-agent and related tools + - ./doc :: Documentation + - ./g10 :: Gpg program here called gpg2 + - ./sm :: Gpgsm program + - ./jnlib :: Not used (formerly used utility functions) + - ./common :: Utility functions + - ./kbx :: Keybox library + - ./scd :: Smartcard daemon + - ./scripts :: Scripts needed by configure and others + - ./dirmngr :: The directory manager + +** Detailed Roadmap + + This list of files is not up to date! + + - g10/gpg.c :: Main module with option parsing and all the stuff you + have to do on startup. Also has the exit handler and + some helper functions. + + - g10/parse-packet.c :: + - g10/build-packet.c :: + - g10/free-packet.c :: Parsing and creating of OpenPGP message packets. + + - g10/getkey.c :: Key selection code + - g10/pkclist.c :: Build a list of public keys + - g10/skclist.c :: Build a list of secret keys + - g10/keyring.c :: Keyring access functions + - g10/keydb.h :: + + - g10/keyid.c :: Helper functions to get the keyid, fingerprint etc. + + - g10/trustdb.c :: Web-of-Trust computations + - g10/trustdb.h :: + - g10/tdbdump.c :: Export/import/list the trustdb.gpg + - g10/tdbio.c :: I/O handling for the trustdb.gpg + - g10/tdbio.h :: + + - g10/compress.c :: Filter to handle compression + - g10/filter.h :: Declarations for all filter functions + - g10/delkey.c :: Delete a key + - g10/kbnode.c :: Helper for the kbnode_t linked list + - g10/main.h :: Prototypes and some constants + - g10/mainproc.c :: Message processing + - g10/armor.c :: Ascii armor filter + - g10/mdfilter.c :: Filter to calculate hashs + - g10/textfilter.c :: Filter to handle CR/LF and trailing white space + - g10/cipher.c :: En-/Decryption filter + - g10/misc.c :: Utlity functions + - g10/options.h :: Structure with all the command line options + and related constants + - g10/openfile.c :: Create/Open Files + - g10/keyserver.h :: Keyserver access dispatcher. + - g10/packet.h :: Defintion of OpenPGP structures. + - g10/passphrase.c :: Passphrase handling code + + - g10/pubkey-enc.c :: Process a public key encoded packet. + - g10/seckey-cert.c :: Not anymore used + - g10/seskey.c :: Make sesssion keys etc. + - g10/import.c :: Import keys into our key storage. + - g10/export.c :: Export keys to the OpenPGP format. + - g10/sign.c :: Create signature and optionally encrypt. + - g10/plaintext.c :: Process plaintext packets. + - g10/decrypt-data.c :: Decrypt an encrypted data packet + - g10/encrypt.c :: Main encryption driver + - g10/revoke.c :: Create recovation certificates. + - g10/keylist.c :: Print information about OpenPGP keys + - g10/sig-check.c :: Check a signature + - g10/helptext.c :: Show online help texts + - g10/verify.c :: Verify signed data. + - g10/decrypt.c :: Decrypt and verify data. + - g10/keyedit.c :: Edit properties of a key. + - g10/dearmor.c :: Armor utility. + - g10/keygen.c :: Generate a key pair + +** Memory allocation + +Use only the functions: + + - xmalloc + - xmalloc_secure + - xtrymalloc + - xtrymalloc_secure + - xcalloc + - xcalloc_secure + - xtrycalloc + - xtrycalloc_secure + - xrealloc + - xtryrealloc + - xstrdup + - xtrystrdup + - xfree + + +The *secure versions allocate memory in the secure memory. That is, +swapping out of this memory is avoided and is gets overwritten on +free. Use this for passphrases, session keys and other sensitive +material. This memory set aside for secure memory is linited to a few +k. In general the function don't print a memeory message and +terminate the process if there is not enough memory available. The +"try" versions of the functions return NULL instead. + +** Logging + + TODO + +** Option parsing + +GnuPG does not use getopt or GNU getopt but functions of it's own. +See util/argparse.c for details. The advantage of these functions is +that it is more easy to display and maintain the help texts for the +options. The same option table is also used to parse resource files. + +** What is an IOBUF + +This is the data structure used for most I/O of gnupg. It is similar +to System?V Streams but much simpler. Because OpenPGP messages are +nested in different ways; the use of such a system has big advantages. +Here is an example, how it works: If the parser sees a packet header +with a partial length, it pushes the block_filter onto the IOBUF to +handle these partial length packets: from now on you don't have to +worry about this. When it sees a compressed packet it pushes the +uncompress filter and the next read byte is one which has already been +uncompressed by this filter. Same goes for enciphered packet, +plaintext packets and so on. The file g10/encode.c might be a good +starting point to see how it is used - actually this is the other way: +constructing messages using pushed filters but it may be easier to +understand. ----------------------------------------------------------------------- Summary of changes: web/documentation/bts.org | 2 +- web/faq/HACKING.org | 384 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 385 insertions(+), 1 deletion(-) create mode 100644 web/faq/HACKING.org hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 18 19:00:00 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Jan 2016 19:00:00 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-127-g79778a8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 79778a8dd5f61a6b7abeeb44b75d82932db788b7 (commit) via 576fedc5f6a1d76d6e1ed0cd3b54a1090230399e (commit) from 9309bda9581715d304305c8c5116f2cbb31aec77 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 79778a8dd5f61a6b7abeeb44b75d82932db788b7 Author: Werner Koch Date: Mon Jan 18 18:54:46 2016 +0100 g10: Improve strings printed by tofu.c. * g10/tofu.c: Include ttyio.h. Change many strings to help translating. Make use of ngettext wehere needed. (CONTROL_L): New. (TIME_AGO_UNIT_SMALL_NAME): Remove this and all similar *_NAME macros. (time_ago_unit): Remove. (get_trust): Use tty_prints and cpr_get only for the actual prompt. Add Ctrl-L hack. (show_statistics): Use two English strings for singular and plural. * po/POTFILES.in: Add tofu.c. -- These changes are required for proper translation. More to changes may be needed, though. Signed-off-by: Werner Koch diff --git a/g10/tofu.c b/g10/tofu.c index 903f076..e593083 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -38,12 +38,17 @@ #include "options.h" #include "mbox-util.h" #include "i18n.h" +#include "ttyio.h" #include "trustdb.h" #include "mkdir_p.h" #include "sqlite.h" #include "tofu.h" + +#define CONTROL_L ('L' - 'A' + 1) + + #define DEBUG_TOFU_CACHE 0 #if DEBUG_TOFU_CACHE static int prepares_saved; @@ -144,28 +149,16 @@ tofu_cache_dump (struct db *db) #define TIME_AGO_FUTURE_IGNORE (2 * 60 * 60) #if 0 # define TIME_AGO_UNIT_SMALL 60 -# define TIME_AGO_UNIT_SMALL_NAME _("minute") -# define TIME_AGO_UNIT_SMALL_NAME_PLURAL _("minutes") # define TIME_AGO_MEDIUM_THRESHOLD (60 * TIME_AGO_UNIT_SMALL) # define TIME_AGO_UNIT_MEDIUM (60 * 60) -# define TIME_AGO_UNIT_MEDIUM_NAME _("hour") -# define TIME_AGO_UNIT_MEDIUM_NAME_PLURAL _("hours") # define TIME_AGO_LARGE_THRESHOLD (24 * 60 * TIME_AGO_UNIT_SMALL) # define TIME_AGO_UNIT_LARGE (24 * 60 * 60) -# define TIME_AGO_UNIT_LARGE_NAME _("day") -# define TIME_AGO_UNIT_LARGE_NAME_PLURAL _("days") #else # define TIME_AGO_UNIT_SMALL (24 * 60 * 60) -# define TIME_AGO_UNIT_SMALL_NAME _("day") -# define TIME_AGO_UNIT_SMALL_NAME_PLURAL _("days") # define TIME_AGO_MEDIUM_THRESHOLD (4 * TIME_AGO_UNIT_SMALL) # define TIME_AGO_UNIT_MEDIUM (7 * 24 * 60 * 60) -# define TIME_AGO_UNIT_MEDIUM_NAME _("week") -# define TIME_AGO_UNIT_MEDIUM_NAME_PLURAL _("weeks") # define TIME_AGO_LARGE_THRESHOLD (28 * TIME_AGO_UNIT_SMALL) # define TIME_AGO_UNIT_LARGE (30 * 24 * 60 * 60) -# define TIME_AGO_UNIT_LARGE_NAME _("month") -# define TIME_AGO_UNIT_LARGE_NAME_PLURAL _("months") #endif @@ -1435,30 +1428,6 @@ time_ago_scale (signed long t) return t / TIME_AGO_UNIT_LARGE; } -/* Return the appropriate unit (respecting whether it is plural or - singular). */ -const char * -time_ago_unit (signed long t) -{ - signed long t_scaled = time_ago_scale (t); - - if (t < TIME_AGO_UNIT_MEDIUM) - { - if (t_scaled == 1) - return TIME_AGO_UNIT_SMALL_NAME; - return TIME_AGO_UNIT_SMALL_NAME_PLURAL; - } - if (t < TIME_AGO_UNIT_LARGE) - { - if (t_scaled == 1) - return TIME_AGO_UNIT_MEDIUM_NAME; - return TIME_AGO_UNIT_MEDIUM_NAME_PLURAL; - } - if (t_scaled == 1) - return TIME_AGO_UNIT_LARGE_NAME; - return TIME_AGO_UNIT_LARGE_NAME_PLURAL; -} - /* Return the policy for the binding (email has already been normalized) and any conflict information in *CONFLICT @@ -1839,7 +1808,8 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, if (policy == TOFU_POLICY_NONE) { - es_fprintf (fp, _("The binding %s is NOT known. "), binding); + es_fprintf (fp, _("The binding %s is NOT known."), binding); + es_fputs (" ", fp); binding_shown = 1; } else if (policy == TOFU_POLICY_ASK @@ -1851,17 +1821,21 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, es_fprintf (fp, _("The key %s raised a conflict with this binding (%s)." " Since this binding's policy was 'auto', it was " - "changed to 'ask'. "), + "changed to 'ask'."), conflict_pp, binding); + es_fputs (" ", fp); xfree (conflict_pp); binding_shown = 1; } + /* TRANSLATORS: The %s%s is replaced by either a fingerprint and a + blank or by two empty strings. */ es_fprintf (fp, _("Please indicate whether you believe the binding %s%s" "is legitimate (the key belongs to the stated owner) " - "or a forgery (bad).\n\n"), + "or a forgery (bad)."), binding_shown ? "" : binding, binding_shown ? "" : " "); + es_fputs ("\n\n", fp); xfree (binding); @@ -1900,7 +1874,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, { strlist_t strlist_iter; - es_fprintf (fp, _("Known user ids associated with this key:\n")); + es_fprintf (fp, _("Known user IDs associated with this key:\n")); for (strlist_iter = other_user_ids; strlist_iter; strlist_iter = strlist_iter->next) @@ -1918,10 +1892,10 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, else other_policy = atoi (other_thing); - es_fprintf (fp, _(" %s (policy: %s)\n"), - other_user_id, - tofu_policy_str (other_policy)); - } + es_fprintf (fp, " %s (", other_user_id); + es_fprintf (fp, _("policy: %s"), tofu_policy_str (other_policy)); + es_fprintf (fp, ")\n"); + } es_fprintf (fp, "\n"); free_strlist (other_user_ids); @@ -1970,18 +1944,20 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, { strlist_t strlist_iter; - log_error (_("error gathering signature stats: %s.\n"), - err); + log_error (_("error gathering signature stats: %s\n"), err); sqlite3_free (err); err = NULL; - es_fprintf - (fp, _("The email address (%s) is associated with %d keys:\n"), - email, bindings_with_this_email_count); + es_fprintf (fp, ngettext("The email address \"%s\" is" + " associated with %d key:\n", + "The email address \"%s\" is" + " associated with %d keys:\n", + bindings_with_this_email_count), + email, bindings_with_this_email_count); for (strlist_iter = bindings_with_this_email; strlist_iter; strlist_iter = strlist_iter->next) - es_fprintf (fp, _(" %s\n"), strlist_iter->d); + es_fprintf (fp, " %s\n", strlist_iter->d); } else { @@ -1994,8 +1970,9 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, any messages signed by this key. Add a dummy entry. */ signature_stats_prepend (&stats, fingerprint, TOFU_POLICY_AUTO, 0, 0); - es_fprintf (fp, _("Statistics for keys with the email '%s':\n"), - email); + es_fprintf + (fp, _("Statistics for keys with the email address \"%s\":\n"), + email); for (stats_iter = stats; stats_iter; stats_iter = stats_iter->next) { if (! key || strcmp (key, stats_iter->fingerprint) != 0) @@ -2005,37 +1982,54 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, key = stats_iter->fingerprint; this_key = strcmp (key, fingerprint) == 0; key_pp = format_hexfingerprint (key, NULL, 0); + es_fprintf (fp, " %s (", key_pp); if (this_key) - es_fprintf (fp, _(" %s (this key):"), key_pp); + es_fprintf (fp, _("this key")); else - es_fprintf (fp, _(" %s (policy: %s):"), - key_pp, tofu_policy_str (stats_iter->policy)); + es_fprintf (fp, _("policy: %s"), + tofu_policy_str (stats_iter->policy)); + es_fputs ("):\n", fp); xfree (key_pp); - es_fprintf (fp, "\n"); } + es_fputs (" ", fp); if (stats_iter->time_ago == -1) - es_fprintf (fp, _(" %ld %s signed in the future.\n"), - stats_iter->count, - stats_iter->count == 1 - ? _("message") : _("messages")); - else if (stats_iter->count == 0) - es_fprintf (fp, _(" 0 signed messages.\n")); + es_fprintf (fp, ngettext("%ld message signed in the future.", + "%ld messages signed in the future.", + stats_iter->count), stats_iter->count); else - es_fprintf (fp, _(" %ld %s signed over the past %ld %s.\n"), - stats_iter->count, - stats_iter->count == 1 - ? _("message") : _("messages"), - time_ago_scale (stats_iter->time_ago), - time_ago_unit (stats_iter->time_ago)); + { + long t_scaled = time_ago_scale (stats_iter->time_ago); + + /* TANSLATORS: This string is concatenated with one of + * the day/week/month strings to form one sentence. */ + es_fprintf (fp, ngettext("%ld message signed", + "%ld messages signed", + stats_iter->count), stats_iter->count); + if (!stats_iter->count) + es_fputs (".", fp); + else if (stats_iter->time_ago < TIME_AGO_UNIT_MEDIUM) + es_fprintf (fp, ngettext(" over the past %ld day.", + " over the past %ld days.", + t_scaled), t_scaled); + else if (stats_iter->time_ago < TIME_AGO_UNIT_LARGE) + es_fprintf (fp, ngettext(" over the past %ld week.", + " over the past %ld weeks.", + t_scaled), t_scaled); + else + es_fprintf (fp, ngettext(" over the past %ld month.", + " over the past %ld months.", + t_scaled), t_scaled); + } + es_fputs ("\n", fp); } } if (is_conflict) { - /* TRANSLATORS: translate the below text. We don't directly - internationalize that text so that we can tweak it without - breaking translations. */ + /* TRANSLATORS: Please translate the text found in the source + file below. We don't directly internationalize that text + so that we can tweak it without breaking translations. */ char *text = _("TOFU detected a binding conflict"); if (strcmp (text, "TOFU detected a binding conflict") == 0) /* No translation. Use the English text. */ @@ -2052,34 +2046,42 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, } es_fputc ('\n', fp); - /* TRANSLATORS: Two letters (normally the lower and upper case - version of the hotkey) for each of the five choices. If there - is only one choice in your language, repeat it. */ - choices = _("gG" "aA" "uU" "rR" "bB"); - es_fprintf (fp, _("(G)ood/(A)ccept once/(U)nknown/(R)eject once/(B)ad? ")); /* Add a NUL terminator. */ es_fputc (0, fp); if (es_fclose_snatch (fp, (void **) &prompt, NULL)) log_fatal ("error snatching memory stream\n"); + /* I think showing the large message once is sufficient. If we + would move it right before the cpr_get many lines will scroll + away and the user might not realize that he merely entered a + wrong choise (because he does not see that either). As a small + benefit we allow C-L to redisplay everything. */ + tty_printf ("%s", prompt); while (1) { char *response; + /* TRANSLATORS: Two letters (normally the lower and upper case + version of the hotkey) for each of the five choices. If + there is only one choice in your language, repeat it. */ + choices = _("gG" "aA" "uU" "rR" "bB"); if (strlen (choices) != 10) log_bug ("Bad TOFU conflict translation! Please report."); - response = cpr_get ("tofu conflict", prompt); + response = cpr_get + ("tofu.conflict", + _("(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? ")); trim_spaces (response); cpr_kill_prompt (); - if (strlen (response) == 1) + if (*response == CONTROL_L) + tty_printf ("%s", prompt); + else if (strlen (response) == 1) { char *choice = strchr (choices, *response); if (choice) { int c = ((size_t) choice - (size_t) choices) / 2; - assert (0 <= c && c <= 4); switch (c) { @@ -2160,6 +2162,14 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, return trust_level; } + +/* Return a malloced string of the form + * "7 months, 1 day, 5 minutes, 0 seconds" + * The caller must free that string. + * + * This is actually a bad hack which may not work correctly with all + * languages. + */ static char * time_ago_str (long long int t) { @@ -2229,10 +2239,7 @@ time_ago_str (long long int t) if (years) { - if (years > 1) - es_fprintf (fp, _("%d years"), years); - else - es_fprintf (fp, _("%d year"), years); + es_fprintf (fp, ngettext("%d year", "%d years", years), years); count ++; first = i; } @@ -2241,11 +2248,7 @@ time_ago_str (long long int t) { if (count) es_fprintf (fp, ", "); - - if (months > 1) - es_fprintf (fp, _("%d months"), months); - else - es_fprintf (fp, _("%d month"), months); + es_fprintf (fp, ngettext("%d month", "%d months", months), months); count ++; first = i; } @@ -2254,11 +2257,7 @@ time_ago_str (long long int t) { if (count) es_fprintf (fp, ", "); - - if (days > 1) - es_fprintf (fp, _("%d days"), days); - else - es_fprintf (fp, _("%d day"), days); + es_fprintf (fp, ngettext("%d day", "%d days", days), days); count ++; first = i; } @@ -2267,11 +2266,7 @@ time_ago_str (long long int t) { if (count) es_fprintf (fp, ", "); - - if (hours > 1) - es_fprintf (fp, _("%d hours"), hours); - else - es_fprintf (fp, _("%d hour"), hours); + es_fprintf (fp, ngettext("%d hour", "%d hours", hours), hours); count ++; first = i; } @@ -2280,11 +2275,7 @@ time_ago_str (long long int t) { if (count) es_fprintf (fp, ", "); - - if (minutes > 1) - es_fprintf (fp, _("%d minutes"), minutes); - else - es_fprintf (fp, _("%d minute"), minutes); + es_fprintf (fp, ngettext("%d minute", "%d minutes", minutes), minutes); count ++; first = i; } @@ -2293,11 +2284,7 @@ time_ago_str (long long int t) { if (count) es_fprintf (fp, ", "); - - if (seconds > 1) - es_fprintf (fp, _("%d seconds"), seconds); - else - es_fprintf (fp, _("%d second"), seconds); + es_fprintf (fp, ngettext("%d second", "%d seconds", seconds), seconds); } es_fputc (0, fp); @@ -2307,6 +2294,7 @@ time_ago_str (long long int t) return str; } + static void show_statistics (struct dbs *dbs, const char *fingerprint, const char *email, const char *user_id, @@ -2416,25 +2404,33 @@ show_statistics (struct dbs *dbs, const char *fingerprint, if (messages == 0) es_fprintf (fp, _("Verified 0 messages signed by \"%s\"" - " (key: %s, policy %s)."), + " (key: %s, policy: %s)."), user_id, fingerprint_pp, tofu_policy_str (policy)); else { - char *first_seen_ago_str = time_ago_str (first_seen_ago); + char *first_seen_ago_str = + time_ago_str (first_seen_ago); char *most_recent_seen_ago_str = time_ago_str (most_recent_seen_ago); - es_fprintf (fp, - _("Verified %ld messages signed by \"%s\"" - " (key: %s, policy: %s) in the past %s."), + /* TRANSLATORS: The final %s is replaced by a string like + "7 months, 1 day, 5 minutes, 0 seconds". */ + es_fprintf (fp, ngettext("Verified %ld message signed by \"%s\"" + " (key: %s, policy: %s) in the past %s.", + "Verified %ld messages signed by \"%s\"" + " (key: %s, policy: %s) in the past %s.", + messages), messages, user_id, fingerprint_pp, tofu_policy_str (policy), first_seen_ago_str); if (messages > 1) - es_fprintf (fp, - _(" The most recent message was verified %s ago."), - most_recent_seen_ago_str); + { + es_fputs (" ", fp); + es_fprintf (fp, + _("The most recent message was verified %s ago."), + most_recent_seen_ago_str); + } xfree (first_seen_ago_str); xfree (most_recent_seen_ago_str); @@ -2465,18 +2461,26 @@ show_statistics (struct dbs *dbs, const char *fingerprint, /* TRANSLATORS: translate the below text. We don't directly internationalize that text so that we can tweak it without breaking translations. */ - text = _("TOFU: few signatures %d %s %s"); - if (strcmp (text, "TOFU: few signatures %d %s %s") == 0) - text = - "Warning: if you think you've seen more than %d %s " - "signed by this key, then this key might be a forgery! " - "Carefully examine the email address for small variations " - "(e.g., additional white space). If the key is suspect, " - "then use '%s' to mark it as being bad.\n"; - tmp = xasprintf - (text, - messages, messages == 1 ? _("message") : _("message"), - set_policy_command); + text = ngettext("TOFU: few signatures %d message %s", + "TOFU: few signatures %d messages %s", 1); + if (strcmp (text, "TOFU: few signatures %d message %s") == 0) + { + text = + (messages == 1? + "Warning: if you think you've seen more than %d message " + "signed by this key, then this key might be a forgery! " + "Carefully examine the email address for small variations " + "(e.g., additional white space). If the key is suspect, " + "then use '%s' to mark it as being bad.\n" + : + "Warning: if you think you've seen more than %d messages " + "signed by this key, then this key might be a forgery! " + "Carefully examine the email address for small variations " + "(e.g., additional white space). If the key is suspect, " + "then use '%s' to mark it as being bad.\n"); + } + + tmp = xasprintf (text, messages, set_policy_command); text = format_text (tmp, 0, 72, 80); xfree (tmp); log_info ("%s", text); diff --git a/po/POTFILES.in b/po/POTFILES.in index dc88448..e42cb32 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -70,6 +70,7 @@ g10/skclist.c g10/tdbdump.c g10/tdbio.c g10/textfilter.c +g10/tofu.c g10/trustdb.c g10/trust.c g10/verify.c commit 576fedc5f6a1d76d6e1ed0cd3b54a1090230399e Author: Werner Koch Date: Mon Jan 18 12:15:09 2016 +0100 gpg: Minor string changes. -- diff --git a/g10/getkey.c b/g10/getkey.c index d6e27e6..9a4f81e 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -621,7 +621,7 @@ get_pubkeys (ctrl_t ctrl, { char fingerprint_formatted[MAX_FORMATTED_FINGERPRINT_LEN + 1]; - log_info (_("Warning: %s appears in the keyring %d times.\n"), + log_info (_("Warning: %s appears in the keyring %d times\n"), format_hexfingerprint (fingerprint, fingerprint_formatted, sizeof fingerprint_formatted), diff --git a/g10/misc.c b/g10/misc.c index 57d5fef..5e764fa 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -374,10 +374,10 @@ print_reported_error (gpg_error_t err, gpg_err_code_t ignore_ec) else if (gpg_err_code (err) == ignore_ec) ; else if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) - log_info (_("(reported error: %s\n)"), + log_info (_("(reported error: %s)\n"), gpg_strerror (err)); else - log_info (_("(reported error: %s <%s>\n)"), + log_info (_("(reported error: %s <%s>)\n"), gpg_strerror (err), gpg_strsource (err)); } diff --git a/g10/pkclist.c b/g10/pkclist.c index d7e78cb..d9ada59 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -940,7 +940,7 @@ build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list) xfree (r->pk); xfree (r); - log_error (_("Can't encrypt to '%s'.\n"), default_key); + log_error (_("can't encrypt to '%s'\n"), default_key); if (!opt.quiet) log_info (_("(check argument of option '%s')\n"), "--default-key"); ----------------------------------------------------------------------- Summary of changes: g10/getkey.c | 2 +- g10/misc.c | 4 +- g10/pkclist.c | 2 +- g10/tofu.c | 260 +++++++++++++++++++++++++++++---------------------------- po/POTFILES.in | 1 + 5 files changed, 137 insertions(+), 132 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 19 18:05:40 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 19 Jan 2016 18:05:40 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-131-g4c6c973 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 4c6c973950df1471544f5d485e4cc2f4603bbd77 (commit) via cfa41890bb5ff306c07dad295136601fe47566a7 (commit) via 8b7f64f9dfc80b2a0ad235996b47369c2ba9b48f (commit) via d96e76d15f61812b950b64a60bc47117785a9dac (commit) from 79778a8dd5f61a6b7abeeb44b75d82932db788b7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4c6c973950df1471544f5d485e4cc2f4603bbd77 Author: Werner Koch Date: Tue Jan 19 16:30:39 2016 +0100 po: Update German translation -- These are mainly new strings for the TOFU module, diff --git a/po/de.po b/po/de.po index 7d3e301..0312d16 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2015-12-03 17:23+0100\n" +"PO-Revision-Date: 2016-01-19 16:22+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" "Language: de\n" @@ -1197,6 +1197,18 @@ msgid "Enter passphrase: " msgstr "Geben Sie die Passphrase ein: " #, c-format +msgid "error getting version from '%s': %s\n" +msgstr "Fehler beim Holen der Version von '%s': %s\n" + +#, c-format +msgid "server '%s' is older than us (%s < %s)" +msgstr "Der Server '%s' is ?lter als wir selbst (Version %s < %s)" + +#, c-format +msgid "WARNING: %s\n" +msgstr "WARNUNG: %s\n" + +#, c-format msgid "OpenPGP card not available: %s\n" msgstr "OpenPGP Karte ist nicht vorhanden: %s\n" @@ -1675,6 +1687,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 " - skipped" +msgstr " - ?bersprungen" + msgid "exporting secret keys not allowed\n" msgstr "Exportieren geheimer Schl?ssel ist nicht erlaubt\n" @@ -1686,16 +1701,34 @@ msgstr "Schl?ssel %s: PGP 2.x-artiger Schl?ssel - ?bersprungen\n" msgid "key %s: key material on-card - skipped\n" msgstr "Schl?ssel %s: Schl?sselmaterial ist auf einer Karte - ?bersprungen\n" -msgid " - skipped" -msgstr " - ?bersprungen" - msgid "WARNING: nothing exported\n" msgstr "WARNUNG: Nichts exportiert\n" +#, c-format +msgid "error creating '%s': %s\n" +msgstr "Fehler beim Erstellen von `%s': %s\n" + msgid "[User ID not found]" msgstr "[User-ID nicht gefunden]" #, c-format +msgid "(check argument of option '%s')\n" +msgstr "(Pr?fe das Argument der Option '%s')\n" + +#, c-format +msgid "Warning: '%s' should be a long key ID or a fingerprint\n" +msgstr "" +"WARNUNG: '%s' sollte eine lange Schl?ssel-ID oder ein Fingerabdruck sein\n" + +#, c-format +msgid "error looking up: %s\n" +msgstr "Fehler beim Nachschlagen von: %s\n" + +#, c-format +msgid "Warning: %s appears in the keyring %d times\n" +msgstr "WARNUNG: %s ist %d mal im Schl?sselbund vorhanden\n" + +#, c-format msgid "automatically retrieved '%s' via %s\n" msgstr "`%s' automatisch via %s geholt\n" @@ -1711,12 +1744,18 @@ msgid "secret key \"%s\" not found: %s\n" msgstr "Geheimer Schl?ssel \"%s\" nicht gefunden: %s\n" #, c-format -msgid "(check argument of option '%s')\n" -msgstr "(Pr?fe das Argument der Option '%s')\n" +msgid "Warning: not using '%s' as default key: %s\n" +msgstr "" +"WARNUNG: \"%s\" wird nicht als voreingestellter geheimer Schl?ssel benutzt: " +"%s\n" + +#, c-format +msgid "using \"%s\" as default secret key for signing\n" +msgstr "\"%s\" wird als voreingestellter geheimer Signaturschl?ssel benutzt\n" #, c-format -msgid "using \"%s\" as default secret key\n" -msgstr "\"%s\" wird als voreingestellter geheimer Schl?ssel benutzt\n" +msgid "all values passed to '%s' ignored\n" +msgstr "Alle f?r '%s' angegebenen Werte wurden ignoriert\n" #, c-format msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n" @@ -2059,29 +2098,6 @@ msgid "Note: old default options file '%s' ignored\n" msgstr "Hinweis: Alte voreingestellte Optionendatei '%s' wurde ignoriert\n" #, c-format -msgid "" -"Warning: value '%s' for option '%s' should be a long key ID or a " -"fingerprint\n" -msgstr "" -"WARNUNG: Der Wert '%s' der Option '%s' sollte eine lange Schl?ssel-ID\n" -"oder ein Fingerabdruck sein\n" - -#, c-format -msgid "key specification '%s' is ambiguous\n" -msgstr "Schl?sselangabe '%s' ist mehrdeutig\n" - -#. TRANSLATORS: The %s prints a key specification which -#. for example has been given at the command line. Two -#. lines with fingerprints are printed after this message. -#, c-format -msgid "'%s' matches at least:\n" -msgstr "'%s' pa?t mindest auf:\n" - -#, c-format -msgid "error searching the keyring: %s\n" -msgstr "Fehler beim Suchen im Schl?sselbund: %s\n" - -#, c-format msgid "libgcrypt is too old (need %s, have %s)\n" msgstr "" "Die Bibliothek \"libgcrypt\" ist zu alt (ben?tigt wird %s, vorhanden ist " @@ -2281,14 +2297,6 @@ msgid "WARNING: recipients (-r) given without using public key encryption\n" msgstr "" "WARNUNG: Empf?nger (-r) angegeben ohne Verwendung von Public-Key-Verfahren\n" -#, c-format -msgid "option '%s' given, but no valid default keys given\n" -msgstr "Option '%s' ohne g?ltige Standardschl?ssel angegeben\n" - -#, c-format -msgid "option '%s' given, but option '%s' not given\n" -msgstr "Option '%s' ohne Verwendung der Option '%s' angegeben\n" - msgid "--store [filename]" msgstr "--store [Dateiname]" @@ -2366,6 +2374,10 @@ msgid "key export failed: %s\n" msgstr "Schl?sselexport fehlgeschlagen: %s\n" #, c-format +msgid "export as ssh key failed: %s\n" +msgstr "Schl?sselexport im SSH Format fehlgeschlagen: %s\n" + +#, c-format msgid "keyserver search failed: %s\n" msgstr "Suche auf dem Schl?sselserver fehlgeschlagen: %s\n" @@ -2855,33 +2867,29 @@ msgstr "[Widerruf]" msgid "[self-signature]" msgstr "[Eigenbeglaubigung]" -msgid "1 bad signature\n" -msgstr "1 falsche Beglaubigung\n" - #, c-format -msgid "%d bad signatures\n" -msgstr "%d falsche Beglaubigungen\n" - -msgid "1 signature not checked due to a missing key\n" -msgstr "1 Beglaubigung wegen fehlendem Schl?ssel nicht gepr?ft\n" +msgid "%d bad signature\n" +msgid_plural "%d bad signatures\n" +msgstr[0] "%d falsche Beglaubigung\n" +msgstr[1] "%d falsche Beglaubigungen\n" #, c-format -msgid "%d signatures not checked due to missing keys\n" -msgstr "%d Beglaubigungen wegen fehlenden Schl?sseln nicht gepr?ft\n" - -msgid "1 signature not checked due to an error\n" -msgstr "1 Beglaubigung aufgrund von Fehler nicht gepr?ft\n" +msgid "%d signature not checked due to a missing key\n" +msgid_plural "%d signatures not checked due to missing keys\n" +msgstr[0] "%d Beglaubigung wegen fehlendem Schl?ssel nicht gepr?ft\n" +msgstr[1] "%d Beglaubigungen wegen fehlender Schl?ssel nicht gepr?ft\n" #, c-format -msgid "%d signatures not checked due to errors\n" -msgstr "%d Beglaubigungen aufgrund von Fehlern nicht gepr?ft\n" - -msgid "1 user ID without valid self-signature detected\n" -msgstr "Eine User-ID ohne g?ltige Eigenbeglaubigung entdeckt\n" +msgid "%d signature not checked due to an error\n" +msgid_plural "%d signatures not checked due to errors\n" +msgstr[0] "%d Beglaubigung aufgrund eines Fehlers nicht gepr?ft\n" +msgstr[1] "%d Beglaubigungen aufgrund von Fehlern nicht gepr?ft\n" #, c-format -msgid "%d user IDs without valid self-signatures detected\n" -msgstr "%d User-IDs ohne g?ltige Eigenbeglaubigung entdeckt\n" +msgid "%d user ID without valid self-signature detected\n" +msgid_plural "%d user IDs without valid self-signatures detected\n" +msgstr[0] "%d User-ID ohne g?ltige Eigenbeglaubigung entdeckt\n" +msgstr[1] "%d User-IDs ohne g?ltige Eigenbeglaubigungen entdeckt\n" msgid "" "Please decide how far you trust this user to correctly verify other users' " @@ -3472,11 +3480,9 @@ msgstr "Eigenbeglaubigung wirklich entfernen? (j/N)" #, c-format msgid "Deleted %d signature.\n" -msgstr "%d Beglaubigungen entfernt.\n" - -#, c-format -msgid "Deleted %d signatures.\n" -msgstr "%d Beglaubigungen entfernt.\n" +msgid_plural "Deleted %d signatures.\n" +msgstr[0] "%d Beglaubigung entfernt.\n" +msgstr[1] "%d Beglaubigungen entfernt.\n" msgid "Nothing deleted.\n" msgstr "Nichts entfernt.\n" @@ -3490,11 +3496,9 @@ msgstr "User-ID \"%s\" bereits verkleinert: %s\n" #, c-format msgid "User ID \"%s\": %d signature removed\n" -msgstr "User-ID \"%s\": %d Signatur entfernt\n" - -#, c-format -msgid "User ID \"%s\": %d signatures removed\n" -msgstr "User-ID \"%s\": %d Signaturen entfernt\n" +msgid_plural "User ID \"%s\": %d signatures removed\n" +msgstr[0] "User-ID \"%s\": %d Signatur entfernt\n" +msgstr[1] "User-ID \"%s\": %d Signaturen entfernt\n" #, c-format msgid "User ID \"%s\": already minimized\n" @@ -4013,39 +4017,6 @@ msgid "Please correct the error first\n" msgstr "Bitte beseitigen Sie zuerst den Fehler\n" msgid "" -"You need a Passphrase to protect your secret key.\n" -"\n" -msgstr "" -"Sie ben?tigen eine Passphrase, um den geheimen Schl?ssel zu sch?tzen.\n" -"\n" - -msgid "" -"Please enter a passphrase to protect the off-card backup of the new " -"encryption key." -msgstr "" -"Bitte geben Sie die Passphrase ein, um die Sicherheitskopie des neuen " -"Verschl?sselungsschl?ssel der Karte zu sch?tzen." - -msgid "passphrase not correctly repeated; try again" -msgstr "Passphrase wurde nicht richtig wiederholt; noch einmal versuchen" - -#, c-format -msgid "%s.\n" -msgstr "%s.\n" - -msgid "" -"You don't want a passphrase - this is probably a *bad* idea!\n" -"I will do it anyway. You can change your passphrase at any time,\n" -"using this program with the option \"--edit-key\".\n" -"\n" -msgstr "" -"Sie m?chten keine Passphrase - Dies ist *nicht* zu empfehlen!\n" -"Es ist trotzdem m?glich. Sie k?nnen Ihre Passphrase jederzeit\n" -"?ndern, indem sie dieses Programm mit dem Befehl \"--edit-key\"\n" -"aufrufen.\n" -"\n" - -msgid "" "We need to generate a lot of random bytes. It is a good idea to perform\n" "some other action (type on the keyboard, move the mouse, utilize the\n" "disks) during the prime generation; this gives the random number\n" @@ -4090,6 +4061,14 @@ msgid "Key generation canceled.\n" msgstr "Schl?sselerzeugung abgebrochen.\n" #, c-format +msgid "can't create backup file '%s': %s\n" +msgstr "Sicherungsdatei '%s' kann nicht erzeugt werden: %s\n" + +#, c-format +msgid "Note: backup of card key saved to '%s'\n" +msgstr "Hinweis: Sicherung des Kartenschl?ssels wurde auf `%s' gespeichert\n" + +#, c-format msgid "writing public key to '%s'\n" msgstr "schreiben des ?ffentlichen Schl?ssels nach '%s'\n" @@ -4138,18 +4117,6 @@ msgstr "Geheime Teile des Hauptschl?ssels sind auf der Karte gespeichert.\n" msgid "Really create? (y/N) " msgstr "Wirklich erzeugen? (j/N) " -#, c-format -msgid "storing key onto card failed: %s\n" -msgstr "Speicher des Schl?ssels auf der Karte schlug fehl: %s\n" - -#, c-format -msgid "can't create backup file '%s': %s\n" -msgstr "Sicherungsdatei '%s' kann nicht erzeugt werden: %s\n" - -#, c-format -msgid "Note: backup of card key saved to '%s'\n" -msgstr "Hinweis: Sicherung des Kartenschl?ssels wurde auf `%s' gespeichert\n" - msgid "never " msgstr "niemals " @@ -4168,16 +4135,17 @@ msgstr "Entscheidender Beglaubigungs-\"Notation\": " msgid "Signature notation: " msgstr "Beglaubigungs-\"Notation\": " -msgid "1 good signature\n" -msgstr "1 korrekte Signatur\n" - #, c-format -msgid "%d good signatures\n" -msgstr "%d korrekte Signaturen\n" +msgid "%d good signature\n" +msgid_plural "%d good signatures\n" +msgstr[0] "%d korrekte Signatur\n" +msgstr[1] "%d korrekte Signaturen\n" #, c-format -msgid "Warning: %lu key(s) skipped due to their large size\n" -msgstr "WARNUNG: %lu Schl?ssel ?bersprungen, da sie zu gro? sind\n" +msgid "Warning: %lu key skipped due to its large size\n" +msgid_plural "Warning: %lu keys skipped due to their large sizes\n" +msgstr[0] "WARNUNG: %lu Schl?ssel ?bersprungen, da er zu gro? ist\n" +msgstr[1] "WARNUNG: %lu Schl?ssel ?bersprungen, da sie zu gro? sind\n" msgid "Keyring" msgstr "Schl?sselbund" @@ -4207,20 +4175,26 @@ msgid " Card serial no. =" msgstr " Kartenseriennr. =" #, c-format -msgid "renaming '%s' to '%s' failed: %s\n" -msgstr "umbenennen von `%s' nach `%s' schlug fehl: %s\n" - -#, c-format msgid "caching keyring '%s'\n" msgstr "Puffern des Schl?sselbundes `%s'\n" #, c-format -msgid "%lu keys cached so far (%lu signatures)\n" -msgstr "%lu Schl?ssel bislang gepuffert (%lu Beglaubigungen)\n" +msgid "%lu keys cached so far (%lu signature)\n" +msgid_plural "%lu keys cached so far (%lu signatures)\n" +msgstr[0] "%lu Schl?ssel bislang gepuffert (%lu Beglaubigung)\n" +msgstr[1] "%lu Schl?ssel bislang gepuffert (%lu Beglaubigungen)\n" + +#, c-format +msgid "%lu key cached" +msgid_plural "%lu keys cached" +msgstr[0] "%lu Schl?ssel gepuffert" +msgstr[1] "%lu Schl?ssel gepuffert" #, c-format -msgid "%lu keys cached (%lu signatures)\n" -msgstr "%lu Schl?ssel gepuffert (%lu Beglaubigungen)\n" +msgid " (%lu signature)\n" +msgid_plural " (%lu signatures)\n" +msgstr[0] " (%lu Beglaubigung)\n" +msgstr[1] " (%lu Beglaubigungen)\n" #, c-format msgid "%s: keyring created\n" @@ -4263,18 +4237,16 @@ msgid "\"%s\" not a key ID: skipping\n" msgstr "\"%s\" ist keine Schl?ssel-ID: ?berspringe\n" #, c-format -msgid "refreshing 1 key from %s\n" -msgstr "ein Schl?ssel wird per %s aktualisiert\n" +msgid "refreshing %d key from %s\n" +msgid_plural "refreshing %d keys from %s\n" +msgstr[0] "%d Schl?ssel wird per %s aktualisiert\n" +msgstr[1] "%d Schl?ssel werden per %s aktualisiert\n" #, c-format msgid "WARNING: unable to refresh key %s via %s: %s\n" msgstr "WARNUNG: Schl?ssel %s kann per %s nicht aktualisiert werden: %s\n" #, c-format -msgid "refreshing %d keys from %s\n" -msgstr "%d Schl?ssel werden per %s aktualisiert\n" - -#, c-format msgid "key \"%s\" not found on keyserver\n" msgstr "Schl?ssel \"%s\" wurde auf dem Schl?sselserver nicht gefunden\n" @@ -4515,6 +4487,17 @@ msgid "Note: signatures using the %s algorithm are rejected\n" msgstr "Hinweis: %s basierte Signaturen werden zur?ckgewiesen.\n" #, c-format +msgid "(reported error: %s)\n" +msgstr "(gemeldeter Fehler: %s)\n" + +#, c-format +msgid "(reported error: %s <%s>)\n" +msgstr "(gemeldeter Fehler: %s <%s>)\n" + +msgid "(further info: " +msgstr "(weitere Infos: " + +#, c-format msgid "%s:%d: deprecated option \"%s\"\n" msgstr "%s:%d: mi?billigte Option \"%s\".\n" @@ -4934,6 +4917,18 @@ msgstr "%s: ?bersprungen: ?ffentlicher Schl?ssel ist abgeschaltet\n" msgid "%s: skipped: public key already present\n" msgstr "%s: ?bersprungen: ?ffentlicher Schl?ssel bereits vorhanden\n" +#, c-format +msgid "can't encrypt to '%s'\n" +msgstr "Verschl?sseln an '%s' ist nicht m?glich\n" + +#, c-format +msgid "option '%s' given, but no valid default keys given\n" +msgstr "Option '%s' ohne g?ltige Standardschl?ssel angegeben\n" + +#, c-format +msgid "option '%s' given, but option '%s' not given\n" +msgstr "Option '%s' ohne Verwendung der Option '%s' angegeben\n" + msgid "You did not specify a user ID. (you may use \"-r\")\n" msgstr "" "Sie haben keine User-ID angegeben (Sie k?nnen die Option \"-r\" verwenden).\n" @@ -4980,10 +4975,6 @@ msgid "data not saved; use option \"--output\" to save it\n" msgstr "" "Daten wurden nicht gespeichert; verwenden Sie daf?r die Option \"--output\"\n" -#, c-format -msgid "error creating '%s': %s\n" -msgstr "Fehler beim Erstellen von `%s': %s\n" - msgid "Detached signature.\n" msgstr "Abgetrennte Beglaubigungen.\n" @@ -5102,6 +5093,10 @@ msgstr "Geheimer Schl?ssel \"%s\" nicht gefunden\n" msgid "'%s' matches multiple secret keys:\n" msgstr "'%s' trifft auf mehrere geheime Schl?ssel zu:\n" +#, c-format +msgid "error searching the keyring: %s\n" +msgstr "Fehler beim Suchen im Schl?sselbund: %s\n" + msgid "Create a revocation certificate for this key? (y/N) " msgstr "Ein Widerrufszertifikat f?r diesen Schl?ssel erzeugen? (j/N) " @@ -5184,24 +5179,38 @@ msgstr "WARNUNG: Signaturunterschl?ssel %s hat eine ung?ltige R?cksignatur\n" #, c-format msgid "public key %s is %lu second newer than the signature\n" -msgstr "?ffentlicher Schl?ssel %s ist %lu Sekunden j?nger als die Signatur\n" +msgid_plural "public key %s is %lu seconds newer than the signature\n" +msgstr[0] "?ffentlicher Schl?ssel %s ist %lu Sekunde j?nger als die Signatur\n" +msgstr[1] "" +"?ffentlicher Schl?ssel %s ist %lu Sekunden j?nger als die Signatur\n" #, c-format -msgid "public key %s is %lu seconds newer than the signature\n" -msgstr "?ffentlicher Schl?ssel %s ist %lu Sekunden j?nger als die Signatur\n" +msgid "public key %s is %lu day newer than the signature\n" +msgid_plural "public key %s is %lu days newer than the signature\n" +msgstr[0] "?ffentlicher Schl?ssel %s ist %lu Tag j?nger als die Signatur\n" +msgstr[1] "?ffentlicher Schl?ssel %s ist %lu Tage j?nger als die Signatur\n" #, c-format msgid "" "key %s was created %lu second in the future (time warp or clock problem)\n" -msgstr "" +msgid_plural "" +"key %s was created %lu seconds in the future (time warp or clock problem)\n" +msgstr[0] "" +"Schl?ssel %s wurde %lu Sekunde in der Zukunft erzeugt (Zeitreise oder " +"Uhrenproblem)\n" +msgstr[1] "" "Schl?ssel %s wurde %lu Sekunden in der Zukunft erzeugt (Zeitreise oder " "Uhrenproblem)\n" #, c-format -msgid "" -"key %s was created %lu seconds in the future (time warp or clock problem)\n" -msgstr "" -"Schl?ssel %s wurde %lu Sekunden in der Zukunft erzeugt (Zeitreise oder " +msgid "key %s was created %lu day in the future (time warp or clock problem)\n" +msgid_plural "" +"key %s was created %lu days in the future (time warp or clock problem)\n" +msgstr[0] "" +"Schl?ssel %s wurde %lu Tag in der Zukunft erzeugt (Zeitreise oder " +"Uhrenproblem)\n" +msgstr[1] "" +"Schl?ssel %s wurde %lu Tage in der Zukunft erzeugt (Zeitreise oder " "Uhrenproblem)\n" #, c-format @@ -5436,6 +5445,267 @@ msgid "input line longer than %d characters\n" msgstr "Eingabezeile ist l?nger als %d Zeichen\n" #, c-format +msgid "error beginning transaction on TOFU database: %s\n" +msgstr "Fehler beim Starten einer Transaktion auf der TOFU Datenbank: %s\n" + +#, c-format +msgid "error committing transaction on TOFU database: %s\n" +msgstr "Fehler beim Committen einer Transaktion auf der TOFU Datenbank: %s\n" + +#, c-format +msgid "error rolling back transaction on TOFU database: %s\n" +msgstr "" +"Fehler beim Zur?ckrollen einer Transaktion auf der TOFU Datenbank: %s\n" + +#, c-format +msgid "unsupported TOFU database version: %s\n" +msgstr "Nicht unterst?tzte TOFU Datenbank Version: %s\n" + +#, c-format +msgid "error reading TOFU database: %s\n" +msgstr "Fehler beim Lesen der TOFU Datenbank: %s\n" + +#, c-format +msgid "error determining TOFU database's version: %s\n" +msgstr "Fehler beim Feststellen der TOFU Datenbank Version: %s\n" + +#, c-format +msgid "error initializing TOFU database: %s\n" +msgstr "Fehler beim Initialisieren der TOFU Datenbank: %s\n" + +#, c-format +msgid "error opening TOFU database '%s': %s\n" +msgstr "Fehler beim ?ffner der TOFU Datenbank '%s': %s\n" + +msgid "Warning: Home directory contains both tofu.db and tofu.d.\n" +msgstr "" +"WARNUNG: Das Home-Verzeichnis hat sowohl 'tofu.db' als auch 'tofu.d'.\n" + +msgid "Using split format for TOFU database\n" +msgstr "Das \"Split\" Format wird f?r die TOFU Datenbank benutzt\n" + +#, c-format +msgid "error updating TOFU database: %s\n" +msgstr "Fehler beim Schreiben der TOFU Datenbank: %s\n" + +#, c-format +msgid "public key %s not found: %s\n" +msgstr "?ffentlicher Schl?ssel %s nicht gefunden: %s\n" + +#, c-format +msgid "error setting TOFU binding's trust level to %s\n" +msgstr "Fehler beim Setzen der TOFU Binding Vertrauensstufe auf %s\n" + +#, c-format +msgid "The binding %s is NOT known." +msgstr "Die Bindung %s ist NICHT bekannt." + +#, c-format +msgid "" +"The key %s raised a conflict with this binding (%s). Since this binding's " +"policy was 'auto', it was changed to 'ask'." +msgstr "" +"Der Schl?ssel %s steht im Konflikt mit der Bindung (%s). Die Richtlinie " +"dieser Bindung wurde deswegen von 'auto' auf 'ask' ge?ndert." + +#, c-format +msgid "" +"Please indicate whether you believe the binding %s%sis legitimate (the key " +"belongs to the stated owner) or a forgery (bad)." +msgstr "" +"Bitte geben Sie Ihre Einsch?tzung, ob die Bindung %s%s legitim (der " +"Schl?ssel geh?rt dem angegebenen Besitzer) oder eine F?lschung (ung?ltig) " +"ist." + +#, c-format +msgid "error gathering other user IDs: %s\n" +msgstr "Fehler beim Einsammeln der ?brigen User-IDs: %s\n" + +msgid "Known user IDs associated with this key:\n" +msgstr "Bekannte, mit diesem Schl?ssel assozierte, User-IDs:\n" + +#, c-format +msgid "policy: %s" +msgstr "Richtlinie: %s" + +#, c-format +msgid "error gathering signature stats: %s\n" +msgstr "Fehler beim Einsammeln der Signaturstatistik: %s\n" + +#, c-format +msgid "The email address \"%s\" is associated with %d key:\n" +msgid_plural "The email address \"%s\" is associated with %d keys:\n" +msgstr[0] "Die Email-Adresse \"%s\" ist mit einem Schl?ssel assoziert:\n" +msgstr[1] "Die Email-Adresse \"%s\" ist mit %d Schl?sseln assoziert:\n" + +#, c-format +msgid "Statistics for keys with the email address \"%s\":\n" +msgstr "Statistik f?r Schl?ssel mit der Email-Adresse \"%s\":\n" + +msgid "this key" +msgstr "dieser Schl?ssel" + +#, c-format +msgid "%ld message signed in the future." +msgid_plural "%ld messages signed in the future." +msgstr[0] "%ld Nachricht in der Zukunft signiert." +msgstr[1] "%ld Nachrichten in der Zukunf signiert." + +#, c-format +msgid "%ld message signed" +msgid_plural "%ld messages signed" +msgstr[0] "%ld Nachricht signiert" +msgstr[1] "%ld Nachrichten signiert" + +#, c-format +msgid " over the past %ld day." +msgid_plural " over the past %ld days." +msgstr[0] " innerhalb des letzten Tages." +msgstr[1] " innerhalb der letzten %ld Tage." + +#, c-format +msgid " over the past %ld week." +msgid_plural " over the past %ld weeks." +msgstr[0] " innerhalb der letzten Woche." +msgstr[1] " innerhalb der letzten %ld Wochen." + +#, c-format +msgid " over the past %ld month." +msgid_plural " over the past %ld months." +msgstr[0] " innerhalb des letzten Monats." +msgstr[1] " innerhalb der letzten %ld Monate." + +#. TRANSLATORS: Please translate the text found in the source +#. file below. We don't directly internationalize that text +#. so that we can tweak it without breaking translations. +msgid "TOFU detected a binding conflict" +msgstr "" +"Normalerweise ist lediglich ein Schl?ssel mit einer Email-Adresse " +"assoziiert. Es kann allerdings vorkommen, da? Leute einen neuen Schl?ssel " +"erzeugen, wenn ihr alter Schl?ssel zu alt ist oder wenn sie glauben, er " +"k?nnte kompromittiert sein. Es kann allerdings auch sein, da? ein neuer " +"Schl?ssel einen Man-in-the-Middle Angriff aufzeigt! Bevor Sie diesen neuen " +"Schl?ssel akzeptieren, sollten sie die Person, auf einem anderen Weg, fragen " +"ob der neue Schl?ssel legitim ist." + +#. TRANSLATORS: Two letters (normally the lower and upper case +#. version of the hotkey) for each of the five choices. If +#. there is only one choice in your language, repeat it. +msgid "gGaAuUrRbB" +msgstr "gGaAuUlLfF" + +msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? " +msgstr "(G)ut, einmal (A)kzeptieren, (U)nbekannt, einmal ab(L)ehnen, (F)alsch?" + +#, c-format +msgid "error changing TOFU policy: %s\n" +msgstr "Fehler beim ?ndern der TOFU Richtlinie: %s\n" + +#, c-format +msgid "%d year" +msgid_plural "%d years" +msgstr[0] "%d Jahr" +msgstr[1] "%d Jahre" + +#, c-format +msgid "%d month" +msgid_plural "%d months" +msgstr[0] "%d Monat" +msgstr[1] "%d Monate" + +#, c-format +msgid "%d day" +msgid_plural "%d days" +msgstr[0] "%d Tag" +msgstr[1] "%d Tage" + +#, c-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d Stunde" +msgstr[1] "%d Stunden" + +#, c-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d Minute" +msgstr[1] "%d Minuten" + +#, c-format +msgid "%d second" +msgid_plural "%d seconds" +msgstr[0] "%d Sekunde" +msgstr[1] "%d Sekunden" + +#, c-format +msgid "Have never verified a message signed by key %s!\n" +msgstr "Es wurde noch keine Nachricht mit dem Schl?ssel %s ?berpr?ft!\n" + +#, c-format +msgid "Failed to collect signature statistics for \"%s\" (key %s)\n" +msgstr "" +"Signaturstatistiken f?r \"%s\" (Schl?ssel %s) konnten nicht gesammelt " +"werden\n" + +#, c-format +msgid "Verified 0 messages signed by \"%s\" (key: %s, policy: %s)." +msgstr "" +"Keine von \"%s\" signierten Nachrichten ?berpr?ft (Schl.: %s, Richtl.: %s)." + +#. TRANSLATORS: The final %s is replaced by a string like +#. "7 months, 1 day, 5 minutes, 0 seconds". +#, c-format +msgid "" +"Verified %ld message signed by \"%s\" (key: %s, policy: %s) in the past %s." +msgid_plural "" +"Verified %ld messages signed by \"%s\" (key: %s, policy: %s) in the past %s." +msgstr[0] "" +"%ld von \"%s\" (Schl.: %s, Richtl.: %s) signierte Nachricht in den letzten " +"%s ?berpr?ft." +msgstr[1] "" +"%ld von \"%s\" (Schl.: %s, Richtl.: %s) signierte Nachrichten in den letzten " +"%s ?berpr?ft." + +#, c-format +msgid "The most recent message was verified %s ago." +msgstr "Die neueste Nachricht wurde vor %s ?berpr?ft." + +msgid "Warning: we've have yet to see a message signed by this key!\n" +msgstr "" +"WARNUNG: Wir m?ssen noch eine mit diesem Schl?ssel signierte Nachricht " +"sehen.\n" + +msgid "Warning: we've only seen a single message signed by this key!\n" +msgstr "" +"WARNUNG: Wir haben nur eine einzige mit diesem Schl?ssel signierte Nachricht " +"gesehen.\n" + +#. TRANSLATORS: translate the below text. We don't +#. directly internationalize that text so that we can +#. tweak it without breaking translations. +#, c-format +msgid "TOFU: few signatures %d message %s" +msgid_plural "TOFU: few signatures %d messages %s" +msgstr[0] "" +"WARNUNG: Falls sie glauben, mehr als %d mit diesem Schl?ssel signierte\n" +"Nachricht erhalten zu haben, so kann es sich bei diesem Schl?ssel um\n" +"eine F?lschung handeln! Pr?fen Sie die Email-Adresse genau auf kleine\n" +"Variationen (z.B. zus?tzliche Leerzeichen). Falls Ihnen der Schl?ssel\n" +"suspekt erscheint, so benutzen Sie '%s' um den Schl?ssel als F?lschung\n" +"zu markieren." +msgstr[1] "" +"WARNUNG: Falls sie glauben, mehr als %d mit diesem Schl?ssel signierte\n" +"Nachrichten erhalten zu haben, so kann es sich bei diesem Schl?ssel um\n" +"eine F?lschung handeln! Pr?fen Sie die Email-Adresse genau auf kleine\n" +"Variationen (z.B. zus?tzliche Leerzeichen). Falls Ihnen der Schl?ssel\n" +"suspekt erscheint, so benutzen Sie '%s' um den Schl?ssel als F?lschung\n" +"zu markieren." + +#, c-format +msgid "error opening TOFU database: %s\n" +msgstr "Fehler beim ?ffnen der TOFU Datenbank: %s\n" + +#, c-format msgid "'%s' is not a valid long keyID\n" msgstr "'%s' ist keine g?ltige lange Schl?ssel-ID\n" @@ -5498,20 +5768,24 @@ msgstr "\"Trust-DB\"-?berpr?fung ist beim `%s'-Vertrauensmodell nicht n?tig\n msgid "no need for a trustdb update with '%s' trust model\n" msgstr "\"Trust-DB\"-?nderung ist beim `%s'-Vertrauensmodell nicht n?tig\n" -#, c-format -msgid "public key %s not found: %s\n" -msgstr "?ffentlicher Schl?ssel %s nicht gefunden: %s\n" - msgid "please do a --check-trustdb\n" msgstr "Bitte ein --check-trustdb durchf?hren\n" msgid "checking the trustdb\n" msgstr "\"Trust-DB\" wird ?berpr?ft\n" +#, c-format +msgid "%d key processed" +msgid_plural "%d keys processed" +msgstr[0] "%d Schl?ssel bislang bearbeitet" +msgstr[1] "%d Schl?ssel bislang bearbeitet" + # translated by wk #, c-format -msgid "%d keys processed (%d validity counts cleared)\n" -msgstr "%d Schl?ssel verarbeitet (%d Validity Z?hler gel?scht)\n" +msgid " (%d validity count cleared)\n" +msgid_plural " (%d validity counts cleared)\n" +msgstr[0] " (%d Validity Z?hler gel?scht)\n" +msgstr[1] " (%d Validity Z?hler gel?scht)\n" msgid "no ultimately trusted keys found\n" msgstr "keine ultimativ vertrauensw?rdigen Schl?ssel gefunden\n" @@ -5521,10 +5795,6 @@ msgid "public key of ultimately trusted key %s not found\n" msgstr "?ff. Schl?ssel des ultimativ vertrauten Schl?ssel %s nicht gefunden\n" #, c-format -msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n" -msgstr "%d marginal-needed, %d complete-needed, %s Vertrauensmodell\n" - -#, c-format msgid "" "depth: %d valid: %3d signed: %3d trust: %d-, %dq, %dn, %dm, %df, %du\n" msgstr "" @@ -5731,8 +6001,11 @@ msgid "card is permanently locked!\n" msgstr "Karte ist dauerhaft gesperrt!\n" #, c-format -msgid "%d Admin PIN attempts remaining before card is permanently locked\n" -msgstr "Noch %d Admin-PIN-Versuche, bis die Karte dauerhaft gesperrt ist\n" +msgid "%d Admin PIN attempt remaining before card is permanently locked\n" +msgid_plural "" +"%d Admin PIN attempts remaining before card is permanently locked\n" +msgstr[0] "Noch %d Admin-PIN-Versuch, bis die Karte dauerhaft gesperrt ist\n" +msgstr[1] "Noch %d Admin-PIN-Versuche, bis die Karte dauerhaft gesperrt ist\n" #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at #. the start of the string. Use %%0A to force a linefeed. @@ -5810,8 +6083,10 @@ msgid "generating key failed\n" msgstr "Schl?sselerzeugung fehlgeschlagen\n" #, c-format -msgid "key generation completed (%d seconds)\n" -msgstr "Schl?sselerzeugung abgeschlossen (%d Sekunden)\n" +msgid "key generation completed (%d second)\n" +msgid_plural "key generation completed (%d seconds)\n" +msgstr[0] "Schl?sselerzeugung abgeschlossen (%d Sekunde)\n" +msgstr[1] "Schl?sselerzeugung abgeschlossen (%d Sekunden)\n" msgid "invalid structure of OpenPGP card (DO 0x93)\n" msgstr "Ung?ltige Struktur der OpenPGP-Karte (DO 0x93)\n" @@ -8252,27 +8527,164 @@ msgstr "" "Syntax: gpg-check-pattern [optionen] Musterdatei\n" "Die von stdin gelesene Passphrase gegen die Musterdatei pr?fen\n" -#~ msgid "cleared passphrase cached with ID: %s\n" -#~ msgstr "Passphrase aus dem Cache gel?scht. Cache ID: %s\n" +#~ msgid "error commiting transaction on TOFU database: %s\n" +#~ msgstr "" +#~ "Fehler beim Committen einer Transaktion auf der TOFU Datenbank: %s\n" #, fuzzy -#~ msgid "Failed to open the keyring DB.\n" -#~ msgstr "Fehler beim ?ffnen der Schl?sseldatenbank.\n" +#~| msgid "error binding socket to '%s': %s\n" +#~ msgid "error beginning %s transaction on TOFU database '%s': %s\n" +#~ msgstr "Der Socket kann nicht an `%s' gebunden werden: %s\n" #, fuzzy +#~| msgid "error retrieving '%s' via %s: %s\n" +#~ msgid "error querying TOFU DB's available tables: %s\n" +#~ msgstr "Fehler beim automatischen holen von `%s' ?ber `%s': %s\n" + +#, fuzzy +#~| msgid "error reading nonce on fd %d: %s\n" +#~ msgid "error aborting transaction on TOFU DB: %s\n" +#~ msgstr "Fehler beim Lesen der \"Nonce\" von FD %d: %s\n" + +#, fuzzy +#~| msgid "error getting version from '%s': %s\n" +#~ msgid "error committing transaction on TOFU DB: %s\n" +#~ msgstr "Fehler beim Holen der Version von '%s': %s\n" + +#, fuzzy +#~| msgid "can't open '%s': %s\n" +#~ msgid "can't open TOFU DB ('%s'): %s\n" +#~ msgstr "'%s' kann nicht ge?ffnet werden: %s\n" + +#, fuzzy +#~| msgid "can't create directory '%s': %s\n" +#~ msgid "unable to create directory %s/%s/%s/%s" +#~ msgstr "Verzeichnis `%s' kann nicht erzeugt werden: %s\n" + +#, fuzzy +#~| msgid "error reading from responder: %s\n" +#~ msgid "error reading from TOFU database: bad value for policy: %s\n" +#~ msgstr "Fehler beim Lesen vom Responder: %s\n" + +#, fuzzy +#~| msgid "error reading from responder: %s\n" +#~ msgid "error reading from TOFU database (listing fingerprints): %s\n" +#~ msgstr "Fehler beim Lesen vom Responder: %s\n" + +#, fuzzy +#~| msgid "error opening key DB: %s\n" +#~ msgid "error opening TOFU DB.\n" +#~ msgstr "Fehler beim ?ffnen der Schl?sseldatenbank: %s\n" + +#, fuzzy +#~| msgid "key %s: %s\n" +#~ msgid " %s\n" +#~ msgstr "Schl?ssel %s: %s\n" + +#, fuzzy +#~| msgid " s = skip this key\n" +#~ msgid " %s (this key):" +#~ msgstr " s = diesen Schl?ssel ?berspringen\n" + +#~ msgid "key specification '%s' is ambiguous\n" +#~ msgstr "Schl?sselangabe '%s' ist mehrdeutig\n" + +#~ msgid "'%s' matches at least:\n" +#~ msgstr "'%s' pa?t mindest auf:\n" + +#~ msgid "%d signatures not checked due to missing keys\n" +#~ msgstr "%d Beglaubigungen wegen fehlenden Schl?sseln nicht gepr?ft\n" + +#~ msgid "%d signatures not checked due to errors\n" +#~ msgstr "%d Beglaubigungen aufgrund von Fehlern nicht gepr?ft\n" + +#~ msgid "1 user ID without valid self-signature detected\n" +#~ msgstr "Eine User-ID ohne g?ltige Eigenbeglaubigung entdeckt\n" + +#~ msgid "Deleted %d signatures.\n" +#~ msgstr "%d Beglaubigungen entfernt.\n" + +#~ msgid "User ID \"%s\": %d signatures removed\n" +#~ msgstr "User-ID \"%s\": %d Signaturen entfernt\n" + +#~ msgid "" +#~ "You need a Passphrase to protect your secret key.\n" +#~ "\n" +#~ msgstr "" +#~ "Sie ben?tigen eine Passphrase, um den geheimen Schl?ssel zu sch?tzen.\n" +#~ "\n" + +#~ msgid "" +#~ "Please enter a passphrase to protect the off-card backup of the new " +#~ "encryption key." +#~ msgstr "" +#~ "Bitte geben Sie die Passphrase ein, um die Sicherheitskopie des neuen " +#~ "Verschl?sselungsschl?ssel der Karte zu sch?tzen." + +#~ msgid "passphrase not correctly repeated; try again" +#~ msgstr "Passphrase wurde nicht richtig wiederholt; noch einmal versuchen" + +#~ msgid "%s.\n" +#~ msgstr "%s.\n" + +#~ msgid "" +#~ "You don't want a passphrase - this is probably a *bad* idea!\n" +#~ "I will do it anyway. You can change your passphrase at any time,\n" +#~ "using this program with the option \"--edit-key\".\n" +#~ "\n" +#~ msgstr "" +#~ "Sie m?chten keine Passphrase - Dies ist *nicht* zu empfehlen!\n" +#~ "Es ist trotzdem m?glich. Sie k?nnen Ihre Passphrase jederzeit\n" +#~ "?ndern, indem sie dieses Programm mit dem Befehl \"--edit-key\"\n" +#~ "aufrufen.\n" +#~ "\n" + +#~ msgid "storing key onto card failed: %s\n" +#~ msgstr "Speicher des Schl?ssels auf der Karte schlug fehl: %s\n" + +#~ msgid "1 good signature\n" +#~ msgstr "1 korrekte Signatur\n" + +#~ msgid "renaming '%s' to '%s' failed: %s\n" +#~ msgstr "umbenennen von `%s' nach `%s' schlug fehl: %s\n" + +#~ msgid "%lu keys cached (%lu signatures)\n" +#~ msgstr "%lu Schl?ssel gepuffert (%lu Beglaubigungen)\n" + +#~ msgid "refreshing 1 key from %s\n" +#~ msgstr "ein Schl?ssel wird per %s aktualisiert\n" + +#~ msgid "public key %s is %lu seconds newer than the signature\n" +#~ msgstr "" +#~ "?ffentlicher Schl?ssel %s ist %lu Sekunden j?nger als die Signatur\n" + +#~ msgid "" +#~ "key %s was created %lu seconds in the future (time warp or clock " +#~ "problem)\n" +#~ msgstr "" +#~ "Schl?ssel %s wurde %lu Sekunden in der Zukunft erzeugt (Zeitreise oder " +#~ "Uhrenproblem)\n" + +#~ msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n" +#~ msgstr "%d marginal-needed, %d complete-needed, %s Vertrauensmodell\n" + +#~ msgid "cleared passphrase cached with ID: %s\n" +#~ msgstr "Passphrase aus dem Cache gel?scht. Cache ID: %s\n" + +#~ msgid "Failed to open the keyring DB\n" +#~ msgstr "Fehler beim ?ffnen der Schl?sseldatenbank\n" + #~| msgid "failed to open '%s': %s\n" #~ msgid "Failed to parse '%s'.\n" -#~ msgstr "Datei `%s' kann nicht ge?ffnet werden: %s\n" +#~ msgstr "Datei `%s' kann nicht gescannt werden\n" -#, fuzzy #~| msgid "invalid value\n" #~ msgid "invalid value '%s'\n" -#~ msgstr "Ung?ltiger Wert.\n" +#~ msgstr "Ung?ltiger Wert '%s'\n" -#, fuzzy #~| msgid "error reading secret keyblock \"%s\": %s\n" #~ msgid "error looking up secret key \"%s\": %s\n" -#~ msgstr "Fehler beim Lesen des geheimen Schl?sselblocks \"%s\": %s\n" +#~ msgstr "Fehler beim Nachschlagen der geheimen Schl?ssels \"%s\": %s\n" #~ msgid "Please select at most one subkey.\n" #~ msgstr "Bitte w?hlen Sie h?chstens einen Unterschl?ssel aus.\n" commit cfa41890bb5ff306c07dad295136601fe47566a7 Author: Werner Koch Date: Tue Jan 19 16:29:27 2016 +0100 gpg: Streamline use of error messages in tofu.c * g10/tofu.c: Make use of print_further_info to reduce the number of different error messages to be translated. Also streamline some messages. Signed-off-by: Werner Koch diff --git a/g10/tofu.c b/g10/tofu.c index e593083..6a88172 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -261,9 +261,10 @@ begin_transaction (struct db *db, int only_batch) "savepoint batch;", SQLITE_ARG_END); if (rc) { - log_error - (_("error beginning %s transaction on TOFU database '%s': %s\n"), - "batch", *db->name ? db->name : "combined", err); + log_error (_("error beginning transaction on TOFU database: %s\n"), + err); + print_further_info ("batch, database '%s'", + *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -279,9 +280,10 @@ begin_transaction (struct db *db, int only_batch) "savepoint inner;", SQLITE_ARG_END); if (rc) { - log_error - (_("error beginning %s transaction on TOFU database '%s': %s\n"), - "inner", *db->name ? db->name : "combined", err); + log_error (_("error beginning transaction on TOFU database: %s\n"), + err); + print_further_info ("inner, database '%s'", + *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -313,9 +315,10 @@ end_transaction (struct db *db, int only_batch) "release batch;", SQLITE_ARG_END); if (rc) { - log_error - (_("error committing %s transaction on TOFU database '%s': %s\n"), - "batch", *db->name ? db->name : "combined", err); + log_error (_("error committing transaction on TOFU database: %s\n"), + err); + print_further_info ("batch, database '%s'", + *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -333,9 +336,10 @@ end_transaction (struct db *db, int only_batch) "release inner;", SQLITE_ARG_END); if (rc) { - log_error - (_("error committing %s transaction on TOFU database '%s': %s\n"), - "inner", *db->name ? db->name : "combined", err); + log_error (_("error committing transaction on TOFU database: %s\n"), + err); + print_further_info ("inner, database '%s'", + *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -362,9 +366,10 @@ rollback_transaction (struct db *db) if (rc) { - log_error - (_("error rolling back inner transaction on TOFU database '%s': %s\n"), - *db->name ? db->name : "combined", err); + log_error (_("error rolling back transaction on TOFU database: %s\n"), + err); + print_further_info ("inner, database '%s'", + *db->name ? db->name : "[combined]"); sqlite3_free (err); return gpg_error (GPG_ERR_GENERAL); } @@ -443,7 +448,7 @@ version_check_cb (void *cookie, int argc, char **argv, char **azColName) *version = 1; else { - log_error (_("unsupported TOFU DB version: %s\n"), argv[0]); + log_error (_("unsupported TOFU database version: %s\n"), argv[0]); *version = -1; } @@ -480,8 +485,8 @@ initdb (sqlite3 *db, enum db_type type) get_single_unsigned_long_cb, &count, &err); if (rc) { - log_error (_("error querying TOFU DB's available tables: %s\n"), - err); + log_error (_("error reading TOFU database: %s\n"), err); + print_further_info ("query available tables"); sqlite3_free (err); goto out; } @@ -508,16 +513,16 @@ initdb (sqlite3 *db, enum db_type type) else if (rc) /* Some error. */ { - log_error (_("error determining TOFU DB's version: %s\n"), err); + log_error (_("error determining TOFU database's version: %s\n"), err); sqlite3_free (err); goto out; } else - /* Unexpected success. This can only happen if there are no - rows. */ - { - log_error (_("error determining TOFU DB's version: %s\n"), - "select returned 0, but expected ABORT"); + { + /* Unexpected success. This can only happen if there are no + rows. (select returned 0, but expected ABORT.) */ + log_error (_("error determining TOFU database's version: %s\n"), + gpg_strerror (GPG_ERR_NO_DATA)); rc = 1; goto out; } @@ -529,8 +534,8 @@ initdb (sqlite3 *db, enum db_type type) NULL, NULL, &err); if (rc) { - log_error (_("error initializing TOFU database (%s): %s\n"), - "version", err); + log_error (_("error initializing TOFU database: %s\n"), err); + print_further_info ("create version"); sqlite3_free (err); goto out; } @@ -542,37 +547,37 @@ initdb (sqlite3 *db, enum db_type type) NULL, NULL, &err); if (rc) { - log_error (_("error initializing TOFU database (%s): %s\n"), - "version, init", err); + log_error (_("error initializing TOFU database: %s\n"), err); + print_further_info ("insert version"); sqlite3_free (err); goto out; } /* The list of bindings and auxiliary data. - - OID is a unique ID identifying this binding (and used by the - signatures table, see below). Note: OIDs will never be - reused. - - FINGERPRINT: The key's fingerprint. - - EMAIL: The normalized email address. - - USER_ID: The unmodified user id from which EMAIL was extracted. - - TIME: The time this binding was first observed. - - POLICY: The trust policy (TOFU_POLICY_BAD, etc. as an integer). - - CONFLICT is either NULL or a fingerprint. Assume that we have - a binding <0xdeadbeef, foo at example.com> and then we observe - <0xbaddecaf, foo at example.com>. There two bindings conflict - (they have the same email address). When we observe the - latter binding, we warn the user about the conflict and ask - for a policy decision about the new binding. We also change - the old binding's policy to ask if it was auto. So that we - know why this occurred, we also set conflict to 0xbaddecaf. - */ + * + * OID is a unique ID identifying this binding (and used by the + * signatures table, see below). Note: OIDs will never be + * reused. + * + * FINGERPRINT: The key's fingerprint. + * + * EMAIL: The normalized email address. + * + * USER_ID: The unmodified user id from which EMAIL was extracted. + * + * TIME: The time this binding was first observed. + * + * POLICY: The trust policy (TOFU_POLICY_BAD, etc. as an integer). + * + * CONFLICT is either NULL or a fingerprint. Assume that we have + * a binding <0xdeadbeef, foo at example.com> and then we observe + * <0xbaddecaf, foo at example.com>. There two bindings conflict + * (they have the same email address). When we observe the + * latter binding, we warn the user about the conflict and ask + * for a policy decision about the new binding. We also change + * the old binding's policy to ask if it was auto. So that we + * know why this occurred, we also set conflict to 0xbaddecaf. + */ if (type == DB_EMAIL || type == DB_COMBINED) rc = sqlite3_exec_printf (db, NULL, NULL, &err, @@ -603,8 +608,8 @@ initdb (sqlite3 *db, enum db_type type) " on bindings (fingerprint);\n"); if (rc) { - log_error (_("error initializing TOFU database (%s): %s\n"), - "bindings", err); + log_error (_("error initializing TOFU database: %s\n"), err); + print_further_info ("create bindings"); sqlite3_free (err); goto out; } @@ -633,8 +638,8 @@ initdb (sqlite3 *db, enum db_type type) NULL, NULL, &err); if (rc) { - log_error (_("error initializing TOFU database (%s): %s\n"), - "signatures", err); + log_error (_("error initializing TOFU database: %s\n"), err); + print_further_info ("create signatures"); sqlite3_free (err); goto out; } @@ -646,7 +651,7 @@ initdb (sqlite3 *db, enum db_type type) rc = sqlite3_exec (db, "rollback;", NULL, NULL, &err); if (rc) { - log_error (_("error aborting transaction on TOFU DB: %s\n"), + log_error (_("error rolling back transaction on TOFU database: %s\n"), err); sqlite3_free (err); } @@ -657,7 +662,7 @@ initdb (sqlite3 *db, enum db_type type) rc = sqlite3_exec (db, "end transaction;", NULL, NULL, &err); if (rc) { - log_error (_("error committing transaction on TOFU DB: %s\n"), + log_error (_("error committing transaction on TOFU database: %s\n"), err); sqlite3_free (err); return 1; @@ -692,8 +697,8 @@ opendb (char *filename, enum db_type type) rc = sqlite3_open (filename, &db); if (rc) { - log_error (_("can't open TOFU DB ('%s'): %s\n"), - filename, sqlite3_errmsg (db)); + log_error (_("error opening TOFU database '%s': %s\n"), + filename, sqlite3_errmsg (db)); /* Even if an error occurs, DB is guaranteed to be valid. */ sqlite3_close (db); db = NULL; @@ -755,6 +760,7 @@ getdb (struct dbs *dbs, const char *name, enum db_type type) char *filename = NULL; int need_link = 1; sqlite3 *sqlitedb = NULL; + gpg_error_t rc; assert (dbs); assert (name); @@ -826,10 +832,14 @@ getdb (struct dbs *dbs, const char *name, enum db_type type) char *name_db; /* Make the directory. */ - if (gnupg_mkdir_p (opt.homedir, "tofu.d", type_str, prefix, NULL) != 0) + rc = gnupg_mkdir_p (opt.homedir, "tofu.d", type_str, prefix, NULL); + if (rc) { - log_error (_("unable to create directory %s/%s/%s/%s"), - opt.homedir, "tofu.d", type_str, prefix); + name_db = xstrconcat (opt.homedir, "tofu.d", + type_str, prefix, NULL); + log_error (_("can't create directory '%s': %s\n"), + name_db, gpg_strerror (rc)); + xfree (name_db); goto out; } @@ -906,6 +916,8 @@ closedb (struct db *db) /* Create a new DB meta-handle. Returns NULL on error. */ +/* FIXME: Change to return an error code for better reporting by the + caller. */ static struct dbs * opendbs (void) { @@ -947,26 +959,27 @@ opendbs (void) if (have_tofu_db && have_tofu_d) { log_info (_("Warning: Home directory contains both tofu.db" - " and tofu.d. Using split format for TOFU DB.\n")); + " and tofu.d.\n")); + log_info (_("Using split format for TOFU database\n")); opt.tofu_db_format = TOFU_DB_SPLIT; } else if (have_tofu_db) { opt.tofu_db_format = TOFU_DB_FLAT; if (DBG_TRUST) - log_debug ("Using flat format for TOFU DB.\n"); + log_debug ("Using flat format for TOFU database.\n"); } else if (have_tofu_d) { opt.tofu_db_format = TOFU_DB_SPLIT; if (DBG_TRUST) - log_debug ("Using split format for TOFU DB.\n"); + log_debug ("Using split format for TOFU database.\n"); } else { opt.tofu_db_format = TOFU_DB_FLAT; if (DBG_TRUST) - log_debug ("Using flat format for TOFU DB.\n"); + log_debug ("Using flat format for TOFU database.\n"); } } @@ -1075,7 +1088,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, { char *fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); struct db *db_email = NULL, *db_key = NULL; - int rc; + gpg_error_t rc; char *err = NULL; /* policy_old needs to be a long and not an enum tofu_policy, because we pass it by reference to get_single_long_cb2, which @@ -1091,7 +1104,10 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, db_email = getdb (dbs, email, DB_EMAIL); if (! db_email) - return gpg_error (GPG_ERR_GENERAL); + { + rc = gpg_error (GPG_ERR_GENERAL); + goto leave; + } if (opt.tofu_db_format == TOFU_DB_SPLIT) /* In the split format, we need to update two DBs. To keep them @@ -1102,11 +1118,14 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, { db_key = getdb (dbs, fingerprint, DB_KEY); if (! db_key) - return gpg_error (GPG_ERR_GENERAL); + { + rc = gpg_error (GPG_ERR_GENERAL); + goto leave; + } rc = begin_transaction (db_email, 0); if (rc) - return gpg_error (GPG_ERR_GENERAL); + goto leave; rc = begin_transaction (db_key, 0); if (rc) @@ -1116,7 +1135,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, { rc = begin_transaction (db_email, 1); if (rc) - return gpg_error (GPG_ERR_GENERAL); + goto leave; } @@ -1174,10 +1193,9 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, SQLITE_ARG_END); if (rc) { - log_error (_("error updating TOFU binding database" - " (inserting <%s, %s> = %s): %s\n"), - fingerprint_pp, email, tofu_policy_str (policy), - err); + log_error (_("error updating TOFU database: %s\n"), err); + print_further_info (" insert bindings <%s, %s> = %s", + fingerprint_pp, email, tofu_policy_str (policy)); sqlite3_free (err); goto out; } @@ -1202,9 +1220,9 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, SQLITE_ARG_STRING, user_id, SQLITE_ARG_END); if (rc) { - log_error (_("error updating TOFU binding database" - " (inserting <%s, %s>): %s\n"), - fingerprint_pp, email, err); + log_error (_("error updating TOFU database: %s\n"), err); + print_further_info ("insert bindings <%s, %s>", + fingerprint_pp, email); sqlite3_free (err); goto out; } @@ -1216,18 +1234,14 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, if (opt.tofu_db_format == TOFU_DB_SPLIT) /* We only need a transaction for the split format. */ { - int rc2; + gpg_error_t rc2; if (rc) rc2 = rollback_transaction (db_key); else rc2 = end_transaction (db_key, 0); if (rc2) - { - log_error (_("error ending transaction on TOFU database: %s\n"), - err); - sqlite3_free (err); - } + sqlite3_free (err); out_revert_one: if (rc) @@ -1235,18 +1249,13 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email, else rc2 = end_transaction (db_email, 0); if (rc2) - { - log_error (_("error ending transaction on TOFU database: %s\n"), - err); - sqlite3_free (err); - } + sqlite3_free (err); } + leave: xfree (fingerprint_pp); - if (rc) - return gpg_error (GPG_ERR_GENERAL); - return 0; + return rc; } @@ -1461,9 +1470,8 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email, SQLITE_ARG_END); if (rc) { - log_error (_("error reading from TOFU database" - " (checking for existing bad bindings): %s\n"), - err); + log_error (_("error reading TOFU database: %s\n"), err); + print_further_info ("checking for existing bad bindings"); sqlite3_free (err); goto out; } @@ -1477,10 +1485,11 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email, else if (strlist_length (strlist) != 2) /* The result has the wrong form. */ { - log_error (_("error reading from TOFU database" - " (checking for existing bad bindings):" - " expected 2 results, got %d\n"), - strlist_length (strlist)); + log_error (_("error reading TOFU database: %s\n"), + gpg_strerror (GPG_ERR_BAD_DATA)); + print_further_info ("checking for existing bad bindings:" + " expected 2 results, got %d\n", + strlist_length (strlist)); goto out; } @@ -1490,8 +1499,9 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email, policy = strtol (strlist->d, &tail, 0); if (errno || *tail != '\0') { - log_error (_("error reading from TOFU database: bad value for policy: %s\n"), - strlist->d); + log_error (_("error reading TOFU database: %s\n"), + gpg_strerror (GPG_ERR_BAD_DATA)); + print_further_info ("bad value for policy: %s", strlist->d); goto out; } @@ -1501,8 +1511,9 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email, || policy == TOFU_POLICY_BAD || policy == TOFU_POLICY_ASK)) { - log_error (_("TOFU DB is corrupted. Invalid value for policy (%d).\n"), - policy); + log_error (_("error reading TOFU database: %s\n"), + gpg_strerror (GPG_ERR_DB_CORRUPTED)); + print_further_info ("invalid value for policy (%d)", policy); policy = _tofu_GET_POLICY_ERROR; goto out; } @@ -1711,9 +1722,8 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, SQLITE_ARG_STRING, email, SQLITE_ARG_END); if (rc) { - log_error (_("error reading from TOFU database" - " (listing fingerprints): %s\n"), - err); + log_error (_("error reading TOFU database: %s\n"), err); + print_further_info ("listing fingerprints"); sqlite3_free (err); goto out; } @@ -1863,7 +1873,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_END); if (rc) { - log_error (_("error gathering other user ids: %s.\n"), err); + log_error (_("error gathering other user IDs: %s\n"), err); sqlite3_free (err); err = NULL; } @@ -2327,9 +2337,8 @@ show_statistics (struct dbs *dbs, const char *fingerprint, sig_exclude ? "'" : ""); if (rc) { - log_error (_("error reading from TOFU database" - " (getting statistics): %s\n"), - err); + log_error (_("error reading TOFU database: %s\n"), err); + print_further_info ("getting statistics"); sqlite3_free (err); goto out; } @@ -2556,7 +2565,8 @@ tofu_register (PKT_public_key *pk, const char *user_id, dbs = opendbs (); if (! dbs) { - log_error (_("error opening TOFU DB.\n")); + log_error (_("error opening TOFU database: %s\n"), + gpg_strerror (GPG_ERR_GENERAL)); goto die; } @@ -2589,7 +2599,8 @@ tofu_register (PKT_public_key *pk, const char *user_id, db = getdb (dbs, email, DB_EMAIL); if (! db) { - log_error (_("error opening TOFU DB.\n")); + log_error (_("error opening TOFU database: %s\n"), + gpg_strerror (GPG_ERR_GENERAL)); goto die; } @@ -2615,9 +2626,8 @@ tofu_register (PKT_public_key *pk, const char *user_id, SQLITE_ARG_END); if (rc) { - log_error (_("error reading from signatures database" - " (checking existence): %s\n"), - err); + log_error (_("error reading TOFU database: %s\n"), err); + print_further_info ("checking existence"); sqlite3_free (err); } else if (c > 1) @@ -2662,9 +2672,8 @@ tofu_register (PKT_public_key *pk, const char *user_id, SQLITE_ARG_END); if (rc) { - log_error (_("error updating TOFU DB" - " (inserting into signatures table): %s\n"), - err); + log_error (_("error updating TOFU database: %s\n"), err); + print_further_info ("insert signatures"); sqlite3_free (err); } } @@ -2677,7 +2686,6 @@ tofu_register (PKT_public_key *pk, const char *user_id, rc = end_transaction (db, 0); if (rc) { - log_error (_("error ending transaction on TOFU database: %s\n"), err); sqlite3_free (err); goto die; } @@ -2771,7 +2779,8 @@ tofu_get_validity (PKT_public_key *pk, const char *user_id, dbs = opendbs (); if (! dbs) { - log_error (_("error opening TOFU DB.\n")); + log_error (_("error opening TOFU database: %s\n"), + gpg_strerror (GPG_ERR_GENERAL)); goto die; } @@ -2823,7 +2832,8 @@ tofu_set_policy (kbnode_t kb, enum tofu_policy policy) dbs = opendbs (); if (! dbs) { - log_error (_("error opening TOFU DB.\n")); + log_error (_("error opening TOFU database: %s\n"), + gpg_strerror (GPG_ERR_GENERAL)); return gpg_error (GPG_ERR_GENERAL); } @@ -2902,7 +2912,8 @@ tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, dbs = opendbs (); if (! dbs) { - log_error (_("error opening TOFU DB.\n")); + log_error (_("error opening TOFU database: %s\n"), + gpg_strerror (GPG_ERR_GENERAL)); return gpg_error (GPG_ERR_GENERAL); } commit 8b7f64f9dfc80b2a0ad235996b47369c2ba9b48f Author: Werner Koch Date: Tue Jan 19 16:26:28 2016 +0100 common: Add substitute code for libgpg-error < 1.22. * common/util.h (GPG_ERR_DB_CORRUPTED): New. diff --git a/common/util.h b/common/util.h index 5d94e93..6410b11 100644 --- a/common/util.h +++ b/common/util.h @@ -37,8 +37,10 @@ /* These error codes are used but not defined in the required libgpg-error version. Define them here. */ -/* None right now. (Use #if GPG_ERROR_VERSION_NUMBER < 0x011500 / * 1.21) */ - +/* Example: (#if GPG_ERROR_VERSION_NUMBER < 0x011500 // 1.21) */ +#if GPG_ERROR_VERSION_NUMBER < 0x011600 /* 1.22 */ +# define GPG_ERR_DB_CORRUPTED 218 +#endif /* gpg_error < 1.22 */ /* Hash function used with libksba. */ #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write) commit d96e76d15f61812b950b64a60bc47117785a9dac Author: Werner Koch Date: Tue Jan 19 16:25:31 2016 +0100 gpg: Add function print_further_info. * g10/misc.c (print_further_info): New. Signed-off-by: Werner Koch diff --git a/g10/main.h b/g10/main.h index 503f262..ec24426 100644 --- a/g10/main.h +++ b/g10/main.h @@ -90,6 +90,7 @@ void print_cipher_algo_note (cipher_algo_t algo); void print_digest_algo_note (digest_algo_t algo); void print_digest_rejected_note (enum gcry_md_algos algo); void print_reported_error (gpg_error_t err, gpg_err_code_t skip_if_ec); +void print_further_info (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); void additional_weak_digest (const char* digestname); /*-- armor.c --*/ diff --git a/g10/misc.c b/g10/misc.c index 5e764fa..bdc4505 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -383,6 +383,27 @@ print_reported_error (gpg_error_t err, gpg_err_code_t ignore_ec) } +/* Print a message + * "(further info: %s)\n + * in verbose mode to further explain an error. That message is + * intended to help debug a problem and should not be translated. + */ +void +print_further_info (const char *format, ...) +{ + va_list arg_ptr; + + if (!opt.verbose) + return; + + log_info (_("(further info: ")); + va_start (arg_ptr, format); + log_logv (GPGRT_LOG_CONT, format, arg_ptr); + va_end (arg_ptr); + log_printf (")\n"); +} + + /* Map OpenPGP algo numbers to those used by Libgcrypt. We need to do this for algorithms we implemented in Libgcrypt after they become part of OpenPGP. */ ----------------------------------------------------------------------- Summary of changes: common/util.h | 6 +- g10/main.h | 1 + g10/misc.c | 21 ++ g10/tofu.c | 257 ++++++++++---------- po/de.po | 752 +++++++++++++++++++++++++++++++++++++++++++++------------- 5 files changed, 742 insertions(+), 295 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 19 18:06:49 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 19 Jan 2016 18:06:49 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.21-4-gb3bb6e2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via b3bb6e2cc31208a198e74b42ca495c08ebb00fc4 (commit) from 71370060aae7a83f4d6c3b9c924f204a57cc2538 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b3bb6e2cc31208a198e74b42ca495c08ebb00fc4 Author: Werner Koch Date: Tue Jan 19 18:02:01 2016 +0100 Add GPG_ERR_DB_CORRUPTED. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 0b361d5..b8d6be5 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ Noteworthy changes in version 1.22 (unreleased) [C17/A17/R_) ----------------------------------------------- + * Interface changes relative to the 1.20 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPG_ERR_DB_CORRUPTED NEW. + + Noteworthy changes in version 1.21 (2015-12-12) [C17/A17/R0] ----------------------------------------------- diff --git a/doc/errorref.txt b/doc/errorref.txt index 89c0723..22b78fc 100644 --- a/doc/errorref.txt +++ b/doc/errorref.txt @@ -624,6 +624,8 @@ GPG_ERR_MAC_ALGO 212 GPG_ERR_SEXP_ODD_HEX_NUMBERS Odd hexadecimal numbers in S-expression 213 GPG_ERR_SEXP_BAD_OCT_CHAR Bad octal character in S-expression +GPG_ERR_DB_CORRUPTED (218) Database is corrupted + GPG_ERR_SERVER_FAILED (219) Server indicated a failure GPG_ERR_NO_NAME (220) No name diff --git a/src/err-codes.h.in b/src/err-codes.h.in index d481145..887ea78 100644 --- a/src/err-codes.h.in +++ b/src/err-codes.h.in @@ -247,8 +247,8 @@ 212 GPG_ERR_SEXP_ODD_HEX_NUMBERS Odd hexadecimal numbers in S-expression 213 GPG_ERR_SEXP_BAD_OCT_CHAR Bad octal character in S-expression -# 214 to 218 are free to be used. - +# 214 to 217 are free to be used. +218 GPG_ERR_DB_CORRUPTED Database is corrupted 219 GPG_ERR_SERVER_FAILED Server indicated a failure 220 GPG_ERR_NO_NAME No name 221 GPG_ERR_NO_KEY No key ----------------------------------------------------------------------- Summary of changes: NEWS | 5 +++++ doc/errorref.txt | 2 ++ src/err-codes.h.in | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 20 10:53:43 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 20 Jan 2016 10:53:43 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-132-gc26d299 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via c26d299ef64caa0e8322e70546b833c9b8476fc3 (commit) from 4c6c973950df1471544f5d485e4cc2f4603bbd77 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c26d299ef64caa0e8322e70546b833c9b8476fc3 Author: Werner Koch Date: Wed Jan 20 10:48:50 2016 +0100 doc: Typo fix. -- diff --git a/doc/gpg.texi b/doc/gpg.texi index e0374d4..c6731c0 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2275,7 +2275,7 @@ a passphrase if @option{--personal-cipher-preferences} and @item --s2k-digest-algo @code{name} @opindex s2k-digest-algo Use @code{name} as the digest algorithm used to mangle the passphrases -for symmetric encryption. The defaulte is SHA-1. +for symmetric encryption. The default is SHA-1. @item --s2k-mode @code{n} @opindex s2k-mode ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 20 11:27:55 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 20 Jan 2016 11:27:55 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-133-g4997433 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 499743387f4d07847a2842358bc54f9237e0c2a7 (commit) from c26d299ef64caa0e8322e70546b833c9b8476fc3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 499743387f4d07847a2842358bc54f9237e0c2a7 Author: Werner Koch Date: Wed Jan 20 11:22:44 2016 +0100 agent: New option --pinentry-timeout * agent/gpg-agent.c (oPinentryTimeout): New. (opts): Add new option. (parse_rereadable_options): PArse that option. (main): Tell gpgconf about this option. * agent/call-pinentry.c (start_pinentry): Send option to Pinentry. * tools/gpgconf-comp.c (gc_options_gpg_agent): Add Option. -- GnuPG-bug-id: 2222 Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index 6e24df4..c7e1433 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -94,6 +94,11 @@ struct custom invisible character. */ char *pinentry_invisible_char; + /* The timeout value for the Pinentry in seconds. This is passed to + the pinentry if it is not 0. It is up to the pinentry to act + upon this timeout value. */ + unsigned long pinentry_timeout; + /* The default and maximum TTL of cache entries. */ unsigned long def_cache_ttl; /* Default. */ unsigned long def_cache_ttl_ssh; /* for SSH. */ diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 33e3ec3..0f24086 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -491,6 +491,18 @@ start_pinentry (ctrl_t ctrl) } } + if (opt.pinentry_timeout) + { + char *optstr; + if ((optstr = xtryasprintf ("SETTIMEOUT %lu", opt.pinentry_timeout))) + { + assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + /* We ignore errors because this is just a fancy thing. */ + xfree (optstr); + } + } + /* Tell the pinentry the name of a file it shall touch after having messed with the tty. This is optional and only supported by newer pinentries and thus we do no error checking. */ diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index b60287d..3095531 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -93,6 +93,7 @@ enum cmd_and_opt_values oPinentryProgram, oPinentryTouchFile, oPinentryInvisibleChar, + oPinentryTimeout, oDisplay, oTTYname, oTTYtype, @@ -168,6 +169,7 @@ static ARGPARSE_OPTS opts[] = { /* */ N_("|PGM|use PGM as the PIN-Entry program")), ARGPARSE_s_s (oPinentryTouchFile, "pinentry-touch-file", "@"), ARGPARSE_s_s (oPinentryInvisibleChar, "pinentry-invisible-char", "@"), + ARGPARSE_s_u (oPinentryTimeout, "pinentry-timeout", "@"), ARGPARSE_s_s (oScdaemonProgram, "scdaemon-program", /* */ N_("|PGM|use PGM as the SCdaemon program") ), ARGPARSE_s_n (oDisableScdaemon, "disable-scdaemon", @@ -580,6 +582,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) opt.pinentry_touch_file = NULL; xfree (opt.pinentry_invisible_char); opt.pinentry_invisible_char = NULL; + opt.pinentry_timeout = 0; opt.scdaemon_program = NULL; opt.def_cache_ttl = DEFAULT_CACHE_TTL; opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL_SSH; @@ -632,6 +635,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) xfree (opt.pinentry_invisible_char); opt.pinentry_invisible_char = xtrystrdup (pargs->r.ret_str); break; break; + case oPinentryTimeout: opt.pinentry_timeout = pargs->r.ret_ulong; break; case oScdaemonProgram: opt.scdaemon_program = pargs->r.ret_str; break; case oDisableScdaemon: opt.disable_scdaemon = 1; break; case oDisableCheckOwnSocket: disable_check_own_socket = 1; break; @@ -1124,6 +1128,8 @@ main (int argc, char **argv ) GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); es_printf ("allow-emacs-pinentry:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + es_printf ("pinentry-timeout:%lu:0:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME); agent_exit (0); } diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 4e18b92..f4da9cf 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -402,6 +402,13 @@ This option asks the Pinentry to use @var{char} for displaying hidden characters. @var{char} must be one character UTF-8 string. A Pinentry may or may not honor this request. + at item --pinentry-timeout @var{n} + at opindex pinentry-timeout +This option asks the Pinentry to timeout after @var{n} seconds with no +user input. The default value of 0 does not ask the pinentry to +timeout, however a Pinentry may use its own default timeout value in +this case. A Pinentry may or may not honor this request. + @item --pinentry-program @var{filename} @opindex pinentry-program Use program @var{filename} as the PIN entry. The default is diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 5e4bd58..45e5c90 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -582,6 +582,10 @@ static gc_option_t gc_options_gpg_agent[] = GC_LEVEL_EXPERT, "gnupg", N_("do not allow the reuse of old passphrases"), GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, + { "pinentry-timeout", GC_OPT_FLAG_RUNTIME, + GC_LEVEL_ADVANCED, "gnupg", + N_("|N|set the Pinentry timeout to N seconds"), + GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, GC_OPTION_NULL }; ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 5 +++++ agent/call-pinentry.c | 12 ++++++++++++ agent/gpg-agent.c | 6 ++++++ doc/gpg-agent.texi | 7 +++++++ tools/gpgconf-comp.c | 4 ++++ 5 files changed, 34 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 20 16:21:31 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 20 Jan 2016 16:21:31 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-134-gbdb6135 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via bdb61351776c038d668310d9b5e5c32588ef6519 (commit) from 499743387f4d07847a2842358bc54f9237e0c2a7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bdb61351776c038d668310d9b5e5c32588ef6519 Author: Werner Koch Date: Wed Jan 20 15:51:18 2016 +0100 gpg: Silence message about ignoring revoked user ids. * g10/trustdb.c (tdb_get_validity_core): Print message only in debug mode. -- This makes only sense for debugging. Signed-off-by: Werner Koch diff --git a/g10/trustdb.c b/g10/trustdb.c index d3a186f..8f2b2cb 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1041,18 +1041,22 @@ tdb_get_validity_core (PKT_public_key *pk, PKT_user_id *uid, else user_id = user_id_node->pkt->pkt.user_id; + /* If the user id is revoked or expired, then skip it. */ if (user_id->is_revoked || user_id->is_expired) - /* If the user id is revoked or expired, then skip it. */ { - char *s; - if (user_id->is_revoked && user_id->is_expired) - s = "revoked and expired"; - else if (user_id->is_revoked) - s = "revoked"; - else - s = "expire"; - - log_info ("TOFU: Ignoring %s user id (%s)\n", s, user_id->name); + if (DBG_TRUST) + { + char *s; + if (user_id->is_revoked && user_id->is_expired) + s = "revoked and expired"; + else if (user_id->is_revoked) + s = "revoked"; + else + s = "expire"; + + log_debug ("TOFU: Ignoring %s user id (%s)\n", + s, user_id->name); + } continue; } ----------------------------------------------------------------------- Summary of changes: g10/trustdb.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 21 11:54:51 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Jan 2016 11:54:51 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-135-g09117e7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 09117e769a093467cb47154f36d7dda613313e33 (commit) from bdb61351776c038d668310d9b5e5c32588ef6519 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 09117e769a093467cb47154f36d7dda613313e33 Author: Werner Koch Date: Thu Jan 21 11:49:27 2016 +0100 gpg: Make --auto-key-retrieve work with dirmngr configured server. * g10/call-dirmngr.c (gpg_dirmngr_ks_list): Make R_KEYSERVER optional. * g10/keyserver.c (keyserver_any_configured): New. (keyserver_put): Remove arg keyserver because this will always receive opt.keyserver which is anyway used when connecting dirmngr. Do not check opt.keyserver. (keyserver_import_cert): Replace opt.keyserver by keyserver_any_configured. * g10/mainproc.c (check_sig_and_print): Ditto. * g10/import.c (revocation_present): Ditto. * g10/getkey.c (get_pubkey_byname): Ditto. * g10/gpgv.c (keyserver_any_configured): Add stub. * g10/test-stubs.c (keyserver_any_configured): Add stub. -- The keyserver should be configured in dirmngr.conf and thus we can't use opt.keyserver in gpg to decide whether a keyserver has been configured. GnuPG-bug-id: 2147 Signed-off-by: Werner Koch diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index 360e127..e596533 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -404,7 +404,8 @@ gpg_dirmngr_ks_list (ctrl_t ctrl, char **r_keyserver) memset (&stparm, 0, sizeof stparm); stparm.keyword = "KEYSERVER"; - *r_keyserver = NULL; + if (r_keyserver) + *r_keyserver = NULL; err = open_context (ctrl, &ctx); if (err) @@ -420,7 +421,10 @@ gpg_dirmngr_ks_list (ctrl_t ctrl, char **r_keyserver) goto leave; } - *r_keyserver = stparm.source; + if (r_keyserver) + *r_keyserver = stparm.source; + else + xfree (stparm.source); stparm.source = NULL; leave: diff --git a/g10/getkey.c b/g10/getkey.c index 9a4f81e..74fa753 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1333,9 +1333,9 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk, mailbox for the getname search, but it helps cut down on the problem of searching for something like "john" and getting a whole lot of keys back. */ - if (opt.keyserver) + if (keyserver_any_configured (ctrl)) { - mechanism = opt.keyserver->uri; + mechanism = "keyserver"; glo_ctrl.in_auto_key_retrieve++; rc = keyserver_import_name (ctrl, name, &fpr, &fpr_len, opt.keyserver); diff --git a/g10/gpgv.c b/g10/gpgv.c index 9932756..19a2ff6 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -345,6 +345,13 @@ keyserver_match (struct keyserver_spec *spec) } int +keyserver_any_configured (ctrl_t ctrl) +{ + (void)ctrl; + return 0; +} + +int keyserver_import_keyid (u32 *keyid, void *dummy) { (void)keyid; diff --git a/g10/import.c b/g10/import.c index 8e75aa1..369be35 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2471,9 +2471,9 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) char *tempkeystr=xstrdup(keystr_from_pk(pk)); /* No, so try and get it */ - if(opt.keyserver - && (opt.keyserver_options.options - & KEYSERVER_AUTO_KEY_RETRIEVE)) + if ((opt.keyserver_options.options + & KEYSERVER_AUTO_KEY_RETRIEVE) + && keyserver_any_configured (ctrl)) { log_info(_("WARNING: key %s may be revoked:" " fetching revocation key %s\n"), diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index 676b4db..6f6f430 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -31,6 +31,7 @@ struct keyserver_spec *keyserver_match(struct keyserver_spec *spec); struct keyserver_spec *parse_keyserver_uri (const char *string, int require_scheme); struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig); +int keyserver_any_configured (ctrl_t ctrl); int keyserver_export (ctrl_t ctrl, strlist_t users); int keyserver_import (ctrl_t ctrl, strlist_t users); int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, diff --git a/g10/keyserver.c b/g10/keyserver.c index b0af63d..e9ccb58 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -109,8 +109,7 @@ static gpg_error_t keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, struct keyserver_spec *override_keyserver, unsigned char **r_fpr, size_t *r_fprlen); -static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs, - struct keyserver_spec *keyserver); +static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs); /* Reasonable guess. The commonly used test key simon.josefsson.org @@ -1005,7 +1004,7 @@ keyserver_export (ctrl_t ctrl, strlist_t users) if(sl) { - rc = keyserver_put (ctrl, sl, opt.keyserver); + rc = keyserver_put (ctrl, sl); free_strlist(sl); } @@ -1132,6 +1131,14 @@ keyserver_import (ctrl_t ctrl, strlist_t users) } +/* Return true if any keyserver has been configured. */ +int +keyserver_any_configured (ctrl_t ctrl) +{ + return !gpg_dirmngr_ks_list (ctrl, NULL); +} + + /* Import all keys that exactly match NAME */ int keyserver_import_name (ctrl_t ctrl, const char *name, @@ -1380,7 +1387,12 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users) opt.keyserver_options.import_options|=IMPORT_FAST; /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO - scheme, then enable fake v3 keyid generation. */ + scheme, then enable fake v3 keyid generation. Note that this + works only with a keyserver configured. gpg.conf + (i.e. opt.keyserver); however that method of configuring a + keyserver is deprecated and in any case it is questionable + whether we should keep on supporting these ancient and broken + keyservers. */ if((opt.keyserver_options.options&KEYSERVER_ADD_FAKE_V3) && opt.keyserver && (ascii_strcasecmp(opt.keyserver->scheme,"hkp")==0 || ascii_strcasecmp(opt.keyserver->scheme,"mailto")==0)) @@ -1775,21 +1787,21 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, } -/* Send all keys specified by KEYSPECS to the KEYSERVERS. */ +/* Send all keys specified by KEYSPECS to the configured keyserver. */ static gpg_error_t -keyserver_put (ctrl_t ctrl, strlist_t keyspecs, - struct keyserver_spec *keyserver) +keyserver_put (ctrl_t ctrl, strlist_t keyspecs) { gpg_error_t err; strlist_t kspec; + char *ksurl; if (!keyspecs) return 0; /* Return success if the list is empty. */ - if (!opt.keyserver) + if (gpg_dirmngr_ks_list (ctrl, &ksurl)) { - log_error (_("no keyserver known (use option --keyserver)\n")); + log_error (_("no keyserver known\n")); return gpg_error (GPG_ERR_NO_KEYSERVER); } @@ -1807,14 +1819,9 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs, log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err)); else { - if (keyserver->host) - log_info (_("sending key %s to %s server %s\n"), - keystr (keyblock->pkt->pkt.public_key->keyid), - keyserver->scheme, keyserver->host); - else - log_info (_("sending key %s to %s\n"), - keystr (keyblock->pkt->pkt.public_key->keyid), - keyserver->uri); + log_info (_("sending key %s to %s\n"), + keystr (keyblock->pkt->pkt.public_key->keyid), + ksurl?ksurl:"[?]"); err = gpg_dirmngr_ks_put (ctrl, data, datalen, keyblock); release_kbnode (keyblock); @@ -1827,6 +1834,7 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs, } } + xfree (ksurl); return err; @@ -1940,15 +1948,15 @@ keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode, free_keyserver_spec(spec); } } - else if(opt.keyserver) + else if (keyserver_any_configured (ctrl)) { /* If only a fingerprint is provided, try and fetch it from - our --keyserver */ + the configured keyserver. */ err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver); } else - log_info(_("no keyserver known (use option --keyserver)\n")); + log_info(_("no keyserver known\n")); /* Give a better string here? "CERT fingerprint for \"%s\" found, but no keyserver" " known (use option diff --git a/g10/mainproc.c b/g10/mainproc.c index 8688325..5e6b40b 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1803,8 +1803,8 @@ check_sig_and_print (CTX c, kbnode_t node) no information from the DNS PKA, this is a third try. */ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - && opt.keyserver - && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)) + && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE) + && keyserver_any_configured (c->ctrl)) { int res; diff --git a/g10/test-stubs.c b/g10/test-stubs.c index a1988f0..74b6bf7 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -157,6 +157,13 @@ keyserver_match (struct keyserver_spec *spec) } int +keyserver_any_configured (ctrl_t ctrl) +{ + (void)ctrl; + return 0; +} + +int keyserver_import_keyid (u32 *keyid, void *dummy) { (void)keyid; ----------------------------------------------------------------------- Summary of changes: g10/call-dirmngr.c | 8 ++++++-- g10/getkey.c | 4 ++-- g10/gpgv.c | 7 +++++++ g10/import.c | 6 +++--- g10/keyserver-internal.h | 1 + g10/keyserver.c | 48 ++++++++++++++++++++++++++++-------------------- g10/mainproc.c | 4 ++-- g10/test-stubs.c | 7 +++++++ 8 files changed, 56 insertions(+), 29 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 21 18:58:53 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Jan 2016 18:58:53 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-136-gbb99b40 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via bb99b40bd1e624f58ca806ca16dc73d4d594a30a (commit) from 09117e769a093467cb47154f36d7dda613313e33 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bb99b40bd1e624f58ca806ca16dc73d4d594a30a Author: Werner Koch Date: Thu Jan 21 18:30:51 2016 +0100 gpg: Improve header text of the auto-created revocations. * g10/revoke.c (gen_standard_revoke): Improve header text for the file. Add info output. -- GnuPG-bug-id: 1724 Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index 69c2e5b..7d5a5a8 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -950,11 +950,6 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: All other data after this header is raw image (JPEG) data. -* Unattended key generation - - Please see the GnuPG manual for a description. - - * Layout of the TrustDB The TrustDB is built from fixed length records, where the first byte diff --git a/doc/gpg.texi b/doc/gpg.texi index c6731c0..e1835cf 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -587,7 +587,9 @@ may be used. @item --gen-key @opindex gen-key Generate a new key pair using the current default parameters. This is -the standard command to create a new key. +the standard command to create a new key. In addition to the key a +revocation certificate is created and stored in the + at file{openpgp-revocs.d} directory below the GnuPG home directory. @item --full-gen-key @opindex gen-key @@ -595,13 +597,23 @@ Generate a new key pair with dialogs for all options. This is an extended version of @option{--gen-key}. There is also a feature which allows you to create keys in batch -mode. See the the manual section ``Unattended key generation'' on how +mode. See the manual section ``Unattended key generation'' on how to use this. @item --gen-revoke @code{name} @opindex gen-revoke -Generate a revocation certificate for the complete key. To revoke -a subkey or a signature, use the @option{--edit} command. +Generate a revocation certificate for the complete key. To only revoke +a subkey or a key signature, use the @option{--edit} command. + +This command merely creates the revocation certificate so that it can +be used to revoke the key if that is ever needed. To actually revoke +a key the created revocation certificate needs to be merged with the +key to revoke. This is done by importing the revocation certificate +using the @option{--import} command. Then the revoked key needs to be +published, which is best done by sending the key to a keyserver +(command @option{--send-key}) and by exporting (@option{--export}) it +to a file which is then send to frequent communication partners. + @item --desig-revoke @code{name} @opindex desig-revoke diff --git a/g10/revoke.c b/g10/revoke.c index ba87f35..a8f7658 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -564,14 +564,18 @@ gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce) (int)len, tmpstr); xfree (tmpstr); - es_fprintf (memfp, "%s\n\n%s\n\n:", + es_fprintf (memfp, "%s\n\n%s\n\n%s\n\n:", + _("A revocation certificate is a kind of \"kill switch\" to publicly\n" + "declare that a key shall not anymore be used. It is not possible\n" + "to retract such a revocation certificate once it has been published."), _("Use it to revoke this key in case of a compromise or loss of\n" "the secret key. However, if the secret key is still accessible,\n" "it is better to generate a new revocation certificate and give\n" - "a reason for the revocation."), + "a reason for the revocation. For details see the description of\n" + "of the gpg command \"--gen-revoke\" in the GnuPG manual."), _("To avoid an accidental use of this file, a colon has been inserted\n" "before the 5 dashes below. Remove this colon with a text editor\n" - "before making use of this revocation certificate.")); + "before importing and publishing this revocation certificate.")); es_putc (0, memfp); @@ -583,6 +587,9 @@ gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce) reason.code = 0x00; /* No particular reason. */ reason.desc = NULL; rc = create_revocation (fname, &reason, psk, NULL, leadin, 3, cache_nonce); + if (!rc && !opt.quiet) + log_info (_("revocation certificate stored as '%s.rev'\n"), fname); + xfree (leadin); xfree (fname); ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 5 ----- doc/gpg.texi | 20 ++++++++++++++++---- g10/revoke.c | 13 ++++++++++--- 3 files changed, 26 insertions(+), 12 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 22 10:59:16 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 22 Jan 2016 10:59:16 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-138-g361820a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 361820a3be48def2237f734d1383633891972f62 (commit) via fc0c71dfe5ea8f1c683101948c23f5d2064ee4cd (commit) from bb99b40bd1e624f58ca806ca16dc73d4d594a30a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 361820a3be48def2237f734d1383633891972f62 Author: Werner Koch Date: Fri Jan 22 10:54:10 2016 +0100 gpg: Rework gpg-conf.skel -- Some of the options are too rarley used to deserve an entry in the skeleton config file. Some are even the default for many years. Added auto-key-locate because that is a very useful option. Signed-off-by: Werner Koch diff --git a/g10/options.skel b/g10/options.skel index e8f1882..87fc627 100644 --- a/g10/options.skel +++ b/g10/options.skel @@ -21,17 +21,15 @@ # GnuPG. If the first non white space character of a line is a '#', # this line is ignored. Empty lines are also ignored. # -# See the man page for a list of options. +# See the gpg man page for a list of options. -# Uncomment the following option to get rid of the copyright notice - -#no-greeting # If you have more than 1 secret key in your keyring, you may want to # uncomment the following option and set your preferred keyid. #default-key 621CC013 + # If you do not pass a recipient to gpg, it will ask for one. Using # this option you can encrypt to a default key. Key validation will # not be done in this case. The second form uses the default key as @@ -40,37 +38,6 @@ #default-recipient some-user-id #default-recipient-self -# By default GnuPG creates version 4 signatures for data files as -# specified by OpenPGP. Some earlier (PGP 6, PGP 7) versions of PGP -# require the older version 3 signatures. Setting this option forces -# GnuPG to create version 3 signatures. - -#force-v3-sigs - -# Because some mailers change lines starting with "From " to ">From " -# it is good to handle such lines in a special way when creating -# cleartext signatures; all other PGP versions do it this way too. -# To enable full OpenPGP compliance you may want to use this option. - -#no-escape-from-lines - -# When verifying a signature made from a subkey, ensure that the cross -# certification "back signature" on the subkey is present and valid. -# This protects against a subtle attack against subkeys that can sign. -# Defaults to --no-require-cross-certification. However for new -# installations it should be enabled. - -require-cross-certification - - -# If you do not use the Latin-1 (ISO-8859-1) charset, you should tell -# GnuPG which is the native character set. Please check the man page -# for supported character sets. This character set is only used for -# metadata and not for the actual message which does not undergo any -# translation. Note that future version of GnuPG will change to UTF-8 -# as default character set. - -#charset utf-8 # Group names may be defined like this: # group mynames = paige 0x12345678 joe patti @@ -84,16 +51,17 @@ require-cross-certification #group mynames = paige 0x12345678 joe patti -# Some old Windows platforms require 8.3 filenames. If your system -# can handle long filenames, uncomment this. -#no-mangle-dos-filenames +# GnuPG can automatically locate and retrieve keys as needed using +# this option. This happens when encrypting to an email address (in +# the "user@@example.com" form) and there are no keys matching +# "user at example.com" in the local keyring. This option takes any +# number mechanisms which are tried in the given order. The default +# is "--auto-key-locate local" to search for keys only in the local +# key database. Uncomment the next line to locate a missing key using +# two DNS based mechanisms. -# Lock the file only once for the lifetime of a process. If you do -# not define this, the lock will be obtained and released every time -# it is needed - normally this is not needed. - -#lock-once +#auto-key-locate local,pka,dane # Common options for keyserver functions: @@ -109,18 +77,6 @@ require-cross-certification # Can be used more than once to increase the amount # of information shown. # -# use-temp-files = use temporary files instead of a pipe to talk to the -# keyserver. Some platforms (Win32 for one) always -# have this on. -# -# keep-temp-files = do not delete temporary files after using them -# (really only useful for debugging) -# -# honor-http-proxy = if the keyserver uses HTTP, honor the http_proxy -# environment variable -# -# broken-http-proxy = try to work around a buggy HTTP proxy -# # auto-key-retrieve = automatically fetch keys as needed from the keyserver # when verifying signatures or when importing keys that # have been revoked by a revocation key that is not @@ -131,11 +87,13 @@ require-cross-certification #keyserver-options auto-key-retrieve + # Uncomment this line to display photo user IDs in key listings and # when a signature from a key with a photo is verified. #show-photos + # Use this program to display photo user IDs # # %i is expanded to a temporary file that contains the photo. @@ -166,3 +124,16 @@ require-cross-certification # # Use your MIME handler to view photos: # photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG" + + +# Because some mailers change lines starting with "From " to ">From " +# it is good to handle such lines in a special way when creating +# cleartext signatures; all other PGP versions do it this way too. +# To enable full OpenPGP compliance you may want to use this option. + +#no-escape-from-lines + + +# Uncomment the following option to get rid of the copyright notice + +#no-greeting commit fc0c71dfe5ea8f1c683101948c23f5d2064ee4cd Author: Werner Koch Date: Fri Jan 22 10:35:19 2016 +0100 gpg: Allow new user ids with only the mail address. * g10/keygen.c (ask_user_id): Allow empty name. -- The --quick-gen-key command allows this and further some mail providers require that a key has only the mail address to allow for anonymous accounts. Signed-off-by: Werner Koch diff --git a/g10/keygen.c b/g10/keygen.c index 94ea126..0f7a6a0 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2533,8 +2533,11 @@ ask_user_id (int mode, int full, KBNODE keyblock) } else if( digitp(aname) ) tty_printf(_("Name may not start with a digit\n")); - else if( strlen(aname) < 5 ) + else if (*aname && strlen (aname) < 5) + { tty_printf(_("Name must be at least 5 characters long\n")); + /* However, we allow an empty name. */ + } else break; } @@ -2577,11 +2580,20 @@ ask_user_id (int mode, int full, KBNODE keyblock) xfree(uid); uid = p = xmalloc(strlen(aname)+strlen(amail)+strlen(acomment)+12+10); - p = stpcpy(p, aname ); - if( *acomment ) - p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")"); - if( *amail ) - p = stpcpy(stpcpy(stpcpy(p," <"), amail),">"); + if (!*aname && *amail && !*acomment && !random_is_faked ()) + { /* Empty name and comment but with mail address. Use + simplified form with only the non-angle-bracketed mail + address. */ + p = stpcpy (p, amail); + } + else + { + p = stpcpy (p, aname ); + if (*acomment) + p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")"); + if (*amail) + p = stpcpy(stpcpy(stpcpy(p," <"), amail),">"); + } /* Append a warning if the RNG is switched into fake mode. */ if ( random_is_faked () ) ----------------------------------------------------------------------- Summary of changes: g10/keygen.c | 24 ++++++++++++----- g10/options.skel | 81 ++++++++++++++++++-------------------------------------- 2 files changed, 44 insertions(+), 61 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 22 12:39:55 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 22 Jan 2016 12:39:55 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-140-g77bceb2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 77bceb2902dd489443073d91836ea54376c60bf6 (commit) via afb8696126ff0babaab23e884ff5da008281e3b7 (commit) from 361820a3be48def2237f734d1383633891972f62 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 77bceb2902dd489443073d91836ea54376c60bf6 Author: Werner Koch Date: Fri Jan 22 12:34:50 2016 +0100 dirmngr: Provide the keyserver pool name even if there is no CNAME. * dirmngr/ks-engine-hkp.c (map_host): Fix setting of r_poolname. -- map_host is intended to return the name of the pool as an additional information. However this broke some time ago and a pool name was only retrained if the pool name was retrieved from a DNS CNAME. Signed-off-by: Werner Koch diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 598e614..eca02f0 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -545,9 +545,9 @@ 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 && hi->cname) + if (r_poolname) { - *r_poolname = xtrystrdup (hi->cname); + *r_poolname = xtrystrdup (hi->cname? hi->cname : hi->name); if (!*r_poolname) return gpg_error_from_syserror (); } commit afb8696126ff0babaab23e884ff5da008281e3b7 Author: Daniel Kahn Gillmor Date: Mon Oct 19 23:48:30 2015 -0400 dirmngr: Use sks-keyservers CA by default for the hkps pool. * dirmngr/Makefile.am (dist_pkgdata_DATA): Add sks-keyservers.netCA.pem. * dirmngr/http.c (http_session_new): Add optional arg intended_hostname and set a default cert. * dirmngr/ks-engine-hkp.c (send_request): Pass httphost to http_session_new. -- Ship the certificate for the sks-keyservers hkps pool. If the user has specified that they want to use hkps://hkps.pool.sks-keyservers.net, and they have not specified any hkp-cacert explicitly, then initialize the trust path with this specific trust anchor. Co-authored-by: wk at gnupg.org Signed-off-by: Werner Koch diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index c3bce0d..1c74d10 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -20,6 +20,7 @@ ## Process this file with automake to produce Makefile.in EXTRA_DIST = OAUTHORS ONEWS ChangeLog-2011 tls-ca.pem +dist_pkgdata_DATA = sks-keyservers.netCA.pem bin_PROGRAMS = dirmngr dirmngr-client diff --git a/dirmngr/http.c b/dirmngr/http.c index 74b6911..aa33917 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -562,7 +562,8 @@ http_session_release (http_session_t sess) /* Create a new session object which is currently used to enable TLS support. It may eventually allow reusing existing connections. */ gpg_error_t -http_session_new (http_session_t *r_session, const char *tls_priority) +http_session_new (http_session_t *r_session, const char *tls_priority, + const char *intended_hostname) { gpg_error_t err; http_session_t sess; @@ -600,6 +601,34 @@ http_session_new (http_session_t *r_session, const char *tls_priority) goto leave; } + /* If the user has not specified a CA list, and they are looking + * for the hkps pool from sks-keyservers.net, then default to + * Kristian's certificate authority: */ + if (!tls_ca_certlist + && intended_hostname + && !ascii_strcasecmp (intended_hostname, + "hkps.pool.sks-keyservers.net")) + { + char *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)); + } + else + { + rc = gnutls_certificate_set_x509_trust_file + (sess->certcred, pemname, GNUTLS_X509_FMT_PEM); + if (rc < 0) + log_info ("setting CA from file '%s' failed: %s\n", + pemname, gnutls_strerror (rc)); + xfree (pemname); + } + } + + /* Add configured certificates to the session. */ for (sl = tls_ca_certlist; sl; sl = sl->next) { rc = gnutls_certificate_set_x509_trust_file diff --git a/dirmngr/http.h b/dirmngr/http.h index 64f55e1..58b8c1a 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -98,7 +98,8 @@ void http_register_tls_callback (gpg_error_t (*cb)(http_t,http_session_t,int)); void http_register_tls_ca (const char *fname); gpg_error_t http_session_new (http_session_t *r_session, - const char *tls_priority); + const char *tls_priority, + const char *intended_hostname); http_session_t http_session_ref (http_session_t sess); void http_session_release (http_session_t sess); diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index f38f29a..598e614 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -991,7 +991,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, *r_fp = NULL; - err = http_session_new (&session, NULL); + err = http_session_new (&session, NULL, httphost); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index ae128ee..c51c0ce 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -65,7 +65,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp) estream_t fp = NULL; char *request_buffer = NULL; - err = http_session_new (&session, NULL); + err = http_session_new (&session, NULL, NULL); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 63662a2..9d5ea5f 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -262,7 +262,7 @@ main (int argc, char **argv) http_register_tls_callback (verify_callback); http_register_tls_ca (cafile); - err = http_session_new (&session, NULL); + err = http_session_new (&session, NULL, NULL); if (err) log_error ("http_session_new failed: %s\n", gpg_strerror (err)); ----------------------------------------------------------------------- Summary of changes: dirmngr/Makefile.am | 1 + dirmngr/http.c | 31 ++++++++++++++++++++++++++++++- dirmngr/http.h | 3 ++- dirmngr/ks-engine-hkp.c | 6 +++--- dirmngr/ks-engine-http.c | 2 +- dirmngr/t-http.c | 2 +- 6 files changed, 38 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 22 13:07:55 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 22 Jan 2016 13:07:55 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-141-g12c665b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 12c665b36cdc4b7189549698fc4cc1b3523b18f5 (commit) from 77bceb2902dd489443073d91836ea54376c60bf6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 12c665b36cdc4b7189549698fc4cc1b3523b18f5 Author: Werner Koch Date: Fri Jan 22 12:54:02 2016 +0100 dirmngr: Indicate that serial numbers are hexadecimal. * dirmngr/misc.c (hexify_data): Add arg with_prefix. Adjust all callers. * dirmngr/crlcache.c (cache_isvalid): Print "0x" in front of the S/N. -- GnuPG-bug-id: 1147 Signed-off-by: Werner Koch diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 13d8a26..25ce7a6 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -1345,12 +1345,13 @@ cache_isvalid (ctrl_t ctrl, const char *issuer_hash, if (n != 16) { log_error (_("WARNING: invalid cache record length for S/N ")); + log_printf ("0x"); log_printhex ("", sn, snlen); } else if (opt.verbose) { unsigned char record[16]; - char *tmp = hexify_data (sn, snlen); + char *tmp = hexify_data (sn, snlen, 1); if (cdb_read (cdb, record, n, cdb_datapos (cdb))) log_error (_("problem reading cache record for S/N %s: %s\n"), @@ -1366,7 +1367,7 @@ cache_isvalid (ctrl_t ctrl, const char *issuer_hash, { if (opt.verbose) { - char *serialno = hexify_data (sn, snlen); + char *serialno = hexify_data (sn, snlen, 1); log_info (_("S/N %s is valid, it is not listed in the CRL\n"), serialno ); xfree (serialno); @@ -2095,7 +2096,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader) err = gpg_error (GPG_ERR_CHECKSUM); goto leave; } - checksum = hexify_data (md5buf, 16); + checksum = hexify_data (md5buf, 16, 0); } diff --git a/dirmngr/misc.c b/dirmngr/misc.c index c2c5af1..ac3856e 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -59,17 +59,23 @@ hashify_data( const char* data, size_t len ) { unsigned char buf[20]; gcry_md_hash_buffer (GCRY_MD_SHA1, buf, data, len); - return hexify_data( buf, 20 ); + return hexify_data (buf, 20, 0); } char* -hexify_data( const unsigned char* data, size_t len ) +hexify_data (const unsigned char* data, size_t len, int with_prefix) { int i; - char* result = xmalloc( sizeof( char ) * (2*len+1)); + char *result = xmalloc (2*len + (with_prefix?2:0) + 1); + char *p; + + if (with_prefix) + p = stpcpy (result, "0x"); + else + p = result; - for( i = 0; i < 2*len; i+=2 ) - sprintf( result+i, "%02X", *data++); + for (i = 0; i < 2*len; i+=2 ) + snprintf (p+i, 3, "%02X", *data++); return result; } diff --git a/dirmngr/misc.h b/dirmngr/misc.h index d8c53d3..be4049e 100644 --- a/dirmngr/misc.h +++ b/dirmngr/misc.h @@ -28,7 +28,7 @@ size_t unhexify (unsigned char *result, const char *string); char* hashify_data( const char* data, size_t len ); /* Returns data as a hex string. */ -char* hexify_data( const unsigned char* data, size_t len ); +char* hexify_data (const unsigned char* data, size_t len, int with_prefix); /* Returns the serial number as a hex string. */ char* serial_hex ( ksba_sexp_t serial ); ----------------------------------------------------------------------- Summary of changes: dirmngr/crlcache.c | 7 ++++--- dirmngr/misc.c | 16 +++++++++++----- dirmngr/misc.h | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 22 14:29:15 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 22 Jan 2016 14:29:15 +0100 Subject: [git] gnupg-doc - branch, master, updated. 86b046ac120b5b05539dce4cfdfc3dbdfc1823f7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 86b046ac120b5b05539dce4cfdfc3dbdfc1823f7 (commit) from 0345f3a7feae4c2a4ad27ab0bd385666372e9fbd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 86b046ac120b5b05539dce4cfdfc3dbdfc1823f7 Author: Werner Koch Date: Fri Jan 22 14:24:14 2016 +0100 web: Add new Swedish mirror and removed 5 dead mirrors. diff --git a/web/download/mirrors.org b/web/download/mirrors.org index 5075dbc..b4ee159 100644 --- a/web/download/mirrors.org +++ b/web/download/mirrors.org @@ -9,38 +9,43 @@ The primary FTP site [[ftp://ftp.gnupg.org/gcrypt/][ftp.gnupg.org]] is mirrored sites. Please choose the nearest mirror to you. If you are seeking for web site mirrors, please consult the [[../mirrors.html][WWW mirror page]] . - | Country | Organisation | Links | Sync | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| - | | | | | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| - | The Americas | | | | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| - | Canada | [[http://www.gnupg.ca/][GnuPG.ca]] | [[ftp://ftp.gnupg.ca/][ftp]] | 2/day | - | | | | | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| - | Asia | | | | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| - | Japan | [[http://www.ring.gr.jp/][Ring]] | [[ftp://ftp.ring.gr.jp/pub/net/gnupg/][ftp]] [[http://www.ring.gr.jp/pub/net/gnupg/][http]] | | - | | | | | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| - | Europe | | | | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| - | Austria | [[http://gd.tuwien.ac.at/][TU Wien]] | [[ftp://gd.tuwien.ac.at/privacy/gnupg/][ftp]] [[http://gd.tuwien.ac.at/privacy/gnupg/][http]] | | - | Denmark | [[http://dotsrc.org/][dotsrc.org]] | [[ftp://mirrors.dotsrc.org/gcrypt/][ftp]] [[http://mirrors.dotsrc.org/gcrypt/][http]] | daily | - | Finland | [[http://www.jyu.fi/][JYU]] | [[ftp://ftp.jyu.fi/pub/crypt/gcrypt/][ftp]] | | - | France | [[http://mirror.cict.fr/][CICT Mirror, Toulouse]] | [[ftp://mirror.cict.fr/gnupg/][ftp]] | daily | - | Germany | [[http://www.artfiles.de][Artfiles New Media GmbH]] | [[http://artfiles.org/gnupg.org][http]] | daily | - | | [[http://www.franken.de/][Franken]] | [[ftp://ftp.franken.de/pub/crypt/mirror/ftp.gnupg.org/gcrypt/][ftp]] | daily | - | | [[http://www.freenet.de/][Freenet.de]] | [[ftp://ftp.freenet.de/pub/ftp.gnupg.org/gcrypt/][ftp]] | | - | Hungary | [[http://www.crysys.hu/][CrySyS Lab., Bute]] | [[ftp://ftp.crysys.hu/pub/gnupg/][ftp]] | daily | - | Iceland | [[http://www.hi.is/][HI]] | [[ftp://ftp.hi.is/pub/mirrors/gnupg/][ftp]] | | - | Ireland | [[http://ftp.heanet.ie/about/][HEAnet]] | [[ftp://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/][ftp]] [[http://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/][http]] {{{rsync(rsync://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/)}}} | 4/day | - | Netherlands | [[http://www.bit.nl/][BIT]] | [[ftp://ftp.bit.nl/mirror/gnupg/][ftp]] | | - | | [[http://www.surfnet.nl/][SurfNet]] | [[ftp://ftp.surfnet.nl/pub/security/gnupg/][ftp]] | | - | Portugal | [[http://5coluna.com][5? Coluna]] | [[http://dist.gnupg.pt/][http]] | 2/day | - | Romania | [[http://www.iasi.roedu.net/][Romanian Edu., Iasi Branch]] | [[ftp://ftp.iasi.roedu.net/pub/mirrors/ftp.gnupg.org/][ftp]] | | - | Switzerland | [[http://mirror.switch.ch/][SWITCHmirror]] | [[ftp://mirror.switch.ch/mirror/gnupg/][ftp]] | | - | United Kingdom | [[http://gnupg.org.favoritelinks.net/][favoritelinks]] | [[http://gnupg.org.favoritelinks.net/][http]] | daily | - | | [[http://mirror.tje.me.uk/][mirror.tje.me.uk]] | [[ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org][ftp]] [[http://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/][http]] | 4/day | - | | [[http://www.mirrorservice.org/][UK Mirror Service]] | [[ftp://ftp.mirrorservice.org/sites/ftp.gnupg.org/gcrypt][ftp]] [[http://www.mirrorservice.org/sites/ftp.gnupg.org/gcrypt][http]] {{{rsync(rsync://rsync.mirrorservice.org/ftp.gnupg.org/gcrypt/)}}} | | - |----------------+----------------------------+-------------------------------------------------------------------------------+-------| + | Country | Organisation | Links | Sync | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + | | | | | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + | The Americas | | | | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + | Canada | [[http://www.gnupg.ca/][GnuPG.ca]] | [[ftp://ftp.gnupg.ca/][ftp]] | 2/day | + | | | | | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + | Asia | | | | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + | Japan | [[http://www.ring.gr.jp/][Ring]] | [[ftp://ftp.ring.gr.jp/pub/net/gnupg/][ftp]] [[http://www.ring.gr.jp/pub/net/gnupg/][http]] | | + | | | | | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + | Europe | | | | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + | Austria | [[http://gd.tuwien.ac.at/][TU Wien]] | [[ftp://gd.tuwien.ac.at/privacy/gnupg/][ftp]] [[http://gd.tuwien.ac.at/privacy/gnupg/][http]] | | + | Denmark | [[http://dotsrc.org/][dotsrc.org]] | [[ftp://mirrors.dotsrc.org/gcrypt/][ftp]] [[http://mirrors.dotsrc.org/gcrypt/][http]] | daily | + | Germany | [[http://www.artfiles.de][Artfiles New Media GmbH]] | [[http://artfiles.org/gnupg.org][http]] | daily | + | | [[http://www.franken.de/][Franken]] | [[ftp://ftp.franken.de/pub/crypt/mirror/ftp.gnupg.org/gcrypt/][ftp]] | daily | + | | [[http://www.freenet.de/][Freenet.de]] | [[ftp://ftp.freenet.de/pub/ftp.gnupg.org/gcrypt/][ftp]] | | + | Hungary | [[http://www.crysys.hu/][CrySyS Lab., Bute]] | [[ftp://ftp.crysys.hu/pub/gnupg/][ftp]] | daily | + | Ireland | [[http://ftp.heanet.ie/about/][HEAnet]] | [[ftp://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/][ftp]] [[http://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/][http]] {{{rsync(rsync://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/)}}} | 4/day | + | Netherlands | [[http://www.bit.nl/][BIT]] | [[ftp://ftp.bit.nl/mirror/gnupg/][ftp]] | | + | | [[http://www.surfnet.nl/][SurfNet]] | [[ftp://ftp.surfnet.nl/pub/security/gnupg/][ftp]] | | + | Romania | [[http://www.iasi.roedu.net/][Romanian Edu., Iasi Branch]] | [[ftp://ftp.iasi.roedu.net/pub/mirrors/ftp.gnupg.org/][ftp]] | | + | Sweden | [[https://partyvan.eu][Partyvan]] | [[https://mirror.se.partyvan.eu/pub/ftp.gnupg.org/gcrypt/][https]] [[http://tpvj6abq225m5pcf.onion/pub/ftp.gnupg.org/gcrypt/][onion]] {{{rsync(rsync://mirror.se.partyvan.eu/pub/ftp.gnupg.org/gcrypt/)}}} | daily | + | Switzerland | [[http://mirror.switch.ch/][SWITCHmirror]] | [[ftp://mirror.switch.ch/mirror/gnupg/][ftp]] | | + | United Kingdom | [[http://mirror.tje.me.uk/][mirror.tje.me.uk]] | [[ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org][ftp]] [[http://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/][http]] | 4/day | + | | [[http://www.mirrorservice.org/][UK Mirror Service]] | [[ftp://ftp.mirrorservice.org/sites/ftp.gnupg.org/gcrypt][ftp]] [[http://www.mirrorservice.org/sites/ftp.gnupg.org/gcrypt][http]] {{{rsync(rsync://rsync.mirrorservice.org/ftp.gnupg.org/gcrypt/)}}} | | + |----------------+----------------------------+----------------------------------------------------------------------------------+-------| + +# dead mirrors as of 2016-01-22: +# +# | Finland | [[http://www.jyu.fi/][JYU]] | [[ftp://ftp.jyu.fi/pub/crypt/gcrypt/][ftp]] | | +# | France | [[http://mirror.cict.fr/][CICT Mirror, Toulouse]] | [[ftp://mirror.cict.fr/gnupg/][ftp]] | daily | +# | Iceland | [[http://www.hi.is/][HI]] | [[ftp://ftp.hi.is/pub/mirrors/gnupg/][ftp]] | | +# | Portugal | [[http://5coluna.com][5? Coluna]] | [[http://dist.gnupg.pt/][http]] | 2/day | +# | United Kingdom | [[http://gnupg.org.favoritelinks.net/][favoritelinks]] | [[http://gnupg.org.favoritelinks.net/][http]] | daily | +# ----------------------------------------------------------------------- Summary of changes: web/download/mirrors.org | 75 ++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 35 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 25 10:15:24 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 25 Jan 2016 10:15:24 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-142-g039a557 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 039a55716b8abd22ce23a96dce34cf2dc4be1862 (commit) from 12c665b36cdc4b7189549698fc4cc1b3523b18f5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 039a55716b8abd22ce23a96dce34cf2dc4be1862 Author: Werner Koch Date: Mon Jan 25 09:03:50 2016 +0100 speedo: Allow use of SHA-256 checksums * build-aux/getswdb.sh: Add option --find-sha256sum. * build-aux/speedo.mk (libgpg_error_sha2): New var. Also for all other packages. (SHA2SUM): New. (SETVARS, SETVARS_W64): Prefer sha256sum over sha1sum. (installer-from-source): Create swdb fragment. Signed-off-by: Werner Koch diff --git a/Makefile.am b/Makefile.am index 8bff2ef..19f13fe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -103,6 +103,21 @@ dist_doc_DATA = README dist-hook: gen-ChangeLog +distcheck-hook: + set -e; ( \ + pref="#+macro: gnupg21_" ;\ + reldate="$$(date -u +%Y-%m-%d)" ;\ + echo "$${pref}ver $(PACKAGE_VERSION)" ;\ + echo "$${pref}date $${reldate}" ;\ + list='$(DIST_ARCHIVES)'; for i in $$list; do \ + case "$$i" in *.tar.bz2) \ + echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\ + echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\ + echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\ + esac;\ + done ) | tee $(distdir).swdb + + if HAVE_W32_SYSTEM install-data-hook: set -e; \ diff --git a/build-aux/getswdb.sh b/build-aux/getswdb.sh index e7f6fca..4a1730b 100755 --- a/build-aux/getswdb.sh +++ b/build-aux/getswdb.sh @@ -37,6 +37,7 @@ Options: --skip-verify Do not check signatures --skip-selfcheck Do not check GnuPG version --find-sha1sum Print the name of the sha1sum utility + --find-sha256sum Print the name of the sha256sum utility --help Print this help. EOF exit $1 @@ -49,6 +50,7 @@ skip_download=no skip_verify=no skip_selfcheck=no find_sha1sum=no +find_sha256sum=no while test $# -gt 0; do case "$1" in # Set up `optarg'. @@ -76,6 +78,9 @@ while test $# -gt 0; do --find-sha1sum) find_sha1sum=yes ;; + --find-sha256sum) + find_sha256sum=yes + ;; *) usage 1 1>&2 ;; @@ -96,6 +101,21 @@ if [ ${find_sha1sum} = yes ]; then exit 1 fi +# Mac OSX has only a shasum and not sha256sum +if [ ${find_sha256sum} = yes ]; then + for i in 'shasum -a 256' sha256sum ; do + tmp=$($i /dev/null | cut -d ' ' -f1) + tmp2="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + if [ x"$tmp" = x"$tmp2" ]; then + echo "$i" + exit 0 + fi + done + echo "false" + exit 1 +fi + + # Get GnuPG version from VERSION file. For a GIT checkout this means # that ./autogen.sh must have been run first. For a regular tarball # VERSION is always available. diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index cd3a66d..5dde0fe 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -260,39 +260,51 @@ gnupg_ver := $(shell awk '$$1=="gnupg21_ver" {print $$2}' swdb.lst) libgpg_error_ver := $(shell awk '$$1=="libgpg_error_ver" {print $$2}' swdb.lst) libgpg_error_sha1:= $(shell awk '$$1=="libgpg_error_sha1" {print $$2}' swdb.lst) +libgpg_error_sha2:= $(shell awk '$$1=="libgpg_error_sha2" {print $$2}' swdb.lst) npth_ver := $(shell awk '$$1=="npth_ver" {print $$2}' swdb.lst) npth_sha1 := $(shell awk '$$1=="npth_sha1" {print $$2}' swdb.lst) +npth_sha2 := $(shell awk '$$1=="npth_sha2" {print $$2}' swdb.lst) libgcrypt_ver := $(shell awk '$$1=="libgcrypt_ver" {print $$2}' swdb.lst) libgcrypt_sha1 := $(shell awk '$$1=="libgcrypt_sha1" {print $$2}' swdb.lst) +libgcrypt_sha2 := $(shell awk '$$1=="libgcrypt_sha2" {print $$2}' swdb.lst) libassuan_ver := $(shell awk '$$1=="libassuan_ver" {print $$2}' swdb.lst) libassuan_sha1 := $(shell awk '$$1=="libassuan_sha1" {print $$2}' swdb.lst) +libassuan_sha2 := $(shell awk '$$1=="libassuan_sha2" {print $$2}' swdb.lst) libksba_ver := $(shell awk '$$1=="libksba_ver" {print $$2}' swdb.lst) libksba_sha1 := $(shell awk '$$1=="libksba_sha1" {print $$2}' swdb.lst) +libksba_sha2 := $(shell awk '$$1=="libksba_sha2" {print $$2}' swdb.lst) gpgme_ver := $(shell awk '$$1=="gpgme_ver" {print $$2}' swdb.lst) gpgme_sha1 := $(shell awk '$$1=="gpgme_sha1" {print $$2}' swdb.lst) +gpgme_sha2 := $(shell awk '$$1=="gpgme_sha2" {print $$2}' swdb.lst) pinentry_ver := $(shell awk '$$1=="pinentry_ver" {print $$2}' swdb.lst) pinentry_sha1 := $(shell awk '$$1=="pinentry_sha1" {print $$2}' swdb.lst) +pinentry_sha2 := $(shell awk '$$1=="pinentry_sha2" {print $$2}' swdb.lst) gpa_ver := $(shell awk '$$1=="gpa_ver" {print $$2}' swdb.lst) gpa_sha1 := $(shell awk '$$1=="gpa_sha1" {print $$2}' swdb.lst) +gpa_sha2 := $(shell awk '$$1=="gpa_sha2" {print $$2}' swdb.lst) gpgex_ver := $(shell awk '$$1=="gpgex_ver" {print $$2}' swdb.lst) gpgex_sha1 := $(shell awk '$$1=="gpgex_sha1" {print $$2}' swdb.lst) +gpgex_sha2 := $(shell awk '$$1=="gpgex_sha2" {print $$2}' swdb.lst) zlib_ver := $(shell awk '$$1=="zlib_ver" {print $$2}' swdb.lst) zlib_sha1 := $(shell awk '$$1=="zlib_sha1_gz" {print $$2}' swdb.lst) +zlib_sha2 := $(shell awk '$$1=="zlib_sha2_gz" {print $$2}' swdb.lst) bzip2_ver := $(shell awk '$$1=="bzip2_ver" {print $$2}' swdb.lst) bzip2_sha1 := $(shell awk '$$1=="bzip2_sha1_gz" {print $$2}' swdb.lst) +bzip2_sha2 := $(shell awk '$$1=="bzip2_sha2_gz" {print $$2}' swdb.lst) adns_ver := $(shell awk '$$1=="adns_ver" {print $$2}' swdb.lst) adns_sha1 := $(shell awk '$$1=="adns_sha1" {print $$2}' swdb.lst) +adns_sha2 := $(shell awk '$$1=="adns_sha2" {print $$2}' swdb.lst) $(info Information from the version database) $(info GnuPG ..........: $(gnupg_ver) (building $(gnupg_ver_this))) @@ -628,6 +640,10 @@ SHA1SUM := $(shell $(topsrc)/build-aux/getswdb.sh --find-sha1sum) ifeq ($(SHA1SUM),false) $(error The sha1sum tool is missing) endif +SHA2SUM := $(shell $(topsrc)/build-aux/getswdb.sh --find-sha256sum) +ifeq ($(SHA2SUM),false) +$(error The sha256sum tool is missing) +endif BUILD_ISODATE=$(shell date -u +%Y-%m-%d) @@ -705,6 +721,7 @@ define SETVARS git="$(call GETVAR,speedo_pkg_$(1)_git)"; \ gitref="$(call GETVAR,speedo_pkg_$(1)_gitref)"; \ tar="$(call GETVAR,speedo_pkg_$(1)_tar)"; \ + sha2="$(call GETVAR,$(1)_sha2)"; \ sha1="$(call GETVAR,$(1)_sha1)"; \ pkgsdir="$(sdir)/$(1)"; \ if [ "$(1)" = "gnupg" ]; then \ @@ -739,6 +756,7 @@ define SETVARS_W64 git="$(call GETVAR,speedo_pkg_$(1)_git)"; \ gitref="$(call GETVAR,speedo_pkg_$(1)_gitref)"; \ tar="$(call GETVAR,speedo_pkg_$(1)_tar)"; \ + sha2="$(call GETVAR,$(1)_sha2)"; \ sha1="$(call GETVAR,$(1)_sha1)"; \ pkgsdir="$(sdir)/$(1)"; \ if [ "$(1)" = "gnupg" ]; then \ @@ -814,11 +832,19 @@ $(stampdir)/stamp-$(1)-00-unpack: $(stampdir)/stamp-directories | $$$${pretar} | tar x$$$${opt}f - ;; \ esac; \ if [ -f tmp.tgz ]; then \ - if [ -n "$$$${sha1}" ]; then \ + if [ -n "$$$${sha2}" ]; then \ + tmp=$$$$($(SHA2SUM) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via fbe1cf67aadc5a33cf815ddbcfc9669e43caa123 (commit) via ee87c653bf4b495714e8e6b024d0a8ace3a33452 (commit) from 039a55716b8abd22ce23a96dce34cf2dc4be1862 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fbe1cf67aadc5a33cf815ddbcfc9669e43caa123 Author: Werner Koch Date: Mon Jan 25 11:34:49 2016 +0100 gpg: Print PROGRESS status lines during key generation. * g10/call-agent.c (cache_nonce_status_cb): Rewrite by using has_leading_keyword. Handle PROGRESS lines. -- GnuPG-bug-id: 1415 Co-authored-by: Daiki Ueno Signed-off-by: Werner Koch diff --git a/g10/call-agent.c b/g10/call-agent.c index 83fabcc..1d7ff57 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1749,30 +1749,29 @@ static gpg_error_t cache_nonce_status_cb (void *opaque, const char *line) { struct cache_nonce_parm_s *parm = opaque; - const char *keyword = line; - int keywordlen; - - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - while (spacep (line)) - line++; + const char *s; - if (keywordlen == 11 && !memcmp (keyword, "CACHE_NONCE", keywordlen)) + if ((s = has_leading_keyword (line, "CACHE_NONCE"))) { if (parm->cache_nonce_addr) { xfree (*parm->cache_nonce_addr); - *parm->cache_nonce_addr = xtrystrdup (line); + *parm->cache_nonce_addr = xtrystrdup (s); } } - else if (keywordlen == 12 && !memcmp (keyword, "PASSWD_NONCE", keywordlen)) + else if ((s = has_leading_keyword (line, "PASSWD_NONCE"))) { if (parm->passwd_nonce_addr) { xfree (*parm->passwd_nonce_addr); - *parm->passwd_nonce_addr = xtrystrdup (line); + *parm->passwd_nonce_addr = xtrystrdup (s); } } + else if ((s = has_leading_keyword (line, "PROGRESS"))) + { + if (opt.enable_progress_filter) + write_status_text (STATUS_PROGRESS, s); + } return 0; } commit ee87c653bf4b495714e8e6b024d0a8ace3a33452 Author: Werner Koch Date: Mon Jan 25 11:20:23 2016 +0100 agent: Send PROGRESS status lines to the client. * agent/gpg-agent.c (struct progress_dispatch_s): New. (progress_dispatch_list): New. (main): Register libgcrypt pogress handler. (agent_libgcrypt_progress_cb): New. (agent_set_progress_cb): New. (unregister_progress_cb): New. (agent_deinit_default_ctrl): Call unregister. * agent/command.c (progress_cb): New. (start_command_handler): Register progress callback. -- Signed-off-by: Werner Koch diff --git a/agent/agent.h b/agent/agent.h index c7e1433..c2726bb 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -336,6 +336,9 @@ typedef int (*lookup_ttl_t)(const char *hexgrip); /*-- gpg-agent.c --*/ void agent_exit (int rc) GPGRT_ATTR_NORETURN; /* Also implemented in other tools */ +void agent_set_progress_cb (void (*cb)(ctrl_t ctrl, const char *what, + int printchar, int current, int total), + ctrl_t ctrl); gpg_error_t agent_copy_startup_env (ctrl_t ctrl); const char *get_agent_socket_name (void); const char *get_agent_ssh_socket_name (void); diff --git a/agent/command.c b/agent/command.c index a09da60..421df00 100644 --- a/agent/command.c +++ b/agent/command.c @@ -446,6 +446,23 @@ agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid) } +/* An agent progress callback for Libgcrypt. This has been registered + * to be called via the progress dispatcher mechanism from + * gpg-agent.c */ +static void +progress_cb (ctrl_t ctrl, const char *what, int printchar, + int current, int total) +{ + if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx) + ; + else if (printchar == '\n' && what && !strcmp (what, "primegen")) + agent_print_status (ctrl, "PROGRESS", "%.20s X 100 100", what); + else + agent_print_status (ctrl, "PROGRESS", "%.20s %c %d %d", + what, printchar=='\n'?'X':printchar, current, total); +} + + /* Helper to print a message while leaving a command. */ static gpg_error_t leave_cmd (assuan_context_t ctx, gpg_error_t err) @@ -3205,6 +3222,7 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd) ctrl->digest.raw_value = 0; assuan_set_io_monitor (ctx, io_monitor, NULL); + agent_set_progress_cb (progress_cb, ctrl); for (;;) { diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 3095531..8aab2b9 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -372,6 +372,32 @@ static pid_t parent_pid = (pid_t)(-1); /* Number of active connections. */ static int active_connections; +/* This object is used to dispatch progress messages from Libgcrypt to + * the right thread. Given that we won't have at max a few dozen + * connections at the same time using a linked list is the easiest way + * to handle this. */ +struct progress_dispatch_s +{ + struct progress_dispatch_s *next; + /* The control object of the connection. If this is NULL no + * connection is associated with this item and it is free for reuse + * by new connections. */ + ctrl_t ctrl; + + /* The thread id of (npth_self) of the connection. */ + npth_t tid; + + /* The callback set by the connection. This is similar to the + * Libgcrypt callback but with the control object passed as the + * first argument. */ + void (*cb)(ctrl_t ctrl, + const char *what, int printchar, + int current, int total); +}; +struct progress_dispatch_s *progress_dispatch_list; + + + /* Local prototypes. @@ -383,6 +409,9 @@ static gnupg_fd_t create_server_socket (char *name, int primary, int cygwin, assuan_sock_nonce_t *nonce); static void create_directories (void); +static void agent_libgcrypt_progress_cb (void *data, const char *what, + int printchar, + int current, int total); static void agent_init_default_ctrl (ctrl_t ctrl); static void agent_deinit_default_ctrl (ctrl_t ctrl); @@ -760,6 +789,7 @@ main (int argc, char **argv ) setup_libgcrypt_logging (); gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); + gcry_set_progress_handler (agent_libgcrypt_progress_cb, NULL); disable_core_dumps (); @@ -1445,6 +1475,88 @@ agent_exit (int rc) } +/* This is our callback function for gcrypt progress messages. It is + set once at startup and dispatches progress messages to the + corresponding threads of the agent. */ +static void +agent_libgcrypt_progress_cb (void *data, const char *what, int printchar, + int current, int total) +{ + struct progress_dispatch_s *dispatch; + npth_t mytid = npth_self (); + + (void)data; + + for (dispatch = progress_dispatch_list; dispatch; dispatch = dispatch->next) + if (dispatch->ctrl && dispatch->tid == mytid) + break; + if (dispatch && dispatch->cb) + dispatch->cb (dispatch->ctrl, what, printchar, current, total); +} + + +/* If a progress dispatcher callback has been associated with the + * current connection unregister it. */ +static void +unregister_progress_cb (void) +{ + struct progress_dispatch_s *dispatch; + npth_t mytid = npth_self (); + + for (dispatch = progress_dispatch_list; dispatch; dispatch = dispatch->next) + if (dispatch->ctrl && dispatch->tid == mytid) + break; + if (dispatch) + { + dispatch->ctrl = NULL; + dispatch->cb = NULL; + } +} + + +/* Setup a progress callback CB for the current connection. Using a + * CB of NULL disables the callback. */ +void +agent_set_progress_cb (void (*cb)(ctrl_t ctrl, const char *what, + int printchar, int current, int total), + ctrl_t ctrl) +{ + struct progress_dispatch_s *dispatch, *firstfree; + npth_t mytid = npth_self (); + + firstfree = NULL; + for (dispatch = progress_dispatch_list; dispatch; dispatch = dispatch->next) + { + if (dispatch->ctrl && dispatch->tid == mytid) + break; + if (!dispatch->ctrl && !firstfree) + firstfree = dispatch; + } + if (!dispatch) /* None allocated: Reuse or allocate a new one. */ + { + if (firstfree) + { + dispatch = firstfree; + } + else if ((dispatch = xtrycalloc (1, sizeof *dispatch))) + { + dispatch->next = progress_dispatch_list; + progress_dispatch_list = dispatch; + } + else + { + log_error ("error allocating new progress dispatcher slot: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + return; + } + dispatch->ctrl = ctrl; + dispatch->tid = mytid; + } + + dispatch->cb = cb; +} + + /* Each thread has its own local variables conveyed by a control structure usually identified by an argument named CTRL. This function is called immediately after allocating the control @@ -1481,6 +1593,7 @@ agent_init_default_ctrl (ctrl_t ctrl) static void agent_deinit_default_ctrl (ctrl_t ctrl) { + unregister_progress_cb (); session_env_release (ctrl->session_env); if (ctrl->lc_ctype) ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 3 ++ agent/command.c | 18 +++++++++ agent/gpg-agent.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ g10/call-agent.c | 21 +++++----- 4 files changed, 144 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 25 14:16:53 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 25 Jan 2016 14:16:53 +0100 Subject: [git] GnuPG - branch, justus/scm-3, updated. gnupg-2.1.10-138-gbfe3933 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, justus/scm-3 has been updated via bfe3933a86a282a75cbe4486e1f9210a095ea732 (commit) via 710cff84417bc76c5368085e327be33552fe779a (commit) from 1a73bcbf12464d5c8d99111c28d3e4e8ec63b328 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bfe3933a86a282a75cbe4486e1f9210a095ea732 Author: Justus Winter Date: Mon Jan 25 14:12:45 2016 +0100 Fix whitespace trimming diff --git a/tests/gpgscm/lib.scm b/tests/gpgscm/lib.scm index 2b897d1..f5119eb 100644 --- a/tests/gpgscm/lib.scm +++ b/tests/gpgscm/lib.scm @@ -65,9 +65,27 @@ (define (string-split haystack delimiter) (string-splitn haystack delimiter -1)) -;; Drop whitespace. -(define (filter-whitespace s) - (list->string (filter (lambda (c) (not (char=? #\newline c))) (string->list s)))) +;; Trim the prefix of S containing only characters that make PREDICATE +;; true. For example (string-ltrim char-whitespace? " foo") => +;; "foo". +(define (string-ltrim predicate s) + (let loop ((s' (string->list s))) + (if (predicate (car s')) + (loop (cdr s')) + (list->string s')))) + +;; Trim the suffix of S containing only characters that make PREDICATE +;; true. +(define (string-rtrim predicate s) + (let loop ((s' (reverse (string->list s)))) + (if (predicate (car s')) + (loop (cdr s')) + (list->string (reverse s'))))) + +;; Trim both the prefix and suffix of S containing only characters +;; that make PREDICATE true. +(define (string-trim predicate s) + (string-ltrim predicate (string-rtrim predicate s))) (define (echo . msg) (for-each (lambda (x) (display x) (display " ")) msg) diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index 60e4c2a..585ce76 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -76,7 +76,7 @@ (let* ((config-string (call-popen `(,GPG --with-colons --list-config ,what) "")) (config (string-splitn - (filter-whitespace config-string) #\: 2))) + (string-rtrim char-whitespace? config-string) #\: 2))) (string-split (caddr config) #\;))) (define all-pubkey-algos (get-config "pubkeyname")) commit 710cff84417bc76c5368085e327be33552fe779a Author: Justus Winter Date: Mon Jan 25 14:10:54 2016 +0100 Use gnupg_mkdtemp diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index 7048b55..f8d8b2a 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -278,9 +278,8 @@ do_close (scheme *sc, pointer args) SC_RETURN_ERR (sc, close (fd) == 0 ? 0 : gpg_error_from_syserror ()); } -/* XXX avoid mktemp. */ static pointer -do_mktemp (scheme *sc, pointer args) +do_mkdtemp (scheme *sc, pointer args) { SC_FFI_PROLOG (); char *template; @@ -292,7 +291,7 @@ do_mktemp (scheme *sc, pointer args) SC_RETURN_ERR (sc, EINVAL); strncpy (buffer, template, sizeof buffer); - SC_RETURN_STRING (sc, mktemp (buffer)); + SC_RETURN_STRING (sc, gnupg_mkdtemp (buffer)); } static pointer @@ -796,7 +795,7 @@ ffi_init (scheme *sc) define_function (sc, exit); define_function (sc, open); define_function (sc, close); - define_function (sc, mktemp); + define_function (sc, mkdtemp); define_function (sc, unlink); define_function (sc, getcwd); define_function (sc, mkdir); diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm index ac3af8b..8bf78cb 100644 --- a/tests/gpgscm/tests.scm +++ b/tests/gpgscm/tests.scm @@ -174,8 +174,13 @@ ,(if (= 1 (length (cadr form))) `(begin ,@(cddr form)) `(lettmp ,(cdadr form) ,@(cddr form))))) - (catch #t (unlink ,(caadr form))) - ,result-sym)) (mktemp "gpgscm-XXXXXX")))) + (catch #t + (let* ((filename ,(caadr form)) + (len (string-length filename)) + (dirname (substring 0 (- len 2)))) + (unlink filename) + (rmdir dirname))) + ,result-sym)) (string-append (mkdtemp "gpgscm-XXXXXX") "/a")))) (define (check-execution source transformer) (lettmp (sink) ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/ffi.c | 7 +++---- tests/gpgscm/lib.scm | 24 +++++++++++++++++++++--- tests/gpgscm/tests.scm | 9 +++++++-- tests/openpgp/defs.scm | 2 +- 4 files changed, 32 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 26 03:15:41 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 26 Jan 2016 03:15:41 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-146-gb8bb16c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via b8bb16c6c08d3c2947f1ff67419b36eb203c5c1a (commit) via d33a34004bef028068538f099c32a0e292a004c3 (commit) from fbe1cf67aadc5a33cf815ddbcfc9669e43caa123 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b8bb16c6c08d3c2947f1ff67419b36eb203c5c1a Author: NIIBE Yutaka Date: Tue Jan 26 11:12:33 2016 +0900 g10: Fix segfault on unsupported curve. * g10/call-agent.c (learn_status_cb): Don't use NULL for strcmp. -- With libgcrypt not supporting cv25519, gpg segfaults. Signed-off-by: NIIBE Yutaka diff --git a/g10/call-agent.c b/g10/call-agent.c index 1d7ff57..d9e4859 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -701,14 +701,10 @@ learn_status_cb (void *opaque, const char *line) { const char *curve; - i = 0; - do - { - curve = openpgp_enum_curves (&i); - if (!strcmp (curve, line+n)) - break; - } - while (curve != NULL); + for (i = 0; (curve = openpgp_enum_curves (&i));) + if (!strcmp (curve, line+n)) + break; + parm->key_attr[keyno].curve = curve; } } commit d33a34004bef028068538f099c32a0e292a004c3 Author: NIIBE Yutaka Date: Tue Jan 26 11:00:53 2016 +0900 sm: small fix for GCC 6. * sm/export.c (insert_duptable): Use unsigned 0. -- We can silence message with -Wshift-negative-value. Signed-off-by: NIIBE Yutaka diff --git a/sm/export.c b/sm/export.c index 1dce106..d3dc9b9 100644 --- a/sm/export.c +++ b/sm/export.c @@ -103,7 +103,7 @@ insert_duptable (duptable_t *table, unsigned char *fpr, int *exists) #error cannot handle a table larger than 16 bits or smaller than 8 bits #elif DUPTABLE_BITS > 8 idx <<= (DUPTABLE_BITS - 8); - idx |= (fpr[1] & ~(~0 << 4)); + idx |= (fpr[1] & ~(~0U << 4)); #endif for (t = table[idx]; t; t = t->next) ----------------------------------------------------------------------- Summary of changes: g10/call-agent.c | 12 ++++-------- sm/export.c | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 26 07:47:07 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 26 Jan 2016 07:47:07 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-5-gaa4a3aa Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via aa4a3aa3e7a0c7dc231b90b2958184c7138ccc93 (commit) from a38dffde7b19bd4881afcd87c23aac2daa5bd52a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aa4a3aa3e7a0c7dc231b90b2958184c7138ccc93 Author: NIIBE Yutaka Date: Tue Jan 26 15:38:27 2016 +0900 g10: Fix iobuf API of filter function for alignment. * include/iobuf.h (struct iobuf_struct): Remove DESC. * util/iobuf.c (iobuf_desc): New. (print_chain, iobuf_close, iobuf_open, iobuf_fdopen, iobuf_sockopen) (iobuf_create, iobuf_append, iobuf_openrw, iobuf_ioctl) (iobuf_push_filter2, pop_filter, underflow): Use iobuf_desc. (file_filter, sock_filter, block_filter): Fill the description. * g10/armor.c, g10/cipher.c, g10/compress-bz2.c, g10/compress.c, g10/encode.c, g10/encr-data.c, g10/mdfilter.c, g10/pipemode.c, g10/progress.c, g10/textfilter.c: Likewise. -- Newer GCC warns against possible alignment difference of pointers. This change can silence those warnings. Signed-off-by: NIIBE Yutaka (backported from 2.1 commit 3f52c7da3940ec06572270d511000dc7fe9c27d2) diff --git a/g10/armor.c b/g10/armor.c index be03692..1ae3c60 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1300,7 +1300,7 @@ armor_filter( void *opaque, int control, release_armor_context (afx); } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "armor_filter"; + mem2str (buf, "armor_filter", *ret_len); return rc; } diff --git a/g10/cipher.c b/g10/cipher.c index 0c51100..45e1963 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -145,7 +145,7 @@ cipher_filter( void *opaque, int control, cipher_close(cfx->cipher_hd); } else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "cipher_filter"; + mem2str (buf, "cipher_filter", *ret_len); } return rc; } diff --git a/g10/compress-bz2.c b/g10/compress-bz2.c index baef92f..6c5bd66 100644 --- a/g10/compress-bz2.c +++ b/g10/compress-bz2.c @@ -247,6 +247,6 @@ compress_filter_bz2( void *opaque, int control, zfx->release (zfx); } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "compress_filter"; + mem2str (buf, "compress_filter", *ret_len); return rc; } diff --git a/g10/compress.c b/g10/compress.c index 07c9e5e..4598aff 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -295,7 +295,7 @@ compress_filter( void *opaque, int control, zfx->release (zfx); } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "compress_filter"; + mem2str (buf, "compress_filter", *ret_len); return rc; } diff --git a/g10/encode.c b/g10/encode.c index a579c42..93c70a7 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -736,7 +736,7 @@ encrypt_filter( void *opaque, int control, xfree(efx->symkey_s2k); } else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "encrypt_filter"; + mem2str (buf, "encrypt_filter", *ret_len); } return rc; } diff --git a/g10/encr-data.c b/g10/encr-data.c index c65aa11..baa0606 100644 --- a/g10/encr-data.c +++ b/g10/encr-data.c @@ -300,7 +300,7 @@ mdc_decode_filter( void *opaque, int control, IOBUF a, release_dfx_context (dfx); } else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "mdc_decode_filter"; + mem2str (buf, "mdc_decode_filter", *ret_len); } return rc; } @@ -329,7 +329,7 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) release_dfx_context (fc); } else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "decode_filter"; + mem2str (buf, "decode_filter", *ret_len); } return rc; } diff --git a/g10/mdfilter.c b/g10/mdfilter.c index 9c0059e..bb47f98 100644 --- a/g10/mdfilter.c +++ b/g10/mdfilter.c @@ -58,7 +58,7 @@ md_filter( void *opaque, int control, *ret_len = i; } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "md_filter"; + mem2str (buf, "md_filter", *ret_len); return rc; } diff --git a/g10/pipemode.c b/g10/pipemode.c index 077f967..60c8020 100644 --- a/g10/pipemode.c +++ b/g10/pipemode.c @@ -281,7 +281,7 @@ pipemode_filter( void *opaque, int control, *ret_len = n; } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "pipemode_filter"; + mem2str (buf, "pipemode_filter", *ret_len); return rc; } diff --git a/g10/progress.c b/g10/progress.c index 8c8265f..cea080c 100644 --- a/g10/progress.c +++ b/g10/progress.c @@ -91,7 +91,7 @@ progress_filter (void *opaque, int control, pfx->what = NULL; } else if (control == IOBUFCTRL_DESC) - *(char**)buf = "progress_filter"; + mem2str (buf, "progress_filter", *ret_len); return rc; } diff --git a/g10/textfilter.c b/g10/textfilter.c index dc72a56..79f2f67 100644 --- a/g10/textfilter.c +++ b/g10/textfilter.c @@ -150,7 +150,7 @@ text_filter( void *opaque, int control, tfx->buffer = NULL; } else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "text_filter"; + mem2str (buf, "text_filter", *ret_len); return rc; } diff --git a/include/iobuf.h b/include/iobuf.h index 9515a0e..030f8c8 100644 --- a/include/iobuf.h +++ b/include/iobuf.h @@ -59,7 +59,6 @@ struct iobuf_struct { char *real_fname; IOBUF chain; /* next iobuf used for i/o if any (passed to filter) */ int no, subno; - const char *desc; void *opaque; /* can be used to hold any information */ /* this value is copied to all instances */ struct { diff --git a/util/iobuf.c b/util/iobuf.c index a330460..539356e 100644 --- a/util/iobuf.c +++ b/util/iobuf.c @@ -459,7 +459,7 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len) a->keep_open = a->no_cache = 0; } else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "file_filter"; + mem2str (buf, "file_filter", *ret_len); } else if( control == IOBUFCTRL_FREE ) { if( f != stdin && f != stdout ) { @@ -572,7 +572,7 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len) a->no_cache = 0; } else if ( control == IOBUFCTRL_DESC ) { - *(char**)buf = "file_filter(fd)"; + mem2str (buf, "file_filter(fd)", *ret_len); } else if ( control == IOBUFCTRL_FREE ) { #ifdef HAVE_DOSISH_SYSTEM @@ -660,7 +660,7 @@ sock_filter (void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len) a->no_cache = 0; } else if ( control == IOBUFCTRL_DESC ) { - *(char**)buf = "sock_filter"; + mem2str (buf, "sock_filter", *ret_len); } else if ( control == IOBUFCTRL_FREE ) { if (!a->keep_open) @@ -852,7 +852,7 @@ block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len) a->buflen = 0; } else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "block_filter"; + mem2str (buf, "block_filter", *ret_len); } else if( control == IOBUFCTRL_FREE ) { if( a->use == 2 ) { /* write the end markers */ @@ -906,6 +906,24 @@ block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len) return rc; } +#define MAX_IOBUF_DESC 32 +/* + * Fill the buffer by the description of iobuf A. + * The buffer size should be MAX_IOBUF_DESC (or larger). + * Returns BUF as (const char *). + */ +static const char * +iobuf_desc (iobuf_t a, byte *buf) +{ + size_t len = MAX_IOBUF_DESC; + + if (! a || ! a->filter) + memcpy (buf, "?", 2); + else + a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL, buf, &len); + + return buf; +} static void print_chain( IOBUF a ) @@ -913,16 +931,11 @@ print_chain( IOBUF a ) if( !DBG_IOBUF ) return; for(; a; a = a->chain ) { - size_t dummy_len = 0; - const char *desc = "[none]"; - - if( a->filter ) - a->filter( a->filter_ov, IOBUFCTRL_DESC, NULL, - (byte*)&desc, &dummy_len ); + byte desc[MAX_IOBUF_DESC]; log_debug("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n", - a->no, a->subno, desc?desc:"?", a->filter_eof, - (int)a->d.start, (int)a->d.len ); + a->no, a->subno, iobuf_desc (a, desc), a->filter_eof, + (int)a->d.start, (int)a->d.len ); } } @@ -971,13 +984,14 @@ iobuf_close ( IOBUF a ) } for( ; a && !rc ; a = a2 ) { + byte desc[MAX_IOBUF_DESC]; a2 = a->chain; if( a->use == 2 && (rc=iobuf_flush(a)) ) log_error("iobuf_flush failed on close: %s\n", g10_errstr(rc)); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: close `%s'\n", a->no, a->subno, - a->desc?a->desc:"?"); + iobuf_desc (a, desc)); if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE, a->chain, NULL, &dummy_len)) ) log_error("IOBUFCTRL_FREE failed on close: %s\n", g10_errstr(rc) ); @@ -1132,7 +1146,6 @@ iobuf_open( const char *fname ) a->real_fname = xstrdup( fname ); a->filter = file_filter; a->filter_ov = fcx; - file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len ); file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len ); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: open `%s' fd=%d\n", @@ -1166,7 +1179,6 @@ iobuf_fdopen( int fd, const char *mode ) sprintf(fcx->fname, "[fd %d]", fd ); a->filter = file_filter; a->filter_ov = fcx; - file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len ); file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len ); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname ); @@ -1190,7 +1202,6 @@ iobuf_sockopen ( int fd, const char *mode ) sprintf(scx->fname, "[sock %d]", fd ); a->filter = sock_filter; a->filter_ov = scx; - sock_filter( scx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len ); sock_filter( scx, IOBUFCTRL_INIT, NULL, NULL, &len ); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname); @@ -1213,6 +1224,7 @@ iobuf_create( const char *fname ) size_t len; int print_only = 0; int fd; + byte desc[MAX_IOBUF_DESC]; if( !fname || (*fname=='-' && !fname[1]) ) { fp = FILEP_OR_FD_FOR_STDOUT; @@ -1235,11 +1247,10 @@ iobuf_create( const char *fname ) a->real_fname = xstrdup( fname ); a->filter = file_filter; a->filter_ov = fcx; - file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len ); file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len ); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: create `%s'\n", a->no, a->subno, - a->desc?a->desc:"?" ); + iobuf_desc (a, desc)); return a; } @@ -1257,6 +1268,7 @@ iobuf_append( const char *fname ) FILE *fp; file_filter_ctx_t *fcx; size_t len; + byte desc[MAX_IOBUF_DESC]; if( !fname ) return NULL; @@ -1269,11 +1281,10 @@ iobuf_append( const char *fname ) a->real_fname = xstrdup( fname ); a->filter = file_filter; a->filter_ov = fcx; - file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len ); file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len ); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: append `%s'\n", a->no, a->subno, - a->desc?a->desc:"?" ); + iobuf_desc (a, desc)); return a; } @@ -1286,6 +1297,7 @@ iobuf_openrw( const char *fname ) FILEP_OR_FD fp; file_filter_ctx_t *fcx; size_t len; + byte desc[MAX_IOBUF_DESC]; if( !fname ) return NULL; @@ -1298,11 +1310,10 @@ iobuf_openrw( const char *fname ) a->real_fname = xstrdup( fname ); a->filter = file_filter; a->filter_ov = fcx; - file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len ); file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len ); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno, - a->desc?a->desc:"?"); + iobuf_desc (a, desc)); return a; } @@ -1311,11 +1322,13 @@ iobuf_openrw( const char *fname ) int iobuf_ioctl ( IOBUF a, int cmd, int intval, void *ptrval ) { + byte desc[MAX_IOBUF_DESC]; + if ( cmd == 1 ) { /* keep system filepointer/descriptor open */ if( DBG_IOBUF ) log_debug("iobuf-%d.%d: ioctl `%s' keep=%d\n", a? a->no:-1, a?a->subno:-1, - a&&a->desc?a->desc:"?", intval ); + iobuf_desc (a, desc), intval ); for( ; a; a = a->chain ) if( !a->chain && a->filter == file_filter ) { file_filter_ctx_t *b = a->filter_ov; @@ -1345,7 +1358,7 @@ iobuf_ioctl ( IOBUF a, int cmd, int intval, void *ptrval ) if( DBG_IOBUF ) log_debug("iobuf-%d.%d: ioctl `%s' no_cache=%d\n", a? a->no:-1, a?a->subno:-1, - a&&a->desc?a->desc:"?", intval ); + iobuf_desc (a, desc), intval ); for( ; a; a = a->chain ) if( !a->chain && a->filter == file_filter ) { file_filter_ctx_t *b = a->filter_ov; @@ -1457,11 +1470,12 @@ iobuf_push_filter2( IOBUF a, a->filter_ov_owner = rel_ov; a->subno = b->subno + 1; - f( ov, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &dummy_len ); if( DBG_IOBUF ) { + byte desc[MAX_IOBUF_DESC]; + log_debug("iobuf-%d.%d: push `%s'\n", a->no, a->subno, - a->desc?a->desc:"?" ); + iobuf_desc (a, desc)); print_chain( a ); } @@ -1482,13 +1496,14 @@ pop_filter( IOBUF a, int (*f)(void *opaque, int control, IOBUF b; size_t dummy_len=0; int rc=0; + byte desc[MAX_IOBUF_DESC]; if( a->directfp ) BUG(); if( DBG_IOBUF ) log_debug("iobuf-%d.%d: pop `%s'\n", a->no, a->subno, - a->desc?a->desc:"?" ); + iobuf_desc (a, desc)); if( !a->filter ) { /* this is simple */ b = a->chain; assert(b); @@ -1563,10 +1578,12 @@ underflow(IOBUF a) if( a->filter_eof ) { if( a->chain ) { + byte desc[MAX_IOBUF_DESC]; + IOBUF b = a->chain; if( DBG_IOBUF ) log_debug("iobuf-%d.%d: pop `%s' in underflow\n", - a->no, a->subno, a->desc?a->desc:"?" ); + a->no, a->subno, iobuf_desc (a, desc) ); xfree(a->d.buf); xfree(a->real_fname); memcpy(a, b, sizeof *a); @@ -1625,7 +1642,6 @@ underflow(IOBUF a) a->filter_ov = NULL; } a->filter = NULL; - a->desc = NULL; a->filter_ov = NULL; a->filter_eof = 1; if( !len && a->chain ) { ----------------------------------------------------------------------- Summary of changes: g10/armor.c | 2 +- g10/cipher.c | 2 +- g10/compress-bz2.c | 2 +- g10/compress.c | 2 +- g10/encode.c | 2 +- g10/encr-data.c | 4 +-- g10/mdfilter.c | 2 +- g10/pipemode.c | 2 +- g10/progress.c | 2 +- g10/textfilter.c | 2 +- include/iobuf.h | 1 - util/iobuf.c | 74 +++++++++++++++++++++++++++++++++--------------------- 12 files changed, 56 insertions(+), 41 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 26 10:00:57 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 26 Jan 2016 10:00:57 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-147-g3e50236 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3e50236d4ecc3601b2641bf4273a0ff64bb5fdc4 (commit) from b8bb16c6c08d3c2947f1ff67419b36eb203c5c1a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3e50236d4ecc3601b2641bf4273a0ff64bb5fdc4 Author: Andre Heinecke Date: Tue Jan 26 09:53:42 2016 +0100 gpgtar,w32: Fix gpgtar 8 bit encoding handling on W32 * common/utf8conv.c (wchar_to_utf8): Factor code out to ... (wchar_to_cp): new. (utf8_to_wchar): Factor code out to ... (cp_to_wchar): new. (wchar_to_native): New. (native_to_wchar): New. * tools/gpgtar-create.c (fillup_entry_w32): Use native_to_wchar. (scan_directory): Use wchar_to_native. -- Gpgtar needs to handle filenames in the local 8 bit encoding on Windows as it uses the 8 bit file io functions. GnuPG-bug-id: 1624, 1746 Patch from bug 1624 modified to fit into GnuPG 2.1 by wk. Signed-off-by: Werner Koch diff --git a/common/utf8conv.c b/common/utf8conv.c index a912b82..8a2cf8a 100644 --- a/common/utf8conv.c +++ b/common/utf8conv.c @@ -713,17 +713,17 @@ jnlib_iconv_close (jnlib_iconv_t cd) #ifdef HAVE_W32_SYSTEM -/* Return a malloced string encoded in UTF-8 from the wide char input +/* Return a malloced string encoded for CODEPAGE from the wide char input string STRING. Caller must free this value. Returns NULL and sets ERRNO on failure. Calling this function with STRING set to NULL is not defined. */ -char * -wchar_to_utf8 (const wchar_t *string) +static char * +wchar_to_cp (const wchar_t *string, unsigned int codepage) { int n; char *result; - n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL); + n = WideCharToMultiByte (codepage, 0, string, -1, NULL, 0, NULL, NULL); if (n < 0) { gpg_err_set_errno (EINVAL); @@ -734,7 +734,7 @@ wchar_to_utf8 (const wchar_t *string) if (!result) return NULL; - n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL); + n = WideCharToMultiByte (codepage, 0, string, -1, result, n, NULL, NULL); if (n < 0) { xfree (result); @@ -745,18 +745,18 @@ wchar_to_utf8 (const wchar_t *string) } -/* Return a malloced wide char string from an UTF-8 encoded input +/* Return a malloced wide char string from a CODEPAGE encoded input string STRING. Caller must free this value. Returns NULL and sets ERRNO on failure. Calling this function with STRING set to NULL is not defined. */ -wchar_t * -utf8_to_wchar (const char *string) +static wchar_t * +cp_to_wchar (const char *string, unsigned int codepage) { int n; size_t nbytes; wchar_t *result; - n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0); + n = MultiByteToWideChar (codepage, 0, string, -1, NULL, 0); if (n < 0) { gpg_err_set_errno (EINVAL); @@ -773,7 +773,7 @@ utf8_to_wchar (const char *string) if (!result) return NULL; - n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n); + n = MultiByteToWideChar (codepage, 0, string, -1, result, n); if (n < 0) { xfree (result); @@ -782,4 +782,49 @@ utf8_to_wchar (const char *string) } return result; } + + +/* Return a malloced string encoded in the active code page from the + * wide char input string STRING. Caller must free this value. + * Returns NULL and sets ERRNO on failure. Calling this function with + * STRING set to NULL is not defined. */ +char * +wchar_to_native (const wchar_t *string) +{ + return wchar_to_cp (string, CP_ACP); +} + + +/* Return a malloced wide char string from an UTF-8 encoded input + * string STRING. Caller must free this value. Returns NULL and sets + * ERRNO on failure. Calling this function with STRING set to NULL is + * not defined. */ +wchar_t * +native_to_wchar (const char *string) +{ + return cp_to_wchar (string, CP_ACP); +} + + +/* Return a malloced string encoded in UTF-8 from the wide char input + * string STRING. Caller must free this value. Returns NULL and sets + * ERRNO on failure. Calling this function with STRING set to NULL is + * not defined. */ +char * +wchar_to_utf8 (const wchar_t *string) +{ + return wchar_to_cp (string, CP_UTF8); +} + + +/* Return a malloced wide char string from an UTF-8 encoded input + * string STRING. Caller must free this value. Returns NULL and sets + * ERRNO on failure. Calling this function with STRING set to NULL is + * not defined. */ +wchar_t * +utf8_to_wchar (const char *string) +{ + return cp_to_wchar (string, CP_UTF8); +} + #endif /*HAVE_W32_SYSTEM*/ diff --git a/common/utf8conv.h b/common/utf8conv.h index ad7dbe9..def35de 100644 --- a/common/utf8conv.h +++ b/common/utf8conv.h @@ -48,6 +48,8 @@ size_t jnlib_iconv (jnlib_iconv_t cd, const char **inbuf, size_t *inbytesleft, int jnlib_iconv_close (jnlib_iconv_t cd); #ifdef HAVE_W32_SYSTEM +char *wchar_to_native (const wchar_t *string); +wchar_t *native_to_wchar (const char *string); char *wchar_to_utf8 (const wchar_t *string); wchar_t *utf8_to_wchar (const char *string); #endif /*HAVE_W32_SYSTEM*/ diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index 2fd7019..968dca6 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -72,13 +72,13 @@ fillup_entry_w32 (tar_header_t hdr) for (p=hdr->name; *p; p++) if (*p == '/') *p = '\\'; - wfname = utf8_to_wchar (hdr->name); + wfname = native_to_wchar (hdr->name); for (p=hdr->name; *p; p++) if (*p == '\\') *p = '/'; if (!wfname) { - log_error ("error utf8-ing '%s': %s\n", hdr->name, w32_strerror (-1)); + log_error ("error converting '%s': %s\n", hdr->name, w32_strerror (-1)); return gpg_error_from_syserror (); } if (!GetFileAttributesExW (wfname, GetFileExInfoStandard, &fad)) @@ -299,7 +299,7 @@ scan_directory (const char *dname, scanctrl_t scanctrl) for (p=fname; *p; p++) if (*p == '/') *p = '\\'; - wfname = utf8_to_wchar (fname); + wfname = native_to_wchar (fname); xfree (fname); if (!wfname) { @@ -322,11 +322,11 @@ scan_directory (const char *dname, scanctrl_t scanctrl) do { - char *fname = wchar_to_utf8 (fi.cFileName); + char *fname = wchar_to_native (fi.cFileName); if (!fname) { err = gpg_error_from_syserror (); - log_error ("error utf8-ing filename: %s\n", w32_strerror (-1)); + log_error ("error converting filename: %s\n", w32_strerror (-1)); break; } for (p=fname; *p; p++) ----------------------------------------------------------------------- Summary of changes: common/utf8conv.c | 65 +++++++++++++++++++++++++++++++++++++++++++-------- common/utf8conv.h | 2 ++ tools/gpgtar-create.c | 10 ++++---- 3 files changed, 62 insertions(+), 15 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 26 10:43:08 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 26 Jan 2016 10:43:08 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.1.10-147-g3e50236 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 3e50236d4ecc3601b2641bf4273a0ff64bb5fdc4 (commit) via b8bb16c6c08d3c2947f1ff67419b36eb203c5c1a (commit) via d33a34004bef028068538f099c32a0e292a004c3 (commit) via fbe1cf67aadc5a33cf815ddbcfc9669e43caa123 (commit) via ee87c653bf4b495714e8e6b024d0a8ace3a33452 (commit) via 039a55716b8abd22ce23a96dce34cf2dc4be1862 (commit) via 12c665b36cdc4b7189549698fc4cc1b3523b18f5 (commit) via 77bceb2902dd489443073d91836ea54376c60bf6 (commit) via afb8696126ff0babaab23e884ff5da008281e3b7 (commit) via 361820a3be48def2237f734d1383633891972f62 (commit) via fc0c71dfe5ea8f1c683101948c23f5d2064ee4cd (commit) via bb99b40bd1e624f58ca806ca16dc73d4d594a30a (commit) via 09117e769a093467cb47154f36d7dda613313e33 (commit) via bdb61351776c038d668310d9b5e5c32588ef6519 (commit) via 499743387f4d07847a2842358bc54f9237e0c2a7 (commit) via c26d299ef64caa0e8322e70546b833c9b8476fc3 (commit) via 4c6c973950df1471544f5d485e4cc2f4603bbd77 (commit) via cfa41890bb5ff306c07dad295136601fe47566a7 (commit) via 8b7f64f9dfc80b2a0ad235996b47369c2ba9b48f (commit) via d96e76d15f61812b950b64a60bc47117785a9dac (commit) via 79778a8dd5f61a6b7abeeb44b75d82932db788b7 (commit) via 576fedc5f6a1d76d6e1ed0cd3b54a1090230399e (commit) via 9309bda9581715d304305c8c5116f2cbb31aec77 (commit) via 437965e5622612941ed0fa55584811c65069242e (commit) via 56275e4392a7b38abe5fdd84fe9d67599cf5e6d1 (commit) via 3cccd5a83b96e4558642dcdf5d974f64ebdb9817 (commit) via 663c5d129a8f400cc6eb8ab7b91772d6e578152d (commit) via 3b1248e007a6bf830a3230ee2d9cc548205ec31a (commit) via 8241ed59d05e06252647b26477ed5c2f84895a26 (commit) via f5cceef115f0307664956d01c48b1b397fdad4b3 (commit) via 360534bde770f4845669de223154216d249b954b (commit) via 99cdc15cf103cace11aa6eec9e13a3a8ecf13004 (commit) via c7ca0f73dbe7c080b79f93f90f00ba2396fc4bd0 (commit) via 9b6c91469a804c60289a2ed21334dfd856c294bb (commit) via 8f1368d5e3f7654ad9cb100053535f728dff2344 (commit) via 4aceebf36f103eb380e21d12a1f08b7d6ea7cc8e (commit) via 160862978628b07ed5150ec2c8abad6af1656bc3 (commit) via 9dc355ad3ae0026ab04c424dc984d748b8fad393 (commit) via 96237b9a63a50aed1884cb06f84279b977d6a8fa (commit) via e2f984b4afffaa89bdeba2f5d447b5681237177e (commit) via 4619ea8e519215b4ae0685cd3881937ec26c32d3 (commit) via 4b4639b0b04dc82c550fa711dd7193e13fc4a428 (commit) via 3f52c7da3940ec06572270d511000dc7fe9c27d2 (commit) via 0617a05eb5cb76b239700355d897eb7b49088bf1 (commit) via b280aa6423c9492e8c5a9afa57339d06d957996d (commit) via eb9c021631174fde4c1c444bbc533a7a46d570cd (commit) via b2da3951a395366bf1644bc4c4eb42d657effe17 (commit) via 4970868d8d84d3a64b067e5aafc9f097621758d3 (commit) via 34bca9cd4b8517795833cb754b0d5b1dd33b08ed (commit) via 2aa42baaf3dd7c3ae613ae0c61760a17c8adfcd0 (commit) via 4d7ac43ff71fdadfd2e04621f74840a82fbe788a (commit) via 496643291e1e346434e9c98405c5a370957eb7d3 (commit) via 833ba5faa1340aff80a205acbb701d4ae1d594d0 (commit) via 8fd406c317ad7c2e375ae4f7d20656dadf6d7fcc (commit) via 8a56a38387c10c02ba0790c655dd5c1d08e4a724 (commit) via 008aa6e6d4b213c3a0d15509eb46cf168b6f2c94 (commit) via 126aebbb82667d160c8c4435898efeb3b43c4ec8 (commit) via 0de7d61437bd0bfbe645d5eed7a62df03129fb32 (commit) via a41638acf4808caa619f4f3f4c0dcd12be00d6f8 (commit) via 2c3e67430d9b523c85c81ae562223fd51e3608cc (commit) via c7389ae90fa4a70766400cc241ff6a45aa750324 (commit) via 85cc7449fb00ac85b0c2eecd22bd38b23f33edf5 (commit) via 09accc0e3d74e6289bed40b5bfc6479981cabfe4 (commit) via 7990586828a252e78d2ecacbaaa152431d7e08c8 (commit) via db82b6131d437bf6ba34db0e08b7dfa9edb11e45 (commit) via 6deafb92abe100ff67e3a0a230a39e8c0ad41900 (commit) via e64317c15e9960f3173d374e589f7c3565a4ad08 (commit) via 1fbfa1bf0a6ad0dc7ed67d12252643c2c6c7370a (commit) via 0a00115ee2049ab2357b7a14a51c7da185ffcabd (commit) via e70f7a54f29d727def2cfe9ea5ab9d461b4ce842 (commit) via f2ecbf7454fe1e4b87112b982d7ddcd496ebc1ff (commit) via ff3b607fc879b70665c187500022cc63e2a0cd86 (commit) via 575c15a090913d86cf8d75b2bc4471e371f234b9 (commit) via bf694cbc68cc7dfc0ce16bbe389014f8e8ee0d87 (commit) via 79b51bb8727bd3485229ac8ff5987558156d5d83 (commit) via 5ca57f1a697e875bae5a5c73f1a580c42ca75343 (commit) via 44aee35e69540510617aea4b886ef845590960fe (commit) via ee433d2b00c93b5a4e4ed54b9fb5806361df1b71 (commit) via 40959add1ba0efc1f4aa87fa075fa42423eff73c (commit) via e684c634df814b12d399dcdc375c35d3e9a137af (commit) via ae3e5c25ca4325dc15a105156600322c9e5cb9c4 (commit) via a9cbdcfd9c364557787f4a173cc59f14c067946e (commit) via 363ed2e892adc97fae97111bb56b64f9f809e8d5 (commit) via 04c9cddda95f2a8ca5c0cf10bb3dd6accf56cf45 (commit) via ef7b7e91600f35b4d682a6267001a8d30f0fa49f (commit) via b0c9867fb74d5a00335e6606d5bdcc5342ce26cd (commit) via aecf1a3c57ca8bf8050a3743b62fe142ccf9eb22 (commit) via 5c759924fb92b6de7ab3baed7871e5114ebd2505 (commit) via 4654384fe7a4dcee113dacf27c398b13dea5d0be (commit) via 7195b94345b0bb937477dc47fc5ec27fb108a099 (commit) via dc52995d85048ed12ae8b9f330e9ca41a4030aae (commit) via ffe0b7a6dd6bfaec62f81f511b3caf08978bb269 (commit) via 4103850c2e51274984f69443dee34295cbb8c282 (commit) via dc417bf0c555a7416d0aedde6645fd1087660f92 (commit) via 02eb9fc9d5863abcfed6af704e618f8cac7cc2e8 (commit) via 1cceba163b17b5e9fd7c89e5b40e3d7e1cffc885 (commit) via 4143cc1c3783c54a6f733f08a4739e4e5fb0c8b3 (commit) via 7fe4be0416cdc9269011bc4213b8a22d6ced295c (commit) via 478ca6c75bbf529f95974224dfb7d71bd5860a96 (commit) via ee8a8ec1cf4605e5af427f9c8b01b3609c82cbe7 (commit) via d8392299f311f8cfcf8bc02679dd3ae7ef8cc6d7 (commit) via ab9a9bce77d014159c68460f5a7c263fb72f3c1c (commit) via 98f9e14323bf806f674b3cc259e19ef6219b4378 (commit) via af142854a73567836a0ca44ad62900469c23d531 (commit) via 06436882c31ed6339b2bef2b59d24a1a8ba751fd (commit) via 72eaff1aa610f3c89a755f212760157e1932d847 (commit) via b30c15bf7c5336c4abb1f9dcd974cd77ba6c61a7 (commit) via e644aa7f5943174e3f7ba9408af71531fd125a0b (commit) via fc010b6c7fe14e609734e448775fa384421bdef1 (commit) via 4ffe44c5874ed655d82adfa7a85439fab91cde03 (commit) via 345ec7323d643528d2f904765708b5ecfe51f57b (commit) via 2ea1aebc924c3f0b2269f83cb1b80c75d9fa069c (commit) via f369efd6712148dc7ed40dba6d1ff5b0e169431a (commit) via 2e4e10c1dcd8dfeafec51f44ebf26acfeb770c41 (commit) via 0ea186db645da2b51a7e71f46793d447f2de5e3d (commit) via 4ee881bff4c8fdfa4b3b7a4b7afab611471e97f1 (commit) via 7baca033070e7811f75e2021100adf8e6a48907f (commit) via 7d129a7391115ff1d6a3541078a37a630ab7819f (commit) via 467e18b74b4790dcbdf3c816206d2fbaf170a12a (commit) via d80e1bc430bf64debdb6b08f0b7e5c42836781fa (commit) via f5aa51aaacfe13ab9528aa9b88d8ce8eb61362fc (commit) via e573e6188dada4d70f6897aa2fda3c3af8c50441 (commit) via d40975cbe8ff86fcc4a1b4963fdffc66ddee85ce (commit) via 4d3395ef1fcde0b8c454c09956863959d590ede6 (commit) via f0ae40b0c901e5f5c04c6ed5b2ab96ab7340b2bd (commit) via 1605e34fc365edd473aac15c9b4e5aadc1d95cf5 (commit) via 25f0f053cd306200a6211b5cf397838a59835ee7 (commit) via b78fce327101390685a4dc2f59fb1607b7cd6d0b (commit) via d6e01493cad6ff32f356185c7a2d2b5c2b86a937 (commit) via 6dc37c5fb60acbfd5ba2ab979852383eac8944e0 (commit) via d1a97585c5e73fbc7d4cf90e38f76ffc5aea305f (commit) via 1c8eae95a8b3b89bc0f49cb5f4938101634583dc (commit) via ee0fb42cd1487124011044ba3b5bb87548663e6c (commit) via 71726b627dcff015dc12568021b31d8ccede788a (commit) via b5cd68852d0e3485c9e13a8ddb70f05f36a65cb9 (commit) via 6d64ef869dfbcb7aaa802b80ed648393147e40d8 (commit) via 6ac57a482f7ae02db1bee4e4b861288fc6905adc (commit) via a8308ba5231682ce7c7d591a17e7e940fbd63189 (commit) via 582e684a48eb4f3716cecf7dc73eb93046efcfad (commit) via 45c814f348c89acd8d21d0607ffcf68e5c5c399e (commit) via 0c0dafd8e89bb702e856c661c1561e10cdcaf37f (commit) via a81aca6e1c2a4529d416d1989f15d7338d2ee81e (commit) via d955cb5e0700c6d2b6b26cb210b5a176d22d4235 (commit) via 2ae07f826aa551db8adf714158fce962790a6b54 (commit) via 30af06ee94d670fbc9dc08865e763c3446636185 (commit) via 762fcc027b0b4cc88c1f633804de619273d6a8b9 (commit) from df1e0d27fa0095438f7aa1f05b41b17da026bcea (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: Makefile.am | 17 +- NEWS | 3 + agent/agent.h | 8 + agent/call-pinentry.c | 12 + agent/call-scd.c | 22 +- agent/command-ssh.c | 174 ++++++++-- agent/command.c | 32 +- agent/cvt-openpgp.c | 10 +- agent/cvt-openpgp.h | 1 + agent/gpg-agent.c | 119 +++++++ agent/pksign.c | 14 +- autogen.sh | 2 +- build-aux/getswdb.sh | 20 ++ build-aux/speedo.mk | 42 ++- common/Makefile.am | 5 +- common/asshelp.c | 38 ++ common/asshelp.h | 4 + common/b64enc.c | 2 - common/call-gpg.c | 41 ++- common/call-gpg.h | 9 +- common/common-defs.h | 20 +- common/dotlock.c | 104 +++++- common/exectool.c | 440 +++++++++++++++++++++++ common/exectool.h | 56 +++ common/{userids.h => fwddecl.h} | 16 +- common/get-passphrase.c | 13 +- common/gettime.h | 20 +- common/iobuf.c | 53 +-- common/iobuf.h | 7 +- common/isascii.c | 19 +- common/keyserver.h | 20 +- common/membuf.c | 14 + common/membuf.h | 1 + common/mischelp.h | 28 -- common/status.c | 20 +- common/status.h | 21 +- common/stringhelp.c | 85 +++++ common/stringhelp.h | 3 + common/t-convert.c | 8 +- common/t-iobuf.c | 5 +- common/t-mapstrings.c | 7 +- common/t-stringhelp.c | 98 +++++- common/t-support.h | 4 +- common/t-timestuff.c | 35 +- common/tlv.c | 1 - common/types.h | 10 - common/userids.c | 1 - common/utf8conv.c | 65 +++- common/utf8conv.h | 2 + common/util.h | 131 +------ common/yesno.c | 20 +- configure.ac | 18 +- dirmngr/Makefile.am | 1 + dirmngr/crlcache.c | 7 +- dirmngr/dns-stuff.c | 2 + dirmngr/http.c | 31 +- dirmngr/http.h | 3 +- dirmngr/ks-action.c | 19 +- dirmngr/ks-engine-hkp.c | 30 +- dirmngr/ks-engine-http.c | 2 +- dirmngr/ks-engine.h | 2 +- dirmngr/misc.c | 16 +- dirmngr/misc.h | 2 +- dirmngr/t-dns-stuff.c | 6 +- dirmngr/t-http.c | 2 +- doc/DETAILS | 12 +- doc/Makefile.am | 4 +- doc/gpg-agent.texi | 7 + doc/gpg.texi | 98 +++--- doc/tools.texi | 73 ---- doc/whats-new-in-2.1.txt | 119 ++++--- g10/armor.c | 4 +- g10/call-agent.c | 136 ++++---- g10/call-agent.h | 4 +- g10/call-dirmngr.c | 49 ++- g10/card-util.c | 1 - g10/cipher.c | 2 +- g10/compress-bz2.c | 2 +- g10/compress.c | 2 +- g10/decrypt-data.c | 4 +- g10/delkey.c | 5 +- g10/dirmngr-conf.skel | 6 +- g10/encrypt.c | 5 +- g10/export.c | 455 ++++++++++++++++++++---- g10/getkey.c | 705 +++++++++++++++++++++++++++++++++++-- g10/gpg.c | 298 ++-------------- g10/gpgv.c | 7 + g10/import.c | 75 ++-- g10/keydb.c | 314 +++++++++++++++-- g10/keydb.h | 541 ++++------------------------- g10/keyedit.c | 170 ++++----- g10/keygen.c | 592 +++++++++---------------------- g10/keyid.c | 10 +- g10/keylist.c | 40 +-- g10/keyring.c | 357 +++++++++---------- g10/keyserver-internal.h | 1 + g10/keyserver.c | 63 ++-- g10/main.h | 26 +- g10/mainproc.c | 4 +- g10/mdfilter.c | 2 +- g10/misc.c | 46 +++ g10/options.h | 7 - g10/options.skel | 81 ++--- g10/packet.h | 1 + g10/parse-packet.c | 9 +- g10/pkclist.c | 82 ++++- g10/progress.c | 2 +- g10/revoke.c | 13 +- g10/server.c | 3 +- g10/sig-check.c | 641 ++++++++++++++++++---------------- g10/sign.c | 13 +- g10/skclist.c | 7 + g10/tdbio.c | 33 +- g10/test-stubs.c | 7 + g10/test.c | 11 +- g10/textfilter.c | 2 +- g10/tofu.c | 523 ++++++++++++++-------------- g10/trustdb.c | 41 ++- kbx/keybox-defs.h | 12 +- kbx/keybox-dump.c | 16 +- kbx/keybox-init.c | 96 ++++- kbx/keybox-openpgp.c | 1 - kbx/keybox-search.c | 47 ++- kbx/keybox-update.c | 105 +----- kbx/keybox-util.c | 133 +++++++ kbx/keybox.h | 20 +- po/POTFILES.in | 1 + po/de.po | 752 +++++++++++++++++++++++++++++++--------- po/ja.po | 158 +++------ po/ru.po | 123 +++---- scd/apdu.c | 3 + scd/app-openpgp.c | 21 +- sm/call-agent.c | 70 ++-- sm/call-dirmngr.c | 47 ++- sm/certchain.c | 14 +- sm/encrypt.c | 7 +- sm/export.c | 2 +- sm/fingerprint.c | 1 - sm/gpgsm.c | 2 +- sm/keydb.c | 54 +-- sm/keydb.h | 6 +- sm/server.c | 2 +- tests/openpgp/4gb-packet.test | 6 +- tests/openpgp/Makefile.am | 2 +- tests/openpgp/default-key.test | 73 ++++ tests/openpgp/gpgtar.test | 77 +++- tools/Makefile.am | 17 +- tools/gpgconf-comp.c | 4 + tools/gpgkey2ssh.c | 337 ------------------ tools/gpgtar-create.c | 72 +++- tools/gpgtar-extract.c | 26 +- tools/gpgtar-list.c | 34 +- tools/gpgtar.c | 25 +- tools/gpgtar.h | 2 +- 154 files changed, 6089 insertions(+), 4037 deletions(-) create mode 100644 common/exectool.c create mode 100644 common/exectool.h copy common/{userids.h => fwddecl.h} (72%) create mode 100755 tests/openpgp/default-key.test delete mode 100644 tools/gpgkey2ssh.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 26 12:00:25 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 26 Jan 2016 12:00:25 +0100 Subject: [git] ADNS-g10 - branch, justus/tor, created. adns-1.4-g10-6-8-g54f3128 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "ADNS migrated to autotools/libtool". The branch, justus/tor has been created at 54f312816e32ccd6519171940f381ccdce6822d8 (commit) - Log ----------------------------------------------------------------- commit 54f312816e32ccd6519171940f381ccdce6822d8 Author: Werner Koch Date: Fri Nov 20 13:15:40 2015 +0100 Also try port 9150 in Tor mode. * src/w32support.c (ECONNREFUSED): Define if missing. (adns__sock_wsa2errno): Map WSAECONNREFUSED. * src/event.c (socks_connect): Try port 9150. -- The Tor browser uses this port. Signed-off-by: Werner Koch diff --git a/src/event.c b/src/event.c index 064fbd9..5f4c8c1 100644 --- a/src/event.c +++ b/src/event.c @@ -164,6 +164,12 @@ socks_connect (adns_state ads, int fd, proxyaddr = (struct sockaddr *)&proxyaddr_in; proxyaddrlen = sizeof proxyaddr_in; ret = adns__sock_connect(fd, proxyaddr, proxyaddrlen); + if (ret && errno == ECONNREFUSED) + { + /* Assume the Tor browser is used. */ + proxyaddr_in.sin_port = htons (9150); + ret = adns__sock_connect(fd, proxyaddr, proxyaddrlen); + } if (ret) return ret; diff --git a/src/w32support.c b/src/w32support.c index fcf86aa..67b6b83 100644 --- a/src/w32support.c +++ b/src/w32support.c @@ -41,6 +41,12 @@ static int wsa_startup_failed; +/* Define missing error codes for older Windows compilers. */ +#ifndef ECONNREFUSED +#define ECONNREFUSED 107 +#endif + + int WINAPI DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) @@ -81,6 +87,8 @@ adns__sock_wsa2errno (int err) return ENOBUFS; case WSAEMSGSIZE: return EMSGSIZE; + case WSAECONNREFUSED: + return ECONNREFUSED; default: return EIO; } commit e59d05b8d440e9efdc4a4b328781b55306a91d2c Author: Werner Koch Date: Mon Nov 9 18:10:27 2015 +0100 Allow SOCKS5 authentication with username/password. * src/event.c (socks_connect): Implemedn authentication method 2. -- The credentials are given by the new config option adns_sockscred. Changing the credentials is an indication to Tor to use a new circuit. Tor ignore the actual values. Signed-off-by: Werner Koch diff --git a/src/event.c b/src/event.c index 925617d..064fbd9 100644 --- a/src/event.c +++ b/src/event.c @@ -149,8 +149,10 @@ socks_connect (adns_state ads, int fd, size_t proxyaddrlen; struct sockaddr_in6 *addr_in6; struct sockaddr_in *addr_in; - unsigned char buffer[22]; + unsigned char buffer[22+512]; /* The extra 512 bytes is used as + space for username:password. */ size_t buflen; + int method; memset (&proxyaddr_in, 0, sizeof proxyaddr_in); @@ -168,7 +170,11 @@ socks_connect (adns_state ads, int fd, /* Negotiate method. */ buffer[0] = 5; /* RFC-1928 VER field. */ buffer[1] = 1; /* NMETHODS */ - buffer[2] = 0; /* Method: No authentication required. */ + if (ads->sockscred) + method = 2; /* Method: username/password authentication. */ + else + method = 0; /* Method: No authentication required. */ + buffer[2] = method; adns__sigpipe_protect(ads); ret = adns__sock_write(fd, buffer, 3); adns__sigpipe_unprotect(ads); @@ -181,7 +187,7 @@ socks_connect (adns_state ads, int fd, ret = adns__sock_read(fd, buffer, 2); if (ret < 0) return ret; - if (ret != 2 || buffer[0] != 5 || buffer[1] != 0 ) + if (ret != 2 || buffer[0] != 5 || buffer[1] != method ) { /* Socks server returned wrong version or does not support our requested method. */ @@ -189,6 +195,66 @@ socks_connect (adns_state ads, int fd, return -1; } + if (ads->sockscred) + { + /* Username/Password sub-negotiation. */ + const char *password; + int ulen, plen; + + password = strchr (ads->sockscred, ':'); + if (!password) + { + errno = EINVAL; /* No password given. */ + return -1; + } + ulen = password - ads->sockscred; + password++; + plen = strlen (password); + if (!ulen || ulen > 255 || !plen || plen > 255) + { + errno = EINVAL; /* Credentials too long or too short. */ + return -1; + } + + buffer[0] = 1; /* VER of the sub-negotiation. */ + buffer[1] = ulen; + buflen = 2; + memcpy (buffer+buflen, ads->sockscred, ulen); + buflen += ulen; + buffer[buflen++] = plen; + memcpy (buffer+buflen, password, plen); + buflen += plen; + adns__sigpipe_protect(ads); + ret = adns__sock_write(fd, buffer, buflen); + adns__sigpipe_unprotect(ads); + WIPEMEMORY (buffer, buflen); + if (ret != buflen) + { + if (ret >= 0) + errno = EIO; + return -1; + } + ret = adns__sock_read(fd, buffer, 2); + if (ret != 2) + { + if (ret >= 0) + errno = EIO; + return -1; + } + if (buffer[0] != 1) + { + /* SOCKS server returned wrong version. */ + errno = EPROTO; + return -1; + } + if (buffer[1]) + { + /* SOCKS server denied access. */ + errno = EACCES; + return -1; + } + } + /* Send request details (rfc-1928, 4). */ buffer[0] = 5; /* VER */ buffer[1] = 1; /* CMD = CONNECT */ commit fd4837e72b5bca662b9153003c4921e077aad18b Author: Werner Koch Date: Mon Nov 9 18:01:43 2015 +0100 Add macro to safely clear memory. * src/internal.h (WIPEMEMORY): New. -- This kind of platform neutral code has been in use by GnuPG and Libgcrypt for ages. I am still waiting for some C committee f^D experts to figure that this makes use of undefined behaviour for volatile and they tell their optimizing-for-the-flat-world compiler to remove such code and thereby unveil passwords in memory (which actually happened for the standard memset). Signed-off-by: Werner Koch diff --git a/src/internal.h b/src/internal.h index acd6148..927284d 100644 --- a/src/internal.h +++ b/src/internal.h @@ -769,6 +769,14 @@ static inline int errno_resources(int e) { return e==ENOMEM || e==ENOBUFS; } ) +/* To avoid that a compiler optimizes certain memset calls away, this + macro may be used instead. */ +#define WIPEMEMORY(_ptr,_len) do { \ + volatile char *_vptr=(volatile char *)(_ptr); \ + size_t _vlen=(_len); \ + while(_vlen) { *_vptr=0; _vptr++; _vlen--; } \ + } while(0) + #endif commit a3fea30602d2aaea175ba1fc7abaa87fdf561ebe Author: Werner Koch Date: Mon Nov 9 18:08:03 2015 +0100 Make handling of returned SOCKS bound address more robust. * src/event.c (socks_connect): Allow proxy to return a v6 address instead of the provided v4 and vice versa. -- The specs say nothing about this but doing it this way is likely more robust that assuming the same family will be returned. Signed-off-by: Werner Koch diff --git a/src/event.c b/src/event.c index 8aae3af..925617d 100644 --- a/src/event.c +++ b/src/event.c @@ -220,7 +220,7 @@ socks_connect (adns_state ads, int fd, errno = EIO; return -1; } - ret = adns__sock_read(fd, buffer, buflen); + ret = adns__sock_read(fd, buffer, 10 /*(v4 length)*/); if (ret < 0) return ret; if (ret != buflen || buffer[0] != 5 || buffer[2] != 0 ) @@ -258,9 +258,23 @@ socks_connect (adns_state ads, int fd, case 0x07: /* Command not supported */ default: errno = ENOTSUP; /* Fixme: Is there a better errno? */ + break; } return -1; } + if (buffer[3] == 4) + { + /* ATYP indicates a v6 address. We need to read the remaining + 12 bytes to finialize the SOCKS5 intro. */ + ret = adns__sock_read(fd, buffer, 12 /*(v6-v4 length)*/); + if (ret != 12) + { + if (ret >= 0) + errno = EIO; + return -1; + } + } + /* FIXME: We have not way to store the actual address used by the server. */ commit 6d71a6f7f327c9d6763ae3021e609a4e6da4a00a Author: Werner Koch Date: Sun Nov 8 18:57:56 2015 +0100 Add config options adns_tormode and adns_sockscred. * src/internal.h (struct adns__state): Add field "sockscred". * src/setup.c (init_begin): Clear SOCKSCRED. (init_finish): Free SOCKSCRED. (ccf_options): Implement new options. * src/adns.h: Describe options. Signed-off-by: Werner Koch diff --git a/src/adns.h b/src/adns.h index 6ed9a97..9fe9a9a 100644 --- a/src/adns.h +++ b/src/adns.h @@ -515,6 +515,14 @@ int adns_init_logfn(adns_state *newstate_r, adns_initflags flags, * setting of adns_if_check_entex, adns_if_check_freq, or neither, * in the flags passed to adns_init. * + * adns_tormode + * Forces the use of virtual circuits over a SOCKS5 proxy running at + * port 9050. No UDP based communication is done. + * + * adns_sockscred:username:password + * Use username and password for SOCKS5 authentication. Default is + * no authentication. + * * There are a number of environment variables which can modify the * behaviour of adns. They take effect only if adns_init is used, and * the caller of adns_init can disable them using adns_if_noenv. In diff --git a/src/internal.h b/src/internal.h index 6bc0702..acd6148 100644 --- a/src/internal.h +++ b/src/internal.h @@ -347,6 +347,7 @@ struct adns__state { } sortlist[MAXSORTLIST]; char **searchlist; unsigned short rand48xsubi[3]; + char *sockscred; /* Malloced string with the SOCKS5 credentials or NULL. */ }; /* From setup.c: */ diff --git a/src/setup.c b/src/setup.c index 6b0172c..c33e2c5 100644 --- a/src/setup.c +++ b/src/setup.c @@ -269,6 +269,21 @@ static void ccf_options(adns_state ads, const char *fn, } continue; } + if (l==12 && !memcmp(word,"adns_tormode",12)) { + ads->iflags |= adns_if_tormode; + continue; + } + if (l>=15 && !memcmp(word,"adns_sockscred:",15)) { + l -= 15; + ads->sockscred = malloc (l + 1); + if (!ads->sockscred) { + saveerr(ads,errno); + continue; + } + memcpy (ads->sockscred, word+15, l); + ads->sockscred[l] = 0; + continue; + } adns__diag(ads,-1,0,"%s:%d: unknown option `%.*s'", fn,lno, l,word); } } @@ -557,6 +572,8 @@ static int init_begin(adns_state *ads_r, adns_initflags flags, ads->rand48xsubi[1]= (unsigned long)pid >> 16; ads->rand48xsubi[2]= pid ^ ((unsigned long)pid >> 16); + ads->sockscred = NULL; + *ads_r= ads; return 0; } @@ -585,6 +602,8 @@ static int init_finish(adns_state ads) { x_closeudp: close(ads->udpsocket); x_free: + if (ads->sockscred) + free (ads->sockscred); free(ads); return r; } commit ebc35be0fb258e14614e1312ab3a9e3f4884c2ce Author: Werner Koch Date: Tue Oct 20 14:48:23 2015 +0200 Add flag adns_if_tormode to provide a basic TOR mode. * src/adns.h (adns_if_tormode): New. * src/query.c (adns_submit): For a VC in tormode. (adns_submit_reverse_any): Ditto. (adns_synchronous): Ditto. * src/event.c (use_socks_p, socks_connect): New. Based on code from Libassuan. (adns__tcp_tryconnect): Move setnonblock after the init of ADDR. Call socks_connect if needed. * client/adh-opts.c (global_options): Add "--use-tor" (ov_tormode): New. * client/adnshost.h (ov_tormode): New declaration. * client/adh-query.c (ensure_adns_init): Enable TOR mode uf OV_TORMODE is set. -- This patch has the problem that connecting to the TOR server and more important establishing the TOR connection will block. Changing this would require quite some report of the TCP code in ADNS. In fact it has always been the case that when falling back to TCP mode and the connect would have blocked the connection won't be established but times outs. There is no retry code for if connect returns with EWOULDBLOCK or EINPROGRESS. To test the code this command can be used. adnshost --config 'nameserver 8.8.8.8' --use-tor NAME Signed-off-by: Werner Koch diff --git a/client/adh-opts.c b/client/adh-opts.c index 5bb7273..5797b6c 100644 --- a/client/adh-opts.c +++ b/client/adh-opts.c @@ -27,7 +27,7 @@ #include "adnshost.h" -int ov_env=1, ov_pipe=0, ov_asynch=0; +int ov_env=1, ov_pipe=0, ov_asynch=0, ov_tormode = 0; int ov_verbose= 0; adns_rrtype ov_type= adns_r_none; int ov_search=0, ov_qc_query=0, ov_qc_anshost=0, ov_qc_cname=1; @@ -43,6 +43,8 @@ static const struct optioninfo global_options[]= { "f", "pipe", &ov_pipe, 1 }, { ot_flag, "Allow answers to be reordered", "a", "asynch", &ov_asynch, 1 }, + { ot_flag, "Run over TOR", + 0, "use-tor", &ov_tormode, 1 }, { ot_desconly, "answer/error output format and destination (see below):" }, { ot_value, "Answers to stdout, errors as messages to stderr (default)", diff --git a/client/adh-query.c b/client/adh-query.c index b5cfad7..d74dbda 100644 --- a/client/adh-query.c +++ b/client/adh-query.c @@ -70,6 +70,7 @@ void ensure_adns_init(void) { initflags= adns_if_noautosys|adns_if_nosigpipe|ov_verbose; if (!ov_env) initflags |= adns_if_noenv; + if (ov_tormode) initflags |= adns_if_tormode; if (config_text) { r= adns_init_strcfg(&ads, initflags, stderr, config_text); diff --git a/client/adnshost.h b/client/adnshost.h index 876b021..fab3ac0 100644 --- a/client/adnshost.h +++ b/client/adnshost.h @@ -78,7 +78,7 @@ struct perqueryflags_remember { int ttl; }; -extern int ov_env, ov_pipe, ov_asynch; +extern int ov_env, ov_pipe, ov_asynch, ov_tormode; extern int ov_verbose; extern adns_rrtype ov_type; extern int ov_search, ov_qc_query, ov_qc_anshost, ov_qc_cname; diff --git a/src/adns.h b/src/adns.h index feb7cb1..6ed9a97 100644 --- a/src/adns.h +++ b/src/adns.h @@ -92,7 +92,8 @@ typedef enum { /* In general, or together the desired flags: */ adns_if_eintr= 0x0020,/* allow _wait and _synchronous to return EINTR */ adns_if_nosigpipe= 0x0040,/* applic has SIGPIPE ignored, do not protect */ adns_if_checkc_entex=0x0100,/* consistency checks on entry/exit to adns fns */ - adns_if_checkc_freq= 0x0300 /* consistency checks very frequently (slow!) */ + adns_if_checkc_freq= 0x0300,/* consistency checks very frequently (slow!) */ + adns_if_tormode= 0x1000 /* route all trafic via TOR. */ } adns_initflags; typedef enum { /* In general, or together the desired flags: */ diff --git a/src/event.c b/src/event.c index 6a88f98..8aae3af 100644 --- a/src/event.c +++ b/src/event.c @@ -9,6 +9,7 @@ * Copyright (C) 1997-2000,2003,2006 Ian Jackson * Copyright (C) 1999-2000,2003,2006 Tony Finch * Copyright (C) 1991 Massachusetts Institute of Technology + * Copyright (C) 2015 g10 Code GmbH * (See the file INSTALL for full details.) * * This program is free software; you can redistribute it and/or modify @@ -96,6 +97,177 @@ static void tcp_broken_events(adns_state ads) { ads->tcpstate= server_disconnected; } + +/* Return true if SOCKS shall be used. This is the case if + adns_if_tormode is set and the desired address is not the loopback + address. */ +static int +use_socks_p (adns_state ads, const struct sockaddr *addr) +{ + if (!(ads->iflags & adns_if_tormode)) + return 0; + else if (addr->sa_family == AF_INET6) + { + const 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) + { + const 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; +} + + +/* Connect to TOR using the SOCKS5 protocol. We assume that the + connection to the SOCKS proxy (TOR server) does not block; if it + would block we return and the the usual retry logic of the caller + kicks in. */ +static int +socks_connect (adns_state ads, int fd, + const struct sockaddr *addr, socklen_t length) +{ + int ret; + struct sockaddr_in proxyaddr_in; + struct sockaddr *proxyaddr; + size_t proxyaddrlen; + struct sockaddr_in6 *addr_in6; + struct sockaddr_in *addr_in; + unsigned char buffer[22]; + size_t buflen; + + memset (&proxyaddr_in, 0, sizeof proxyaddr_in); + + /* Connect to local host. */ + /* Fixme: First try to use IPv6. */ + proxyaddr_in.sin_family = AF_INET; + proxyaddr_in.sin_port = htons (9050); + proxyaddr_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + proxyaddr = (struct sockaddr *)&proxyaddr_in; + proxyaddrlen = sizeof proxyaddr_in; + ret = adns__sock_connect(fd, proxyaddr, proxyaddrlen); + if (ret) + return ret; + + /* Negotiate method. */ + buffer[0] = 5; /* RFC-1928 VER field. */ + buffer[1] = 1; /* NMETHODS */ + buffer[2] = 0; /* Method: No authentication required. */ + adns__sigpipe_protect(ads); + ret = adns__sock_write(fd, buffer, 3); + adns__sigpipe_unprotect(ads); + if (ret != 3) + { + if (ret >= 0) + errno = EIO; + return -1; + } + ret = adns__sock_read(fd, buffer, 2); + if (ret < 0) + return ret; + if (ret != 2 || buffer[0] != 5 || buffer[1] != 0 ) + { + /* Socks server returned wrong version or does not support our + requested method. */ + errno = ENOTSUP; /* Fixme: Is there a better errno? */ + return -1; + } + + /* Send request details (rfc-1928, 4). */ + buffer[0] = 5; /* VER */ + buffer[1] = 1; /* CMD = CONNECT */ + buffer[2] = 0; /* RSV */ + if (addr->sa_family == AF_INET6) + { + addr_in6 = (struct sockaddr_in6 *)addr; + + buffer[3] = 4; /* ATYP = IPv6 */ + memcpy (buffer+ 4, &addr_in6->sin6_addr.s6_addr, 16); /* DST.ADDR */ + memcpy (buffer+20, &addr_in6->sin6_port, 2); /* DST.PORT */ + buflen = 22; + } + else + { + addr_in = (struct sockaddr_in *)addr; + + buffer[3] = 1; /* ATYP = IPv4 */ + memcpy (buffer+4, &addr_in->sin_addr.s_addr, 4); /* DST.ADDR */ + memcpy (buffer+8, &addr_in->sin_port, 2); /* DST.PORT */ + buflen = 10; + } + adns__sigpipe_protect(ads); + ret = adns__sock_write(fd, buffer, buflen); + adns__sigpipe_unprotect(ads); + if (ret != buflen) + { + if (ret >= 0) + errno = EIO; + return -1; + } + ret = adns__sock_read(fd, buffer, buflen); + if (ret < 0) + return ret; + if (ret != buflen || buffer[0] != 5 || buffer[2] != 0 ) + { + /* Socks server returned wrong version or the reserved field is + not zero. */ + errno = EPROTO; + return -1; + } + if (buffer[1]) + { + switch (buffer[1]) + { + case 0x01: /* general SOCKS server failure. */ + errno = ENETDOWN; + break; + case 0x02: /* connection not allowed by ruleset. */ + errno = EACCES; + break; + case 0x03: /* Network unreachable */ + errno = ENETUNREACH; + break; + case 0x04: /* Host unreachable */ + errno = EHOSTUNREACH; + break; + case 0x05: /* Connection refused */ + errno = ECONNREFUSED; + break; + case 0x06: /* TTL expired */ + errno = ETIMEDOUT; + break; + case 0x08: /* Address type not supported */ + errno = EPROTONOSUPPORT; + break; + case 0x07: /* Command not supported */ + default: + errno = ENOTSUP; /* Fixme: Is there a better errno? */ + } + return -1; + } + /* FIXME: We have not way to store the actual address used by the + server. */ + + return 0; +} + + void adns__tcp_tryconnect(adns_state ads, struct timeval now) { int r, fd, tries; struct sockaddr_in addr; @@ -127,21 +299,41 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) { adns__diag(ads,-1,0,"cannot create TCP socket: %s",strerror(errno)); return; } - r= adns__setnonblock(ads,fd); - if (r) { - adns__diag(ads,-1,0,"cannot make TCP socket nonblocking:" - " %s",strerror(r)); - adns__sock_close(fd); - return; - } memset(&addr,0,sizeof(addr)); addr.sin_family= AF_INET; addr.sin_port= htons(DNS_PORT); addr.sin_addr= ads->servers[ads->tcpserver].addr; - r= adns__sock_connect(fd,(const struct sockaddr*)&addr,sizeof(addr)); + if (use_socks_p(ads, (const struct sockaddr*)&addr)) + { + r= socks_connect(ads, fd,(const struct sockaddr*)&addr,sizeof(addr)); + if (!r) + { + r= adns__setnonblock(ads,fd); + if (r) { + adns__diag(ads,-1,0,"cannot make TCP socket nonblocking:" + " %s",strerror(r)); + adns__sock_close(fd); + return; + } + } + } + else + { + r= adns__setnonblock(ads,fd); + if (r) { + adns__diag(ads,-1,0,"cannot make TCP socket nonblocking:" + " %s",strerror(r)); + adns__sock_close(fd); + return; + } + r= adns__sock_connect(fd,(const struct sockaddr*)&addr,sizeof(addr)); + } ads->tcpsocket= fd; ads->tcpstate= server_connecting; - if (r==0) { tcp_connected(ads,now); return; } + if (r==0) { + tcp_connected(ads,now); + return; + } if (errno == EWOULDBLOCK || errno == EINPROGRESS) { ads->tcptimeout= now; timevaladd(&ads->tcptimeout,TCPCONNMS); diff --git a/src/internal.h b/src/internal.h index c3aa213..6bc0702 100644 --- a/src/internal.h +++ b/src/internal.h @@ -277,7 +277,7 @@ struct adns__query { * too big for UDP / UDP timeout \ \ send via UDP * send via TCP / more retries \ \ * when conn'd / desired \ \ - * | | | + * or TOR-mode | | | * v | v * +-----------+ +-------------+ * | tcpw/tcpw | ________ | tosend/udpw | diff --git a/src/query.c b/src/query.c index 948b5d3..5c8c2cc 100644 --- a/src/query.c +++ b/src/query.c @@ -222,6 +222,9 @@ int adns_submit(adns_state ads, adns__consistency(ads,0,cc_entex); + if ((ads->iflags & adns_if_tormode)) + flags |= adns_qf_usevc; + typei= adns__findtype(type); if (!typei) return ENOSYS; @@ -287,6 +290,8 @@ int adns_submit_reverse_any(adns_state ads, int r, lreq; flags &= ~adns_qf_search; + if ((ads->iflags & adns_if_tormode)) + flags |= adns_qf_usevc; if (addr->sa_family != AF_INET) return ENOSYS; iaddr= (const unsigned char*) @@ -315,6 +320,10 @@ int adns_submit_reverse(adns_state ads, void *context, adns_query *query_r) { if (type != adns_r_ptr && type != adns_r_ptr_raw) return EINVAL; + + if ((ads->iflags & adns_if_tormode)) + flags |= adns_qf_usevc; + return adns_submit_reverse_any(ads,addr,"in-addr.arpa", type,flags,context,query_r); } @@ -326,7 +335,10 @@ int adns_synchronous(adns_state ads, adns_answer **answer_r) { adns_query qu; int r; - + + if ((ads->iflags & adns_if_tormode)) + flags |= adns_qf_usevc; + r= adns_submit(ads,owner,type,flags,0,&qu); if (r) return r; ----------------------------------------------------------------------- hooks/post-receive -- ADNS migrated to autotools/libtool http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 26 14:35:05 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 26 Jan 2016 14:35:05 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.10-153-g167558a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 167558a67e6d931a186ed35cc61902cc1463cc2f (commit) via e9e5e83ec14459c2fc9060c54fc8e7381b541acd (commit) via dc4a47097b01560c9267ca3c1b3317ef0bdf5269 (commit) via cc75359273adc699c1ff91493694e76266ee2592 (commit) via 7313c5fd5a73b0c90738bf393b609cdb388a7202 (commit) via d56f76afbd5429db8cf95ea4069290df97e82122 (commit) from 3e50236d4ecc3601b2641bf4273a0ff64bb5fdc4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: AUTHORS | 10 +- NEWS | 54 ++- README | 4 +- common/argparse.c | 4 +- configure.ac | 2 +- g10/gpg.c | 2 +- po/ca.po | 723 +++++++++++++++++++++++++--------- po/cs.po | 1131 +++++++++++++++++++++++++++++++++++------------------ po/da.po | 766 +++++++++++++++++++++++++++--------- po/de.po | 40 +- po/el.po | 710 ++++++++++++++++++++++++--------- po/eo.po | 704 ++++++++++++++++++++++++--------- po/es.po | 784 +++++++++++++++++++++++++++---------- po/et.po | 697 ++++++++++++++++++++++++--------- po/fi.po | 708 ++++++++++++++++++++++++--------- po/fr.po | 783 ++++++++++++++++++++++++++++--------- po/gl.po | 709 ++++++++++++++++++++++++--------- po/hu.po | 701 ++++++++++++++++++++++++--------- po/id.po | 703 ++++++++++++++++++++++++--------- po/it.po | 707 ++++++++++++++++++++++++--------- po/ja.po | 734 +++++++++++++++++++++++++--------- po/nb.po | 724 +++++++++++++++++++++++++--------- po/pl.po | 806 +++++++++++++++++++++++++++++--------- po/pt.po | 700 ++++++++++++++++++++++++--------- po/ro.po | 746 ++++++++++++++++++++++++++--------- po/ru.po | 830 ++++++++++++++++++++++++++++++--------- po/sk.po | 705 ++++++++++++++++++++++++--------- po/sv.po | 771 +++++++++++++++++++++++++++--------- po/tr.po | 768 ++++++++++++++++++++++++++---------- po/uk.po | 810 +++++++++++++++++++++++++++++--------- po/zh_CN.po | 730 +++++++++++++++++++++++++--------- po/zh_TW.po | 720 +++++++++++++++++++++++++--------- 32 files changed, 14103 insertions(+), 4883 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 26 14:40:26 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 26 Jan 2016 14:40:26 +0100 Subject: [git] gnupg-doc - branch, master, updated. d08d7a5305049f1c91f6fede3eeeafe313329217 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via d08d7a5305049f1c91f6fede3eeeafe313329217 (commit) from 86b046ac120b5b05539dce4cfdfc3dbdfc1823f7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d08d7a5305049f1c91f6fede3eeeafe313329217 Author: Werner Koch Date: Tue Jan 26 14:35:29 2016 +0100 swdb: Release gnupg 2.1.11 diff --git a/web/swdb.mac b/web/swdb.mac index c1adaf0..edc291e 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -19,16 +19,18 @@ # # GnuPG-2.1 # -#+macro: gnupg21_ver 2.1.10 -#+macro: gnupg21_date 2015-12-04 +#+macro: gnupg21_ver 2.1.11 +#+macro: gnupg21_date 2016-01-26 #+macro: gnupg21_branch STABLE-BRANCH-2-2 -#+macro: gnupg21_size 5052k -#+macro: gnupg21_sha1 4aa2594d2d364fe7708a9739ae7cebd251e536c4 -# -#+macro: gnupg21_w32_ver 2.1.10_20151204 -#+macro: gnupg21_w32_date 2015-12-04 -#+macro: gnupg21_w32_size 2617k -#+macro: gnupg21_w32_sha1 b86b642390e1bf1b144b84dfabdcd574a56c0ba8 +#+macro: gnupg21_size 5101k +#+macro: gnupg21_sha1 4af2032a60ff22e322b1c5b270d6d2228f59a3a3 +#+macro: gnupg21_sha2 b7b0fb2c8c5d47d7ec916d4a1097c0ddcb94a12bb1c0ac424ad86b1ee316b61a +# +#+macro: gnupg21_w32_ver 2.1.11_20160126 +#+macro: gnupg21_w32_date 2016-01-26 +#+macro: gnupg21_w32_size 2630k +#+macro: gnupg21_w32_sha1 ed237ba7bf8fd4fd3f2688ddd46b949dd15ebdd6 +#+macro: gnupg21_w32_sha2 4567227bd0885354b17f18639d13820bca81e5202b2388e7a6efa096864d66d4 # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 27 04:28:28 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 27 Jan 2016 04:28:28 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-2-gd0d9708 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via d0d97089706286fafd3c8ff56f3b5bf7ac07c6e0 (commit) from 167558a67e6d931a186ed35cc61902cc1463cc2f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d0d97089706286fafd3c8ff56f3b5bf7ac07c6e0 Author: NIIBE Yutaka Date: Wed Jan 27 12:24:05 2016 +0900 scd: Migrate to new API of libusb 1.0. * configure.ac (LIBUSB_CPPFLAGS): New. * scd/Makefile.am (AM_CPPFLAGS): Add LIBUSB_CPPFLAGS. * scd/ccid-driver.c: Use libusb 1.0 API. -- Changes are straightforward, not use any new features. Signed-off-by: NIIBE Yutaka diff --git a/configure.ac b/configure.ac index b790e6d..c200069 100644 --- a/configure.ac +++ b/configure.ac @@ -783,15 +783,52 @@ AM_PATH_KSBA("$NEED_KSBA_API:$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no) # # FiXME: Use GNUPG_CHECK_LIBUSB and modify to use separate AC_SUBSTs. if test "$use_ccid_driver" = yes ; then - AC_CHECK_LIB(usb, usb_bulk_write, - [ LIBUSB_LIBS="$LIBUSB_LIBS -lusb" - AC_DEFINE(HAVE_LIBUSB,1, - [defined if libusb is available]) + case $target in + *-*-darwin*) + LIBUSB_LIBS="-lusb-1.0 -Wl,-framework,CoreFoundation -Wl,-framework,IOKit" + ;; + *-*-freebsd*) + # FreeBSD has a native 1.0 compatible library by -lusb. + LIBUSB_LIBS="-lusb" + ;; + *) + LIBUSB_LIBS="-lusb-1.0" + ;; + esac + AC_CHECK_LIB(usb-1.0, libusb_init, + [ LIBUSB_LIBS="$LIBUSB_LIBS" + AC_DEFINE(HAVE_LIBUSB,1, [defined if libusb is available]) have_libusb=yes ]) - AC_CHECK_FUNCS(usb_create_match) + AC_DEFINE([HAVE_LIBUSB]) + AC_MSG_CHECKING([libusb include dir]) + usb_incdir_found="no" + for _incdir in "" "/usr/include/libusb-1.0" "/usr/local/include/libusb-1.0"; do + _libusb_save_cppflags=$CPPFLAGS + if test -n "${_incdir}"; then + CPPFLAGS="-I${_incdir} ${CPPFLAGS}" + fi + AC_PREPROC_IFELSE([AC_LANG_SOURCE([[@%:@include ]])], + [usb_incdir=${_incdir}; usb_incdir_found="yes"], []) + CPPFLAGS=${_libusb_save_cppflags} + if test "$usb_incdir_found" = "yes"; then + break + fi + done + if test "$usb_incdir_found" = "yes"; then + AC_MSG_RESULT([${usb_incdir}]) + else + AC_MSG_RESULT([not found]) + use_ccid_driver=no + fi + if test "$usb_incdir" = ""; then + LIBUSB_CPPFLAGS="" + else + LIBUSB_CPPFLAGS="-I${usb_incdir}" + fi fi AC_SUBST(LIBUSB_LIBS) +AC_SUBST(LIBUSB_CPPFLAGS) # # Check wether it is necessary to link against libdl. diff --git a/scd/Makefile.am b/scd/Makefile.am index 80e4c0f..f160244 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -21,7 +21,7 @@ EXTRA_DIST = ChangeLog-2011 scdaemon-w32info.rc libexec_PROGRAMS = scdaemon -AM_CPPFLAGS = -I$(top_srcdir)/common +AM_CPPFLAGS = -I$(top_srcdir)/common $(LIBUSB_CPPFLAGS) include $(top_srcdir)/am/cmacros.am diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 7f83f80..4d83b1f 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -83,11 +83,12 @@ #include #include #include +#include #ifdef HAVE_NPTH # include #endif /*HAVE_NPTH*/ -#include +#include #include "scdaemon.h" #include "iso7816.h" @@ -237,7 +238,7 @@ static struct structure is used as handle for most functions. */ struct ccid_driver_s { - usb_dev_handle *idev; + libusb_device_handle *idev; char *rid; int dev_fd; /* -1 for USB transport or file descriptor of the transport device. */ @@ -985,7 +986,7 @@ parse_ccid_descriptor (ccid_driver_t handle, static char * -get_escaped_usb_string (usb_dev_handle *idev, int idx, +get_escaped_usb_string (libusb_device_handle *idev, int idx, const char *prefix, const char *suffix) { int rc; @@ -1005,18 +1006,20 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx, /* First get the list of supported languages and use the first one. If we do don't find it we try to use English. Note that this is all in a 2 bute Unicode encoding using little endian. */ - rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, - (USB_DT_STRING << 8), 0, - (char*)buf, sizeof buf, 1000 /* ms timeout */); + rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, + (LIBUSB_DT_STRING << 8), 0, + (char*)buf, sizeof buf, 1000 /* ms timeout */); if (rc < 4) langid = 0x0409; /* English. */ else langid = (buf[3] << 8) | buf[2]; - rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, - (USB_DT_STRING << 8) + idx, langid, - (char*)buf, sizeof buf, 1000 /* ms timeout */); - if (rc < 2 || buf[1] != USB_DT_STRING) + rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, + (LIBUSB_DT_STRING << 8) + idx, langid, + (char*)buf, sizeof buf, 1000 /* ms timeout */); + if (rc < 2 || buf[1] != LIBUSB_DT_STRING) return NULL; /* Error or not a string. */ len = buf[0]; if (len > rc) @@ -1059,7 +1062,7 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx, physical reader after a reset. It returns an allocated and possibly percent escaped string or NULL if not enough memory is available. */ static char * -make_reader_id (usb_dev_handle *idev, +make_reader_id (libusb_device_handle *idev, unsigned int vendor, unsigned int product, unsigned char serialno_index) { @@ -1082,7 +1085,7 @@ make_reader_id (usb_dev_handle *idev, /* Helper to find the endpoint from an interface descriptor. */ static int -find_endpoint (struct usb_interface_descriptor *ifcdesc, int mode) +find_endpoint (const struct libusb_interface_descriptor *ifcdesc, int mode) { int no; int want_bulk_in = 0; @@ -1091,21 +1094,21 @@ find_endpoint (struct usb_interface_descriptor *ifcdesc, int mode) want_bulk_in = 0x80; for (no=0; no < ifcdesc->bNumEndpoints; no++) { - struct usb_endpoint_descriptor *ep = ifcdesc->endpoint + no; - if (ep->bDescriptorType != USB_DT_ENDPOINT) + const struct libusb_endpoint_descriptor *ep = ifcdesc->endpoint + no; + if (ep->bDescriptorType != LIBUSB_DT_ENDPOINT) ; else if (mode == 2 - && ((ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) - == USB_ENDPOINT_TYPE_INTERRUPT) - && (ep->bEndpointAddress & 0x80)) - return (ep->bEndpointAddress & 0x0f); - else if (((ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) - == USB_ENDPOINT_TYPE_BULK) + && ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) + == LIBUSB_TRANSFER_TYPE_INTERRUPT) + && (ep->bEndpointAddress & 0x80)) + return ep->bEndpointAddress; + else if (((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) + == LIBUSB_TRANSFER_TYPE_BULK) && (ep->bEndpointAddress & 0x80) == want_bulk_in) - return (ep->bEndpointAddress & 0x0f); + return ep->bEndpointAddress; } - /* Should never happen. */ - return mode == 2? 0x83 : mode == 1? 0x82 :1; + + return -1; } @@ -1116,10 +1119,10 @@ static int scan_or_find_usb_device (int scan_mode, int *readerno, int *count, char **rid_list, const char *readerid, - struct usb_device *dev, + struct libusb_device *dev, char **r_rid, - struct usb_device **r_dev, - usb_dev_handle **r_idev, + struct libusb_device_descriptor *desc, + libusb_device_handle **r_idev, unsigned char **ifcdesc_extra, size_t *ifcdesc_extra_len, int *interface_number, @@ -1128,29 +1131,33 @@ scan_or_find_usb_device (int scan_mode, int cfg_no; int ifc_no; int set_no; - struct usb_config_descriptor *config; - struct usb_interface *interface; - struct usb_interface_descriptor *ifcdesc; + const struct libusb_interface_descriptor *ifcdesc; char *rid; - usb_dev_handle *idev; + libusb_device_handle *idev; + int err; + + err = libusb_get_device_descriptor (dev, desc); + if (err < 0) + return err; *r_idev = NULL; - for (cfg_no=0; cfg_no < dev->descriptor.bNumConfigurations; cfg_no++) + for (cfg_no=0; cfg_no < desc->bNumConfigurations; cfg_no++) { - config = dev->config + cfg_no; - if(!config) - continue; + struct libusb_config_descriptor *config; - for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) + err = libusb_get_config_descriptor (dev, cfg_no, &config); + if (err < 0) { - interface = config->interface + ifc_no; - if (!interface) - continue; + libusb_free_config_descriptor (config); + continue; + } - for (set_no=0; set_no < interface->num_altsetting; set_no++) + for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) + { + for (set_no=0; set_no < config->interface->num_altsetting; set_no++) { - ifcdesc = (interface->altsetting + set_no); + ifcdesc = (config->interface->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 @@ -1161,24 +1168,24 @@ scan_or_find_usb_device (int scan_mode, && ifcdesc->bInterfaceSubClass == 0 && ifcdesc->bInterfaceProtocol == 0) || (ifcdesc->bInterfaceClass == 255 - && dev->descriptor.idVendor == VENDOR_SCM - && dev->descriptor.idProduct == SCM_SPR532) + && desc->idVendor == VENDOR_SCM + && desc->idProduct == SCM_SPR532) || (ifcdesc->bInterfaceClass == 255 - && dev->descriptor.idVendor == VENDOR_CHERRY - && dev->descriptor.idProduct == CHERRY_ST2000))) + && desc->idVendor == VENDOR_CHERRY + && desc->idProduct == CHERRY_ST2000))) { - idev = usb_open (dev); - if (!idev) + err = libusb_open (dev, &idev); + if (err < 0) { DEBUGOUT_1 ("usb_open failed: %s\n", - strerror (errno)); + libusb_error_name (err)); continue; /* with next setting. */ } rid = make_reader_id (idev, - dev->descriptor.idVendor, - dev->descriptor.idProduct, - dev->descriptor.iSerialNumber); + desc->idVendor, + desc->idProduct, + desc->iSerialNumber); if (rid) { if (scan_mode) @@ -1219,16 +1226,16 @@ scan_or_find_usb_device (int scan_mode, if (ifcdesc_extra && ifcdesc_extra_len) { *ifcdesc_extra = malloc (ifcdesc - ->extralen); + ->extra_length); if (!*ifcdesc_extra) { - usb_close (idev); + libusb_close (idev); free (rid); return 1; /* Out of core. */ } memcpy (*ifcdesc_extra, ifcdesc->extra, - ifcdesc->extralen); - *ifcdesc_extra_len = ifcdesc->extralen; + ifcdesc->extra_length); + *ifcdesc_extra_len = ifcdesc->extra_length; } if (interface_number) @@ -1241,8 +1248,6 @@ scan_or_find_usb_device (int scan_mode, if (ep_intr) *ep_intr = find_endpoint (ifcdesc, 2); - if (r_dev) - *r_dev = dev; if (r_rid) { *r_rid = rid; @@ -1265,7 +1270,7 @@ scan_or_find_usb_device (int scan_mode, free (rid); } - usb_close (idev); + libusb_close (idev); idev = NULL; return 0; } @@ -1316,27 +1321,27 @@ scan_or_find_usb_device (int scan_mode, static int scan_or_find_devices (int readerno, const char *readerid, char **r_rid, - struct usb_device **r_dev, + struct libusb_device_descriptor *r_desc, unsigned char **ifcdesc_extra, size_t *ifcdesc_extra_len, int *interface_number, int *ep_bulk_out, int *ep_bulk_in, int *ep_intr, - usb_dev_handle **r_idev, + libusb_device_handle **r_idev, int *r_fd) { char *rid_list = NULL; int count = 0; - struct usb_bus *busses, *bus; - struct usb_device *dev = NULL; - usb_dev_handle *idev = NULL; + libusb_device **dev_list = NULL; + libusb_device *dev; + libusb_device_handle *idev = NULL; int scan_mode = (readerno == -1 && !readerid); int i; + ssize_t n; + struct libusb_device_descriptor desc; /* Set return values to a default. */ if (r_rid) *r_rid = NULL; - if (r_dev) - *r_dev = NULL; if (ifcdesc_extra) *ifcdesc_extra = NULL; if (ifcdesc_extra_len) @@ -1354,39 +1359,32 @@ scan_or_find_devices (int readerno, const char *readerid, assert (r_rid); } - usb_find_busses(); - usb_find_devices(); - -#ifdef HAVE_USB_GET_BUSSES - busses = usb_get_busses(); -#else - busses = usb_busses; -#endif + n = libusb_get_device_list (NULL, &dev_list); - for (bus = busses; bus; bus = bus->next) + for (i = 0; i < n; i++) { - for (dev = bus->devices; dev; dev = dev->next) + dev = dev_list[i]; + if (scan_or_find_usb_device (scan_mode, &readerno, &count, &rid_list, + readerid, + dev, + r_rid, + &desc, + &idev, + ifcdesc_extra, + ifcdesc_extra_len, + interface_number, + ep_bulk_out, ep_bulk_in, ep_intr)) { - if (scan_or_find_usb_device (scan_mode, &readerno, &count, &rid_list, - readerid, - dev, - r_rid, - r_dev, - &idev, - ifcdesc_extra, - ifcdesc_extra_len, - interface_number, - ep_bulk_out, ep_bulk_in, ep_intr)) + /* Found requested device or out of core. */ + if (!idev) { - /* Found requested device or out of core. */ - if (!idev) - { - free (rid_list); - return -1; /* error */ - } - *r_idev = idev; - return 0; + free (rid_list); + return -1; /* error */ } + *r_idev = idev; + if (r_desc) + memcpy (r_desc, &desc, sizeof (struct libusb_device_descriptor)); + return 0; } } @@ -1501,7 +1499,7 @@ ccid_get_reader_list (void) if (!initialized_usb) { - usb_init (); + libusb_init (NULL); initialized_usb = 1; } @@ -1546,20 +1544,20 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid, const char **rdrname_p) { int rc = 0; - struct usb_device *dev = NULL; - usb_dev_handle *idev = NULL; + libusb_device_handle *idev = NULL; int dev_fd = -1; char *rid = NULL; unsigned char *ifcdesc_extra = NULL; size_t ifcdesc_extra_len; int readerno; int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr; + struct libusb_device_descriptor desc; *handle = NULL; if (!initialized_usb) { - usb_init (); + libusb_init (NULL); initialized_usb = 1; } @@ -1581,7 +1579,7 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid, else readerno = 0; /* Default. */ - if (scan_or_find_devices (readerno, readerid, &rid, &dev, + 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) ) @@ -1607,9 +1605,9 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid, { (*handle)->idev = idev; (*handle)->dev_fd = -1; - (*handle)->id_vendor = dev->descriptor.idVendor; - (*handle)->id_product = dev->descriptor.idProduct; - (*handle)->bcd_device = dev->descriptor.bcdDevice; + (*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; @@ -1639,8 +1637,8 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid, goto leave; } - rc = usb_claim_interface (idev, ifc_no); - if (rc) + rc = libusb_claim_interface (idev, ifc_no); + if (rc < 0) { DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); rc = CCID_DRIVER_ERR_CARD_IO_ERROR; @@ -1656,7 +1654,7 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid, { free (rid); if (idev) - usb_close (idev); + libusb_close (idev); if (dev_fd != -1) close (dev_fd); free (*handle); @@ -1697,8 +1695,8 @@ do_close_reader (ccid_driver_t handle) } if (handle->idev) { - usb_release_interface (handle->idev, handle->ifc_no); - usb_close (handle->idev); + libusb_release_interface (handle->idev, handle->ifc_no); + libusb_close (handle->idev); handle->idev = NULL; } if (handle->dev_fd != -1) @@ -1721,8 +1719,7 @@ int ccid_shutdown_reader (ccid_driver_t handle) { int rc = 0; - struct usb_device *dev = NULL; - usb_dev_handle *idev = NULL; + libusb_device_handle *idev = NULL; unsigned char *ifcdesc_extra = NULL; size_t ifcdesc_extra_len; int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr; @@ -1732,7 +1729,7 @@ ccid_shutdown_reader (ccid_driver_t handle) do_close_reader (handle); - if (scan_or_find_devices (-1, handle->rid, NULL, &dev, + if (scan_or_find_devices (-1, handle->rid, NULL, NULL, &ifcdesc_extra, &ifcdesc_extra_len, &ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr, &idev, NULL) || !idev) @@ -1756,7 +1753,7 @@ ccid_shutdown_reader (ccid_driver_t handle) goto leave; } - rc = usb_claim_interface (idev, ifc_no); + rc = libusb_claim_interface (idev, ifc_no); if (rc) { DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); @@ -1770,7 +1767,7 @@ ccid_shutdown_reader (ccid_driver_t handle) if (rc) { if (handle->idev) - usb_close (handle->idev); + libusb_close (handle->idev); handle->idev = NULL; if (handle->dev_fd != -1) close (handle->dev_fd); @@ -1843,11 +1840,6 @@ writen (int fd, const void *buf, size_t nbytes) return 0; } -#if defined(ENXIO) && !defined(LIBUSB_PATH_MAX) && defined(__GNU_LIBRARY__) -#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENXIO /* libusb-compat */ -#elif defined(ENODEV) -#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENODEV /* Original libusb */ -#endif /* Write a MSG of length MSGLEN to the designated bulk out endpoint. Returns 0 on success. */ @@ -1916,35 +1908,23 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen, if (handle->idev) { - rc = usb_bulk_write (handle->idev, - handle->ep_bulk_out, - (char*)msg, msglen, - 5000 /* ms timeout */); - if (rc == msglen) + int transferred; + + rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out, + (char*)msg, msglen, &transferred, + 5000 /* ms timeout */); + if (rc == 0 && transferred == msglen) return 0; -#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE - if (rc == -(LIBUSB_ERRNO_NO_SUCH_DEVICE)) - { - /* The Linux libusb returns a negative error value. Catch - the most important one. */ - errno = LIBUSB_ERRNO_NO_SUCH_DEVICE; - rc = -1; - } -#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/ - if (rc == -1) + if (rc < 0) { - DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno)); -#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE - if (errno == LIBUSB_ERRNO_NO_SUCH_DEVICE) + DEBUGOUT_1 ("usb_bulk_write error: %s\n", libusb_error_name (rc)); + if (rc == LIBUSB_ERROR_NO_DEVICE) { handle->enodev_seen = 1; return CCID_DRIVER_ERR_NO_READER; } -#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/ } - else - DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc); } else { @@ -1981,14 +1961,11 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, retry: if (handle->idev) { - rc = usb_bulk_read (handle->idev, - handle->ep_bulk_in, - (char*)buffer, length, - timeout); + rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in, + (char*)buffer, length, &msglen, timeout); if (rc < 0) { - rc = errno; - DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (rc)); + DEBUGOUT_1 ("usb_bulk_read error: %s\n", libusb_error_name (rc)); if (rc == EAGAIN && eagain_retries++ < 3) { my_sleep (1); @@ -1996,7 +1973,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, } return CCID_DRIVER_ERR_CARD_IO_ERROR; } - *nread = msglen = rc; + *nread = msglen; } else { @@ -2117,17 +2094,17 @@ abort_cmd (ccid_driver_t handle, int seqno) /* Send the abort command to the control pipe. Note that we don't need to keep track of sent abort commands because there should never be another thread using the same slot concurrently. */ - rc = usb_control_msg (handle->idev, - 0x21,/* bmRequestType: host-to-device, - class specific, to interface. */ - 1, /* ABORT */ - (seqno << 8 | 0 /* slot */), - handle->ifc_no, - dummybuf, 0, - 1000 /* ms timeout */); + rc = libusb_control_transfer (handle->idev, + 0x21,/* bmRequestType: host-to-device, + class specific, to interface. */ + 1, /* ABORT */ + (seqno << 8 | 0 /* slot */), + handle->ifc_no, + dummybuf, 0, + 1000 /* ms timeout */); if (rc < 0) { - DEBUGOUT_1 ("usb_control_msg error: %s\n", strerror (errno)); + DEBUGOUT_1 ("usb_control_msg error: %s\n", libusb_error_name (rc)); return CCID_DRIVER_ERR_CARD_IO_ERROR; } @@ -2137,6 +2114,8 @@ abort_cmd (ccid_driver_t handle, int seqno) seqno--; /* Adjust for next increment. */ do { + int transferred; + seqno++; msg[0] = PC_to_RDR_Abort; msg[5] = 0; /* slot */ @@ -2147,32 +2126,27 @@ abort_cmd (ccid_driver_t handle, int seqno) msglen = 10; set_msg_len (msg, 0); - rc = usb_bulk_write (handle->idev, - handle->ep_bulk_out, - (char*)msg, msglen, - 5000 /* ms timeout */); - if (rc == msglen) + rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out, + (char*)msg, msglen, &transferred, + 5000 /* ms timeout */); + if (rc == 0 && transferred == msglen) rc = 0; - else if (rc == -1) + else if (rc < 0) DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n", - strerror (errno)); - else - DEBUGOUT_1 ("usb_bulk_write failed in abort_cmd: %d\n", rc); + libusb_error_name (rc)); if (rc) return rc; - rc = usb_bulk_read (handle->idev, - handle->ep_bulk_in, - (char*)msg, sizeof msg, - 5000 /*ms timeout*/); + rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in, + (char*)msg, sizeof msg, &msglen, + 5000 /*ms timeout*/); if (rc < 0) { DEBUGOUT_1 ("usb_bulk_read error in abort_cmd: %s\n", - strerror (errno)); + libusb_error_name (rc)); return CCID_DRIVER_ERR_CARD_IO_ERROR; } - msglen = rc; if (msglen < 10) { @@ -2283,11 +2257,10 @@ ccid_poll (ccid_driver_t handle) if (handle->idev) { - rc = usb_bulk_read (handle->idev, - handle->ep_intr, - (char*)msg, sizeof msg, - 0 /* ms timeout */ ); - if (rc < 0 && errno == ETIMEDOUT) + rc = libusb_bulk_transfer (handle->idev, handle->ep_intr, + (char*)msg, sizeof msg, &msglen, + 0 /* ms timeout */ ); + if (rc == LIBUSB_ERROR_TIMEOUT) return 0; } else @@ -2295,13 +2268,10 @@ ccid_poll (ccid_driver_t handle) if (rc < 0) { - DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno)); + DEBUGOUT_1 ("usb_intr_read error: %s\n", libusb_error_name (rc)); return CCID_DRIVER_ERR_CARD_IO_ERROR; } - msglen = rc; - rc = 0; - if (msglen < 1) { DEBUGOUT ("intr-in msg too short\n"); @@ -2365,8 +2335,8 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits) if (!retries) { DEBUGOUT ("USB: CALLING USB_CLEAR_HALT\n"); - usb_clear_halt (handle->idev, handle->ep_bulk_in); - usb_clear_halt (handle->idev, handle->ep_bulk_out); + libusb_clear_halt (handle->idev, handle->ep_bulk_in); + libusb_clear_halt (handle->idev, handle->ep_bulk_out); } else DEBUGOUT ("USB: RETRYING bulk_in AGAIN\n"); @@ -3112,7 +3082,7 @@ ccid_transceive (ccid_driver_t handle, if (tpdulen < 4) { - usb_clear_halt (handle->idev, handle->ep_bulk_in); + libusb_clear_halt (handle->idev, handle->ep_bulk_in); return CCID_DRIVER_ERR_ABORTED; } @@ -3546,7 +3516,7 @@ ccid_transceive_secure (ccid_driver_t handle, if (tpdulen < 4) { - usb_clear_halt (handle->idev, handle->ep_bulk_in); + libusb_clear_halt (handle->idev, handle->ep_bulk_in); return CCID_DRIVER_ERR_ABORTED; } if (debug_level > 1) ----------------------------------------------------------------------- Summary of changes: configure.ac | 47 +++++++- scd/Makefile.am | 2 +- scd/ccid-driver.c | 330 +++++++++++++++++++++++++----------------------------- 3 files changed, 193 insertions(+), 186 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 27 14:28:30 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 27 Jan 2016 14:28:30 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-6-g1b90b52 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 1b90b52a56b4f808ad29a7ef79aeafc03c7424b4 (commit) via ab7d41b69ce569270b25bc69f88b8b420465366c (commit) via 4d67144142f04184b835e50314eb21b882b9e00a (commit) via f099042d82ed49be0ed546a751e26a10c4e01a47 (commit) from d0d97089706286fafd3c8ff56f3b5bf7ac07c6e0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1b90b52a56b4f808ad29a7ef79aeafc03c7424b4 Author: Werner Koch Date: Wed Jan 27 14:23:19 2016 +0100 scd: Fix detection of libusb. * configure.ac (HAVE_LIBUSB): Clear if no header file was found. (LIBUSB_LIBS): Ditto. -- This allows to use commit d0d9708 when libusb is installed without the header files. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index c200069..81fde82 100644 --- a/configure.ac +++ b/configure.ac @@ -797,10 +797,7 @@ if test "$use_ccid_driver" = yes ; then esac AC_CHECK_LIB(usb-1.0, libusb_init, [ LIBUSB_LIBS="$LIBUSB_LIBS" - AC_DEFINE(HAVE_LIBUSB,1, [defined if libusb is available]) - have_libusb=yes - ]) - AC_DEFINE([HAVE_LIBUSB]) + have_libusb=yes ]) AC_MSG_CHECKING([libusb include dir]) usb_incdir_found="no" for _incdir in "" "/usr/include/libusb-1.0" "/usr/local/include/libusb-1.0"; do @@ -819,9 +816,16 @@ if test "$use_ccid_driver" = yes ; then AC_MSG_RESULT([${usb_incdir}]) else AC_MSG_RESULT([not found]) + usb_incdir="" + have_libusb=no use_ccid_driver=no + LIBUSB_LIBS="" fi - if test "$usb_incdir" = ""; then + + if test "$have_libusb" = yes; then + AC_DEFINE(HAVE_LIBUSB,1, [defined if libusb is available]) + fi + if test x"$usb_incdir" = x; then LIBUSB_CPPFLAGS="" else LIBUSB_CPPFLAGS="-I${usb_incdir}" commit ab7d41b69ce569270b25bc69f88b8b420465366c Author: Werner Koch Date: Wed Jan 27 13:58:20 2016 +0100 gpg: Shorten the --tofu-policy help text -- Using "help" as value lists the options. Not having the current options in the help text also makes it easier to keep translations clean. Signed-off-by: Werner Koch diff --git a/g10/gpg.c b/g10/gpg.c index 56bbd0d..330d5a3 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -486,7 +486,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aGenRandom,"gen-random", "@" ), ARGPARSE_c (aServer, "server", N_("run in server mode")), ARGPARSE_c (aTOFUPolicy, "tofu-policy", - N_("|VALUE|set the TOFU policy for a key (good, unknown, bad, ask, auto)")), + N_("|VALUE|set the TOFU policy for a key")), ARGPARSE_group (301, N_("@\nOptions:\n ")), commit 4d67144142f04184b835e50314eb21b882b9e00a Author: Werner Koch Date: Wed Jan 27 13:55:31 2016 +0100 dirmngr: Build fix for FreeBSD (EAI macros) * dirmngr/dns-stuff.c (map_eai_to_gpg_error): Map EAI_NODATA and EAI_ADDRFAMILY only if defined. -- Reported-by: Christoph Moench-Tegeder Signed-off-by: Werner Koch diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 63dfc8d..40c71f3 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -177,13 +177,17 @@ map_eai_to_gpg_error (int ec) case EAI_BADFLAGS: err = gpg_error (GPG_ERR_INV_FLAG); break; case EAI_FAIL: err = gpg_error (GPG_ERR_SERVER_FAILED); break; case EAI_MEMORY: err = gpg_error (GPG_ERR_ENOMEM); break; +#ifdef EAI_NODATA case EAI_NODATA: err = gpg_error (GPG_ERR_NO_DATA); break; +#endif case EAI_NONAME: err = gpg_error (GPG_ERR_NO_NAME); break; case EAI_SERVICE: err = gpg_error (GPG_ERR_NOT_SUPPORTED); break; case EAI_FAMILY: err = gpg_error (GPG_ERR_EAFNOSUPPORT); break; case EAI_SOCKTYPE: err = gpg_error (GPG_ERR_ESOCKTNOSUPPORT); break; #ifndef HAVE_W32_SYSTEM +# ifdef EAI_ADDRFAMILY case EAI_ADDRFAMILY:err = gpg_error (GPG_ERR_EADDRNOTAVAIL); break; +# endif case EAI_SYSTEM: err = gpg_error_from_syserror (); break; #endif default: err = gpg_error (GPG_ERR_UNKNOWN_ERRNO); break; commit f099042d82ed49be0ed546a751e26a10c4e01a47 Author: Ineiev Date: Wed Jan 27 10:42:16 2016 +0100 doc: Typo fixes -- diff --git a/doc/TRANSLATE b/doc/TRANSLATE index 38a6fd9..2a20aad 100644 --- a/doc/TRANSLATE +++ b/doc/TRANSLATE @@ -26,7 +26,7 @@ help used to be translated the usual way with gettext but it turned out that this is too inflexible and does for example not allow to correct little mistakes in the English text. For some newer features we require editable help files anyway and thus the existing help -strings have neen moved to plain text files names "help.LL.txt". We +strings have been moved to plain text files names "help.LL.txt". We distribute these files and allow overriding them by files of that name in /etc/gnupg. The syntax of these files is documented in doc/help.txt. This is also the original we use to describe new diff --git a/doc/help.txt b/doc/help.txt index f545c2b..e92cfbe 100644 --- a/doc/help.txt +++ b/doc/help.txt @@ -207,7 +207,7 @@ N to change the name. C to change the comment. E to change the email address. O to continue with key generation. -Q to to quit the key generation. +Q to quit the key generation. . .gpg.keygen.sub.okay @@ -337,7 +337,7 @@ file (which is shown in brackets) will be used. .gpg.ask_revocation_reason.code # revoke.c (ask_revocation_reason) -You should specify a reason for the certification. Depending on the +You should specify a reason for the revocation. Depending on the context you have the ability to choose from this list: "Key has been compromised" Use this if you have a reason to believe that unauthorized persons @@ -373,7 +373,7 @@ your system administrator whether you should trust this certificate. .gpgsm.crl-problem -# This tex is displayed by the audit log for problems with +# This text is displayed by the audit log for problems with # the CRL or OCSP checking. Depending on your configuration a problem retrieving the CRL or performing an OCSP check occurred. There are a great variety of ----------------------------------------------------------------------- Summary of changes: configure.ac | 14 +++++++++----- dirmngr/dns-stuff.c | 4 ++++ doc/TRANSLATE | 2 +- doc/help.txt | 6 +++--- g10/gpg.c | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 27 14:36:35 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 27 Jan 2016 14:36:35 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-7-g3d952a2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3d952a2fe5da9d84c20d3debdcc1e425b08781c6 (commit) from 1b90b52a56b4f808ad29a7ef79aeafc03c7424b4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3d952a2fe5da9d84c20d3debdcc1e425b08781c6 Author: Werner Koch Date: Wed Jan 27 14:31:13 2016 +0100 scd: Fix size_t/int mismatch in libusb * scd/ccid-driver.c (bulk_in, abort_cmd, ccid_poll): Change msglen to int. -- Signed-off-by: Werner Koch diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 4d83b1f..87cec32 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1952,7 +1952,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, int no_debug) { int rc; - size_t msglen; + int msglen; int eagain_retries = 0; /* Fixme: The next line for the current Valgrind without support @@ -1973,6 +1973,8 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, } return CCID_DRIVER_ERR_CARD_IO_ERROR; } + if (msglen < 0) + return CCID_DRIVER_ERR_INV_VALUE; /* Faulty libusb. */ *nread = msglen; } else @@ -2081,7 +2083,7 @@ abort_cmd (ccid_driver_t handle, int seqno) int rc; char dummybuf[8]; unsigned char msg[100]; - size_t msglen; + int msglen; if (!handle->idev) { @@ -2252,7 +2254,7 @@ ccid_poll (ccid_driver_t handle) { int rc; unsigned char msg[10]; - size_t msglen; + int msglen; int i, j; if (handle->idev) ----------------------------------------------------------------------- Summary of changes: scd/ccid-driver.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 28 17:40:23 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 28 Jan 2016 17:40:23 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-303-g2cf2ca7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 2cf2ca7bb9741ac86e8aa92d8f03b1c5f5938897 (commit) from 191c2e4fe2dc0e00f61aa44e011a9596887e6ce1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2cf2ca7bb9741ac86e8aa92d8f03b1c5f5938897 Author: Werner Koch Date: Thu Jan 28 17:33:51 2016 +0100 ecc: New API function gcry_mpi_ec_decode_point. * mpi/ec.c (_gcry_mpi_ec_decode_point): New. * cipher/ecc-common.h: Move two prototypes to ... * src/ec-context.h: here. * src/gcrypt.h.in (gcry_mpi_ec_decode_point): New. * src/libgcrypt.def (gcry_mpi_ec_decode_point): New. * src/libgcrypt.vers (gcry_mpi_ec_decode_point): New. * src/visibility.c (gcry_mpi_ec_decode_point): New. * src/visibility.h: Add new function. -- This new function make the use of the gcry_mpi_ec_curve_point function possible in many contexts. Here is a code snippet which could be used in gpg to check a point: static gpg_error_t check_point (PKT_public_key *pk, gcry_mpi_t m_point) { gpg_error_t err; char *curve; gcry_ctx_t gctx = NULL; gcry_mpi_point_t point = NULL; /* Get the curve name from the first OpenPGP key parameter. */ curve = openpgp_oid_to_str (pk->pkey[0]); if (!curve) { err = gpg_error_from_syserror (); goto leave; } point = gcry_mpi_point_new (0); if (!point) { err = gpg_error_from_syserror (); goto leave; } err = gcry_mpi_ec_new (&gctx, NULL, curve); if (err) goto leave; err = gcry_mpi_ec_decode_point (point, m_point, gctx); if (err) goto leave; if (!gcry_mpi_ec_curve_point (point, gctx)) err = gpg_error (GPG_ERR_BAD_DATA); leave: gcry_ctx_release (gctx); gcry_mpi_point_release (point); xfree (curve); return err; } Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 22565ed..79d1931 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,7 @@ Noteworthy changes in version 1.7.0 (unreleased) gcry_cipher_set_sbox NEW macro. GCRY_MD_GOSTR3411_CP NEW. gcry_mpi_ec_sub NEW. + gcry_mpi_ec_decode_point NEW. GCRY_CIPHER_MODE_OCB NEW. GCRYCTL_SET_TAGLEN NEW. gcry_cipher_final NEW macro. diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h index 4e528af..748e6db 100644 --- a/cipher/ecc-common.h +++ b/cipher/ecc-common.h @@ -89,13 +89,10 @@ elliptic_curve_t _gcry_ecc_curve_copy (elliptic_curve_t E); const char *_gcry_ecc_model2str (enum gcry_mpi_ec_models model); const char *_gcry_ecc_dialect2str (enum ecc_dialects dialect); gcry_mpi_t _gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p); -gcry_err_code_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value); mpi_point_t _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec, mpi_point_t G, gcry_mpi_t d); -gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, - mpi_point_t result); /*-- ecc.c --*/ @@ -116,10 +113,8 @@ gpg_err_code_t _gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ctx, unsigned int *r_buflen); gpg_err_code_t _gcry_ecc_eddsa_ensure_compact (gcry_mpi_t value, unsigned int nbits); -gpg_err_code_t _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, - mpi_point_t result, - unsigned char **r_encpk, - unsigned int *r_encpklen); + + gpg_err_code_t _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest, gcry_mpi_t d, mpi_ec_t ec); diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 39c7c9f..bbaaac6 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -4882,6 +4882,19 @@ Valid names are the point parameters of an elliptic curve (@pxref{ecc_keyparam}). @end deftypefun + at deftypefun gpg_err_code_t gcry_mpi_ec_decode_point ( @ + @w{mpi_point_t @var{result}}, @w{gcry_mpi_t @var{value}}, @ + @w{gcry_ctx_t @var{ctx}}) + +Decode the point given as an MPI in @var{value} and store at + at var{result}. To decide which encoding is used the function takes a +context @var{ctx} which can be created with @code{gcry_mpi_ec_new}. +If @code{NULL} is given for the context the function assumes a 0x04 +prefixed uncompressed encoding. On error an error code is returned +and @var{result} might be changed. + at end deftypefun + + @deftypefun int gcry_mpi_ec_get_affine ( @ @w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{y}}, @ @w{gcry_mpi_point_t @var{point}}, @w{gcry_ctx_t @var{ctx}}) diff --git a/mpi/ec.c b/mpi/ec.c index 40e09be..346e5f1 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -589,6 +589,27 @@ _gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue, } +/* Given an encoded point in the MPI VALUE and a context EC, decode + * the point according to the context and store it in RESULT. On + * error an error code is return but RESULT might have been changed. + * If no context is given the function tries to decode VALUE by + * assuming a 0x04 prefixed uncompressed encoding. */ +gpg_err_code_t +_gcry_mpi_ec_decode_point (mpi_point_t result, gcry_mpi_t value, mpi_ec_t ec) +{ + gcry_err_code_t rc; + + if (ec && ec->dialect == ECC_DIALECT_ED25519) + rc = _gcry_ecc_eddsa_decodepoint (value, ec, result, NULL, NULL); + else if (ec && ec->model == MPI_EC_MONTGOMERY) + rc = _gcry_ecc_mont_decodepoint (value, ec, result); + else + rc = _gcry_ecc_os2ec (result, value); + + return rc; +} + + /* Compute the affine coordinates from the projective coordinates in POINT. Set them into X and Y. If one coordinate is not required, X or Y may be passed as NULL. CTX is the usual context. Returns: 0 diff --git a/src/ec-context.h b/src/ec-context.h index c8f2ad0..d74fb69 100644 --- a/src/ec-context.h +++ b/src/ec-context.h @@ -81,5 +81,17 @@ gpg_err_code_t _gcry_ecc_set_mpi (const char *name, gpg_err_code_t _gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec); +/*-- cipher/ecc-misc.c --*/ +gcry_err_code_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value); +gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, + mpi_point_t result); + +/*-- cipher/ecc-eddsa.c --*/ +gpg_err_code_t _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, + mpi_point_t result, + unsigned char **r_encpk, + unsigned int *r_encpklen); + + #endif /*GCRY_EC_CONTEXT_H*/ diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 93b1f43..f48f04f 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -694,6 +694,10 @@ gpg_error_t gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue, gpg_error_t gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue, gcry_ctx_t ctx); +/* Decode and store VALUE into RESULT. */ +gpg_error_t gcry_mpi_ec_decode_point (gcry_mpi_point_t result, + gcry_mpi_t value, gcry_ctx_t ctx); + /* Store the affine coordinates of POINT into X and Y. */ int gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point, gcry_ctx_t ctx); diff --git a/src/libgcrypt.def b/src/libgcrypt.def index f3e074b..067cb84 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -280,4 +280,6 @@ EXPORTS gcry_md_extract @245 + gcry_mpi_ec_decode_point @246 + ;; end of file with public symbols for Windows. diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index 5b3d419..785b8ed 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -106,7 +106,7 @@ GCRYPT_1.6 { gcry_mpi_ec_set_mpi; gcry_mpi_ec_set_point; gcry_mpi_ec_get_affine; gcry_mpi_ec_dup; gcry_mpi_ec_add; gcry_mpi_ec_sub; gcry_mpi_ec_mul; - gcry_mpi_ec_curve_point; + gcry_mpi_ec_curve_point; gcry_mpi_ec_decode_point; gcry_log_debug; gcry_log_debughex; gcry_log_debugmpi; gcry_log_debugpnt; gcry_log_debugsxp; diff --git a/src/mpi.h b/src/mpi.h index 0d19f46..cd539f5 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -307,6 +307,8 @@ gpg_err_code_t _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue, gpg_err_code_t _gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue, gcry_ctx_t ctx); +gpg_err_code_t _gcry_mpi_ec_decode_point (mpi_point_t result, + gcry_mpi_t value, mpi_ec_t ec); /*-- ecc-curves.c --*/ gpg_err_code_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, diff --git a/src/visibility.c b/src/visibility.c index 23a2705..3abbd37 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -544,6 +544,15 @@ gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue, return gpg_error (_gcry_mpi_ec_set_point (name, newvalue, ctx)); } +gpg_error_t +gcry_mpi_ec_decode_point (gcry_mpi_point_t result, gcry_mpi_t value, + gcry_ctx_t ctx) +{ + return gpg_error (_gcry_mpi_ec_decode_point + (result, value, + ctx? _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC) : NULL)); +} + int gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point, gcry_ctx_t ctx) diff --git a/src/visibility.h b/src/visibility.h index bb25de0..7ecd75e 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -222,6 +222,7 @@ MARK_VISIBLEX (gcry_mpi_ec_add) MARK_VISIBLEX (gcry_mpi_ec_sub) MARK_VISIBLEX (gcry_mpi_ec_curve_point) MARK_VISIBLEX (gcry_mpi_ec_dup) +MARK_VISIBLEX (gcry_mpi_ec_decode_point) MARK_VISIBLEX (gcry_mpi_ec_get_affine) MARK_VISIBLEX (gcry_mpi_ec_mul) MARK_VISIBLEX (gcry_mpi_ec_new) @@ -492,6 +493,7 @@ MARK_VISIBLEX (_gcry_mpi_get_const) #define gcry_mpi_ec_sub _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_ec_curve_point _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_ec_dup _gcry_USE_THE_UNDERSCORED_FUNCTION +#define gcry_mpi_ec_decode_point _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_ec_get_affine _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_ec_get_mpi _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_ec_get_point _gcry_USE_THE_UNDERSCORED_FUNCTION ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + cipher/ecc-common.h | 9 ++------- doc/gcrypt.texi | 13 +++++++++++++ mpi/ec.c | 21 +++++++++++++++++++++ src/ec-context.h | 12 ++++++++++++ src/gcrypt.h.in | 4 ++++ src/libgcrypt.def | 2 ++ src/libgcrypt.vers | 2 +- src/mpi.h | 2 ++ src/visibility.c | 9 +++++++++ src/visibility.h | 2 ++ 11 files changed, 69 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 28 18:21:25 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 28 Jan 2016 18:21:25 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-304-g79fe55c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 79fe55c36996627a4856e2af280c1bf98f66f170 (commit) from 2cf2ca7bb9741ac86e8aa92d8f03b1c5f5938897 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 79fe55c36996627a4856e2af280c1bf98f66f170 Author: Werner Koch Date: Thu Jan 28 18:16:22 2016 +0100 doc: Fix typos in gcry_mpi_ec_new. -- Reported-by: Hanno B?ck Signed-off-by: Werner Koch diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index bbaaac6..23b1f79 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -4805,7 +4805,7 @@ newly allocated point object. @end deftypefun @anchor{gcry_mpi_ec_new} - at deftypefun gpg_error_t gcry_mpi_ec_p_new (@w{gpg_ctx_t *@var{r_ctx}}, @ + at deftypefun gpg_error_t gcry_mpi_ec_new (@w{gcry_ctx_t *@var{r_ctx}}, @ @w{gcry_sexp_t @var{keyparam}}, @w{const char *@var{curvename}}) Allocate a new context for elliptic curve operations. If ----------------------------------------------------------------------- Summary of changes: doc/gcrypt.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 29 10:04:55 2016 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Fri, 29 Jan 2016 10:04:55 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-305-g5d41e1a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 5d41e1a1216c4b341bc737d7fe91438676a5c361 (commit) from 79fe55c36996627a4856e2af280c1bf98f66f170 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5d41e1a1216c4b341bc737d7fe91438676a5c361 Author: Jussi Kivilinna Date: Thu Jan 28 19:07:50 2016 +0200 Update NEWS -- Signed-off-by: Jussi Kivilinna diff --git a/NEWS b/NEWS index 79d1931..e4e4882 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,18 @@ Noteworthy changes in version 1.7.0 (unreleased) * Added OCB mode. + * Added support for the SHA3-224, SHA3-256, SHA3-384 and SHA3-512 + hash algorithms. + + * Added support for the SHAKE128 and SHAKE256 extendable-output + function algorithms. + + * Added support for the ChaCha20 stream cipher. + + * Added support for the Poly1305 message authentication algorithm and + ChaCha20-Poly1305 Authenticated Encryption with Associated Data + mode. + * New flag "no-keytest" for ECC key generation. Due to a bug in the parser that flag will also be accepted but ignored by older version of Libgcrypt. @@ -30,6 +42,7 @@ Noteworthy changes in version 1.7.0 (unreleased) * Interface changes relative to the 1.6.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gcry_mac_get_algo NEW. + gcry_md_extract NEW. GCRY_MAC_HMAC_MD2 NEW. GCRY_MD_FLAG_BUGEMU1 NEW. GCRYCTL_SET_SBOX NEW. ----------------------------------------------------------------------- Summary of changes: NEWS | 13 +++++++++++++ 1 file changed, 13 insertions(+) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 29 17:04:59 2016 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Fri, 29 Jan 2016 17:04:59 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-307-g57b60bb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 57b60bb1718b4f2c2500bb447ebd1d4562a5aa9b (commit) via f3e51161036382429c3491c7c881f36c0a653c7b (commit) from 5d41e1a1216c4b341bc737d7fe91438676a5c361 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 57b60bb1718b4f2c2500bb447ebd1d4562a5aa9b Author: Jussi Kivilinna Date: Fri Jan 29 17:42:41 2016 +0200 Update 'Interface changes' in NEWS -- Signed-off-by: Jussi Kivilinna diff --git a/NEWS b/NEWS index e4e4882..0064bbe 100644 --- a/NEWS +++ b/NEWS @@ -48,8 +48,25 @@ Noteworthy changes in version 1.7.0 (unreleased) GCRYCTL_SET_SBOX NEW. gcry_cipher_set_sbox NEW macro. GCRY_MD_GOSTR3411_CP NEW. + GCRY_MD_SHA3_224 NEW. + GCRY_MD_SHA3_256 NEW. + GCRY_MD_SHA3_384 NEW. + GCRY_MD_SHA3_512 NEW. + GCRY_MD_SHAKE128 NEW. + GCRY_MD_SHAKE256 NEW. + GCRY_MAC_HMAC_SHA3_224 NEW. + GCRY_MAC_HMAC_SHA3_256 NEW. + GCRY_MAC_HMAC_SHA3_384 NEW. + GCRY_MAC_HMAC_SHA3_512 NEW. + GCRY_MAC_POLY1305 NEW. + GCRY_MAC_POLY1305_AES NEW. + GCRY_MAC_POLY1305_CAMELLIA NEW. + GCRY_MAC_POLY1305_TWOFISH NEW. + GCRY_MAC_POLY1305_SERPENT NEW. + GCRY_MAC_POLY1305_SEED NEW. gcry_mpi_ec_sub NEW. gcry_mpi_ec_decode_point NEW. + GCRY_CIPHER_MODE_POLY1305 NEW. GCRY_CIPHER_MODE_OCB NEW. GCRYCTL_SET_TAGLEN NEW. gcry_cipher_final NEW macro. commit f3e51161036382429c3491c7c881f36c0a653c7b Author: Jussi Kivilinna Date: Fri Jan 29 17:42:41 2016 +0200 Improve performance of generic SHA256 implementation * cipher/sha256.c (R): Let caller do variable shuffling. (Chro, Maj, Sum0, Sum1): Convert from inline functions to macros. (W, I): New. (transform_blk): Unroll round loop; inline message expansion to rounds to make message expansion buffer smaller. -- Benchmark on Cortex-A8 (armv6, 1008 Mhz): Before: | nanosecs/byte mebibytes/sec cycles/byte SHA256 | 27.63 ns/B 34.52 MiB/s 27.85 c/B After (1.31x faster): | nanosecs/byte mebibytes/sec cycles/byte SHA256 | 20.97 ns/B 45.48 MiB/s 21.13 c/B Benchmark on Cortex-A8 (armv7, 1008 Mhz): Before: | nanosecs/byte mebibytes/sec cycles/byte SHA256 | 24.18 ns/B 39.43 MiB/s 24.38 c/B After (1.13x faster): | nanosecs/byte mebibytes/sec cycles/byte SHA256 | 21.28 ns/B 44.82 MiB/s 21.45 c/B Benchmark on Intel Core i5-4570 (i386, 3.2 Ghz): Before: | nanosecs/byte mebibytes/sec cycles/byte SHA256 | 5.78 ns/B 164.9 MiB/s 18.51 c/B After (1.06x faster) | nanosecs/byte mebibytes/sec cycles/byte SHA256 | 5.41 ns/B 176.1 MiB/s 17.33 c/B Signed-off-by: Jussi Kivilinna diff --git a/cipher/sha256.c b/cipher/sha256.c index bc326e0..1b82ee7 100644 --- a/cipher/sha256.c +++ b/cipher/sha256.c @@ -174,50 +174,34 @@ sha224_init (void *context, unsigned int flags) /* Transform the message X which consists of 16 32-bit-words. See FIPS 180-2 for details. */ -#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */ -#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */ #define R(a,b,c,d,e,f,g,h,k,w) do \ { \ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \ t2 = Sum0((a)) + Maj((a),(b),(c)); \ - h = g; \ - g = f; \ - f = e; \ - e = d + t1; \ - d = c; \ - c = b; \ - b = a; \ - a = t1 + t2; \ + d += t1; \ + h = t1 + t2; \ } while (0) /* (4.2) same as SHA-1's F1. */ -static inline u32 -Cho (u32 x, u32 y, u32 z) -{ - return (z ^ (x & (y ^ z))); -} +#define Cho(x, y, z) (z ^ (x & (y ^ z))) /* (4.3) same as SHA-1's F3 */ -static inline u32 -Maj (u32 x, u32 y, u32 z) -{ - return ((x & y) | (z & (x|y))); -} +#define Maj(x, y, z) ((x & y) + (z & (x ^ y))) /* (4.4) */ -static inline u32 -Sum0 (u32 x) -{ - return (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22)); -} +#define Sum0(x) (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22)) /* (4.5) */ -static inline u32 -Sum1 (u32 x) -{ - return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25)); -} +#define Sum1(x) (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25)) +/* Message expansion */ +#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */ +#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */ +#define I(i) ( w[i] = buf_get_be32(data + i * 4) ) +#define W(i) ( w[i&0x0f] = S1(w[(i-2) &0x0f]) \ + + w[(i-7) &0x0f] \ + + S0(w[(i-15)&0x0f]) \ + + w[(i-16)&0x0f] ) static unsigned int transform_blk (void *ctx, const unsigned char *data) @@ -243,8 +227,7 @@ transform_blk (void *ctx, const unsigned char *data) }; u32 a,b,c,d,e,f,g,h,t1,t2; - u32 w[64]; - int i; + u32 w[16]; a = hd->h0; b = hd->h1; @@ -255,60 +238,73 @@ transform_blk (void *ctx, const unsigned char *data) g = hd->h6; h = hd->h7; - for (i=0; i < 16; i++) - w[i] = buf_get_be32(data + i * 4); - for (; i < 64; i++) - w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16]; - - for (i=0; i < 64;) - { -#if 0 - R(a,b,c,d,e,f,g,h,K[i],w[i]); - i++; -#else - t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i]; - t2 = Sum0 (a) + Maj (a, b, c); - d += t1; - h = t1 + t2; - - t1 = g + Sum1 (d) + Cho (d, e, f) + K[i+1] + w[i+1]; - t2 = Sum0 (h) + Maj (h, a, b); - c += t1; - g = t1 + t2; - - t1 = f + Sum1 (c) + Cho (c, d, e) + K[i+2] + w[i+2]; - t2 = Sum0 (g) + Maj (g, h, a); - b += t1; - f = t1 + t2; - - t1 = e + Sum1 (b) + Cho (b, c, d) + K[i+3] + w[i+3]; - t2 = Sum0 (f) + Maj (f, g, h); - a += t1; - e = t1 + t2; - - t1 = d + Sum1 (a) + Cho (a, b, c) + K[i+4] + w[i+4]; - t2 = Sum0 (e) + Maj (e, f, g); - h += t1; - d = t1 + t2; - - t1 = c + Sum1 (h) + Cho (h, a, b) + K[i+5] + w[i+5]; - t2 = Sum0 (d) + Maj (d, e, f); - g += t1; - c = t1 + t2; - - t1 = b + Sum1 (g) + Cho (g, h, a) + K[i+6] + w[i+6]; - t2 = Sum0 (c) + Maj (c, d, e); - f += t1; - b = t1 + t2; - - t1 = a + Sum1 (f) + Cho (f, g, h) + K[i+7] + w[i+7]; - t2 = Sum0 (b) + Maj (b, c, d); - e += t1; - a = t1 + t2; - - i += 8; -#endif - } + R(a, b, c, d, e, f, g, h, K[0], I(0)); + R(h, a, b, c, d, e, f, g, K[1], I(1)); + R(g, h, a, b, c, d, e, f, K[2], I(2)); + R(f, g, h, a, b, c, d, e, K[3], I(3)); + R(e, f, g, h, a, b, c, d, K[4], I(4)); + R(d, e, f, g, h, a, b, c, K[5], I(5)); + R(c, d, e, f, g, h, a, b, K[6], I(6)); + R(b, c, d, e, f, g, h, a, K[7], I(7)); + R(a, b, c, d, e, f, g, h, K[8], I(8)); + R(h, a, b, c, d, e, f, g, K[9], I(9)); + R(g, h, a, b, c, d, e, f, K[10], I(10)); + R(f, g, h, a, b, c, d, e, K[11], I(11)); + R(e, f, g, h, a, b, c, d, K[12], I(12)); + R(d, e, f, g, h, a, b, c, K[13], I(13)); + R(c, d, e, f, g, h, a, b, K[14], I(14)); + R(b, c, d, e, f, g, h, a, K[15], I(15)); + + R(a, b, c, d, e, f, g, h, K[16], W(16)); + R(h, a, b, c, d, e, f, g, K[17], W(17)); + R(g, h, a, b, c, d, e, f, K[18], W(18)); + R(f, g, h, a, b, c, d, e, K[19], W(19)); + R(e, f, g, h, a, b, c, d, K[20], W(20)); + R(d, e, f, g, h, a, b, c, K[21], W(21)); + R(c, d, e, f, g, h, a, b, K[22], W(22)); + R(b, c, d, e, f, g, h, a, K[23], W(23)); + R(a, b, c, d, e, f, g, h, K[24], W(24)); + R(h, a, b, c, d, e, f, g, K[25], W(25)); + R(g, h, a, b, c, d, e, f, K[26], W(26)); + R(f, g, h, a, b, c, d, e, K[27], W(27)); + R(e, f, g, h, a, b, c, d, K[28], W(28)); + R(d, e, f, g, h, a, b, c, K[29], W(29)); + R(c, d, e, f, g, h, a, b, K[30], W(30)); + R(b, c, d, e, f, g, h, a, K[31], W(31)); + + R(a, b, c, d, e, f, g, h, K[32], W(32)); + R(h, a, b, c, d, e, f, g, K[33], W(33)); + R(g, h, a, b, c, d, e, f, K[34], W(34)); + R(f, g, h, a, b, c, d, e, K[35], W(35)); + R(e, f, g, h, a, b, c, d, K[36], W(36)); + R(d, e, f, g, h, a, b, c, K[37], W(37)); + R(c, d, e, f, g, h, a, b, K[38], W(38)); + R(b, c, d, e, f, g, h, a, K[39], W(39)); + R(a, b, c, d, e, f, g, h, K[40], W(40)); + R(h, a, b, c, d, e, f, g, K[41], W(41)); + R(g, h, a, b, c, d, e, f, K[42], W(42)); + R(f, g, h, a, b, c, d, e, K[43], W(43)); + R(e, f, g, h, a, b, c, d, K[44], W(44)); + R(d, e, f, g, h, a, b, c, K[45], W(45)); + R(c, d, e, f, g, h, a, b, K[46], W(46)); + R(b, c, d, e, f, g, h, a, K[47], W(47)); + + R(a, b, c, d, e, f, g, h, K[48], W(48)); + R(h, a, b, c, d, e, f, g, K[49], W(49)); + R(g, h, a, b, c, d, e, f, K[50], W(50)); + R(f, g, h, a, b, c, d, e, K[51], W(51)); + R(e, f, g, h, a, b, c, d, K[52], W(52)); + R(d, e, f, g, h, a, b, c, K[53], W(53)); + R(c, d, e, f, g, h, a, b, K[54], W(54)); + R(b, c, d, e, f, g, h, a, K[55], W(55)); + R(a, b, c, d, e, f, g, h, K[56], W(56)); + R(h, a, b, c, d, e, f, g, K[57], W(57)); + R(g, h, a, b, c, d, e, f, K[58], W(58)); + R(f, g, h, a, b, c, d, e, K[59], W(59)); + R(e, f, g, h, a, b, c, d, K[60], W(60)); + R(d, e, f, g, h, a, b, c, K[61], W(61)); + R(c, d, e, f, g, h, a, b, K[62], W(62)); + R(b, c, d, e, f, g, h, a, K[63], W(63)); hd->h0 += a; hd->h1 += b; @@ -319,7 +315,7 @@ transform_blk (void *ctx, const unsigned char *data) hd->h6 += g; hd->h7 += h; - return /*burn_stack*/ 74*4+32; + return /*burn_stack*/ 26*4+32; } #undef S0 #undef S1 ----------------------------------------------------------------------- Summary of changes: NEWS | 17 ++++++ cipher/sha256.c | 170 +++++++++++++++++++++++++++----------------------------- 2 files changed, 100 insertions(+), 87 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org