From cvs at cvs.gnupg.org Wed Mar 4 15:11:58 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 04 Mar 2015 15:11:58 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-21-g007d9d5 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 007d9d57da69af95138d203846ba4d2bf3aaf51e (commit) via 82146af85b65498a69b28913593dc1ffeb6b6fed (commit) from c071be698efadef1ad01fd3d329d1b486a372927 (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 007d9d57da69af95138d203846ba4d2bf3aaf51e Author: Werner Koch Date: Wed Mar 4 15:10:52 2015 +0100 doc: Fix FAQ stub and remove faq build rules. -- The FAQ is maintained in the gnupg-doc repo. diff --git a/doc/FAQ b/doc/FAQ index 32d0744..309788c 100644 --- a/doc/FAQ +++ b/doc/FAQ @@ -3,11 +3,11 @@ GnuPG Frequently Asked Questions A FAQ is a fast moving target and thus we don't distribute it anymore with GnuPG. You may retrieve the current FAQ in HTML format at - http://www.gnupg.org/faq/GnuPG-FAQ.html + https://gnupg.org/faq/gnupg-faq.html -or in plain text format at the FTP server: +or in plain text format at - ftp://ftp.gnupg.org/gcrypt/gnupg/GnuPG-FAQ.txt + https://gnupg.org/faq/gnupg-faq.txt diff --git a/doc/Makefile.am b/doc/Makefile.am index a308444..240bcf3 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -75,7 +75,7 @@ man_MANS = $(myman_pages) gnupg.7 watchgnupg_SOURCE = gnupg.texi -CLEANFILES = yat2m faq.txt faq.html +CLEANFILES = yat2m DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \ $(myman_pages) gnupg.7 @@ -139,24 +139,3 @@ online: gnupg.html gnupg.pdf cd gnupg.html ; \ rsync -vr --exclude='.git' . \ $${user}@$${webhost}:webspace/manuals/gnupg$${dashdevel}/ - -# Note that you need a recent version of emacs23 with org-mode 7.01h -faq.txt faq.html: faq.org - @set -e; expopt="t nil nil nil \"$$(pwd)\""; \ - emacs --batch \ - --eval "(require 'org)" \ - --visit "$(srcdir)/faq.org" \ - --eval "(setq org-export-ascii-entities 'utf8)" \ - --eval "(org-export-as-ascii org-export-headline-levels $${expopt})"\ - --visit "$(srcdir)/faq.org" \ - --eval "(setq org-export-html-style-include-default nil)" \ - --eval "(setq org-export-html-style-include-scripts nil)" \ - --eval "(org-export-as-html org-export-headline-levels $${expopt})" - -faq-online: faq.txt faq.html - set -e; \ - user=werner ; webhost="ftp.gnupg.org" ; ftphost="ftp.gnupg.org" ; \ - echo "Uploading current FAQ to {www,ftp}.gnupg.org ..."; \ - scp faq.html $${user}@$${webhost}:webspace/manuals/GnuPG-FAQ.html ; \ - scp faq.txt $${user}@$${ftphost}:gcrypt/gnupg/GnuPG-FAQ.txt ; \ - echo "...ready" commit 82146af85b65498a69b28913593dc1ffeb6b6fed Author: Daniel Kahn Gillmor Date: Sat Feb 21 11:04:13 2015 -0500 gpg: avoid chatter about trustdb when --quiet * g10/trustdb.c (tdb_check_trustdb_stale): avoid log_info() when opt.quiet -- gpg(1) says: -q, --quiet Try to be as quiet as possible. While the mentions about the stale trustdb information are edifying, they aren't necessary, and shouldn't be emitted when the user requests --quiet. Signed-off-by: Daniel Kahn Gillmor diff --git a/g10/trustdb.c b/g10/trustdb.c index f0b5501..6145cf0 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -938,11 +938,13 @@ tdb_check_trustdb_stale (void) if (opt.no_auto_check_trustdb) { pending_check_trustdb = 1; - log_info (_("please do a --check-trustdb\n")); + if (!opt.quiet) + log_info (_("please do a --check-trustdb\n")); } else { - log_info (_("checking the trustdb\n")); + if (!opt.quiet) + log_info (_("checking the trustdb\n")); validate_keys (0); } } ----------------------------------------------------------------------- Summary of changes: doc/FAQ | 6 +++--- doc/Makefile.am | 23 +---------------------- g10/trustdb.c | 6 ++++-- 3 files changed, 8 insertions(+), 27 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 4 15:20:09 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 04 Mar 2015 15:20:09 +0100 Subject: [git] gnupg-doc - branch, master, updated. b8773eae1a20010d4635503e1439d21d4cfc3637 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 b8773eae1a20010d4635503e1439d21d4cfc3637 (commit) via fd8fa8fbaec8951d2202a98a9a7ba11d086ff59c (commit) from 4acb6162899cf58c97b2a34e0dadf13590d0ffe7 (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 b8773eae1a20010d4635503e1439d21d4cfc3637 Author: Werner Koch Date: Wed Mar 4 15:18:54 2015 +0100 web: Update gnupg FAQ links and added a simple Makefile. -- The Makefile is used to build and upload the text version. We should really have one Makefile for all tasks in this repo. diff --git a/web/documentation/faqs.org b/web/documentation/faqs.org index 3209562..fd7aa15 100644 --- a/web/documentation/faqs.org +++ b/web/documentation/faqs.org @@ -10,6 +10,6 @@ - [[https://www.gnupg.org/faq/gnupg-faq.txt][Plain text]] The FAQ is generated using this [[http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg-doc.git;a=blob_plain;f=web/faq/gnupg-faq.org][source code]]. If you are looking for - the old and outdated FAQ, please go to [[http://www-old.gnupg.org/faq/GnuPG-FAQ.html][here]]. + the old and outdated FAQ, please go to [[ftp://ftp.gnupg.org/gcrypt/gnupg/GnuPG-FAQ.old.txt][here]]. # eof diff --git a/web/faq/Makefile b/web/faq/Makefile new file mode 100644 index 0000000..2926b29 --- /dev/null +++ b/web/faq/Makefile @@ -0,0 +1,25 @@ + +srcdir = . + +# Note that you need a recent version of emacs23 with org-mode 7.01h +# +# Note that due to a problem with hyperref we are currently not able +# to build a pdf version +# +# --visit "$(srcdir)/gnupg-faq.org" \ +# --eval "(org-latex-export-to-pdf)"\ +# + +gnupg-faq.txt gnupg-faq.html: gnupg-faq.org + @set -e; \ + emacs --batch \ + --eval "(require 'org)" \ + --visit "$(srcdir)/gnupg-faq.org" \ + --eval "(org-ascii-export-to-ascii)" + +faq-online: gnupg-faq.txt gnupg-faq.html + set -e; \ + user=werner ; \ + echo "Uploading current FAQ to ftp.gnupg.org ..."; \ + scp gnupg-faq.txt $${user}@ftp.gnupg.org:gcrypt/gnupg/GnuPG-FAQ.txt; \ + echo "...ready" diff --git a/web/index.org b/web/index.org index 44f1081..f1f3ad9 100644 --- a/web/index.org +++ b/web/index.org @@ -118,6 +118,16 @@ all [[file:news.org][news of previous years]] is also available. # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** GnuPG 1.4.19 released (2015-02-27) :important: + +GnuPG 1.4.19 is now available. This release mitigates two new of side +channel attack methods as well as a couple of other bugs. [[http://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000363.html][{more}]] + +** Libgcrypt 1.6.3 released (2015-02-27) :important: + +Libgcrypt version 1.6.3 has been released to mitigate two new side +channel attack methods. [[http://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000364.html][{more}]] + ** GnuPG 2.0.27 released (2015-02-18) GnuPG 2.0.27 is now available. This release fixes a couple of bugs; commit fd8fa8fbaec8951d2202a98a9a7ba11d086ff59c Author: Werner Koch Date: Fri Feb 27 12:35:14 2015 +0100 web: Release info for gnupg 1.4.19 and Libgcrypt 1.6.3. diff --git a/web/download/integrity_check.org b/web/download/integrity_check.org index 6bbdfb9..3825fbb 100644 --- a/web/download/integrity_check.org +++ b/web/download/integrity_check.org @@ -63,7 +63,6 @@ {{{gnupg21_w32_sha1}}} gnupg-w32-{{{gnupg21_w32_ver}}}.exe {{{gnupg1_sha1}}} gnupg-{{{gnupg1_ver}}}.tar.bz2 {{{gnupg1_sha1_gz}}} gnupg-{{{gnupg1_ver}}}.tar.gz - {{{gnupg1_patch_sha1}}} gnupg-{{{gnupg1_patch_ver}}}.diff.bz2 {{{gnupg1_w32cli_sha1}}} gnupg-w32cli-{{{gnupg1_w32cli_ver}}}.exe {{{libgpg_error_sha1}}} libgpg-error-{{{libgpg_error_ver}}}.tar.bz2 {{{libgcrypt_sha1}}} libgcrypt-{{{libgcrypt_ver}}}.tar.bz2 diff --git a/web/swdb.mac b/web/swdb.mac index 93da7ff..c295ccb 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -30,20 +30,16 @@ # # GnuPG-1 # -#+macro: gnupg1_ver 1.4.18 +#+macro: gnupg1_ver 1.4.19 #+macro: gnupg1_branch STABLE-BRANCH-1-4 -#+macro: gnupg1_size 3564k -#+macro: gnupg1_size_gz 4930k -#+macro: gnupg1_sha1 41462d1a97f91abc16a0031b5deadc3095ce88ae -#+macro: gnupg1_sha1_gz ea7d66c3de7aaf46de9e8678f4fc4a8c329400b2 +#+macro: gnupg1_size 3627k +#+macro: gnupg1_size_gz 5020k +#+macro: gnupg1_sha1 5503f7faa0a0e84450838706a67621546241ca50 +#+macro: gnupg1_sha1_gz d0cf40cc42ce057d7d747908ec21a973a423a508 # -#+macro: gnupg1_patch_ver 1.4.17-1.4.18 -#+macro: gnupg1_patch_size 5k -#+macro: gnupg1_patch_sha1 f30571f855b3ff8becff5378a884638da4c3cc9e -# -#+macro: gnupg1_w32cli_ver 1.4.18 -#+macro: gnupg1_w32cli_size 1575k -#+macro: gnupg1_w32cli_sha1 579de2464528b436f39c5835e766867a1efa5fee +#+macro: gnupg1_w32cli_ver 1.4.19 +#+macro: gnupg1_w32cli_size 1586k +#+macro: gnupg1_w32cli_sha1 dc03ae4e4c3e8fe0583b37dd6c3124f94246d2f8 # @@ -74,9 +70,9 @@ # # LIBGCRYPT # -#+macro: libgcrypt_ver 1.6.2 -#+macro: libgcrypt_size 2418k -#+macro: libgcrypt_sha1 cc31aca87e4a3769cb86884a3f5982b2cc8eb7ec +#+macro: libgcrypt_ver 1.6.3 +#+macro: libgcrypt_size 2436k +#+macro: libgcrypt_sha1 9456e7b64db9df8360a1407a38c8c958da80bbf1 # ----------------------------------------------------------------------- Summary of changes: web/documentation/faqs.org | 2 +- web/download/integrity_check.org | 1 - web/faq/Makefile | 25 +++++++++++++++++++++++++ web/index.org | 10 ++++++++++ web/swdb.mac | 26 +++++++++++--------------- 5 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 web/faq/Makefile hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 4 16:16:52 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 04 Mar 2015 16:16:52 +0100 Subject: [git] gnupg-doc - branch, master, updated. 1d0089b9bf30e24aabd0b2b63e3f9234e61ef3bd 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 1d0089b9bf30e24aabd0b2b63e3f9234e61ef3bd (commit) from b8773eae1a20010d4635503e1439d21d4cfc3637 (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 1d0089b9bf30e24aabd0b2b63e3f9234e61ef3bd Author: Werner Koch Date: Wed Mar 4 16:15:54 2015 +0100 Cleaned up web symlinks and repalced them by redirects. diff --git a/README b/README index 0d6069c..3f45fa6 100644 --- a/README +++ b/README @@ -30,43 +30,57 @@ use: Alias /documentation/manuals /var/www/shared/manuals Alias /gph /var/www/shared/gph -# The FAQ is located in the manuals directory but linked to the faq directory -Alias /faq/GnuPG-FAQ.html /var/www/shared/manuals/GnuPG-FAQ.html - - -# Redirect a couple of well-known URLs -Redirect /gpa.html http://www.gnupg.org/related_software/gpa/ -Redirect /gpgme.html http://www.gnupg.org/related_software/gpgme/ -Redirect /docs.html http://www.gnupg.org/documentation/ -Redirect /download.html http://www.gnupg.org/download/ -Redirect /faq.html http://www.gnupg.org/documentation/faqs.html +# The blog is maintained outside of the standard tree, so that it can be build using +# a separate script. +Alias /blog /var/www/www/www.gnupg.org/misc/blog +# Redirect a couple of well-known old URLs # We use redirect to make language switching work. -Redirect /why-not-idea.html http://www.gnupg.org/faq/why-not-idea.html +Redirect /gpa.html http://www.gnupg.org/related_software/gpa/ +Redirect /gpgme.html http://www.gnupg.org/related_software/gpgme/ +Redirect /docs.html http://www.gnupg.org/documentation/ +Redirect /download.html http://www.gnupg.org/download/ +Redirect /faq.html http://www.gnupg.org/documentation/faqs.html +Redirect /faqs.html http://www.gnupg.org/documentation/faqs.html +Redirect /gpgme-faq.html http://www.gnupg.org/faq/gpgme-faq.html +Redirect /gnupg-faq.html http://www.gnupg.org/documentation/faqs.html +Redirect /GnuPG-FAQ.html http://www.gnupg.org/documentation/faqs.html +Redirect /supported_systems.html http://www.gnupg.org/download/supported_systems.html +Redirect /release_notes.html http://www.gnupg.org/download/release_notes.html +Redirect /integrity_check.html http://www.gnupg.org/download/integrity_check.html +Redirect /cvs_access.html http://www.gnupg.org/download/cvs_access.html +Redirect /iconv.html http://www.gnupg.org/download/iconv.html +Redirect /manpage.html http://www.gnupg.org/documentation/manpage.html +Redirect /sites.html http://www.gnupg.org/documentation/sites.html +Redirect /guides.html http://www.gnupg.org/documentation/guides.html +Redirect /manuals.html http://www.gnupg.org/documentation/manuals.html +Redirect /mailing-lists.html http://www.gnupg.org/documentation/mailing-lists.html +Redirect /howtos.html http://www.gnupg.org/documentation/howtos.html +Redirect /bts.html http://www.gnupg.org/documentation/bts.html +Redirect /weak-digest-algos.html http://www.gnupg.org/faq/weak-digest-algos.html +Redirect /subkey-cross-certify.html http://www.gnupg.org/faq/subkey-cross-certify.html +Redirect /why-not-idea.html http://www.gnupg.org/faq/why-not-idea.html Redirect /howtos/ch/ http://www.gnupg.org/howtos/zh/ +# Temporary: Redirect /fund http://goteo.org/project/gnupg-new-website-and-infrastructure #+END_EXAMPLE -The howtos are symlinked into the www.gnupg.org tree. +The howtos are symlinked into the www.gnupg.org tree; see below. ** Symlinks -For compatibility with the old website it is best to run this script -in the htdocs directory: - -for d in $(find . -type d); \\ - do (cd $d && for f in $(ls *.html | grep -v '*.??.html'); \\ - do ln -s $f ${f%.html}.en.html; ln -s $f ${f%.html}.de.html ; \\ - done ); done +#+begin_example +howtos -> ../../howtos.gnupg.org/htdocs +#+end_example ** Cronjobs A cronjob needs to run mkkudos.sh to update the list of donors. - This can be done every few minutes becuase mkkudos won't do anything + This can be done every few minutes because mkkudos won't do anything if the list of donors has not been updated. ** Writing a blog entry ----------------------------------------------------------------------- Summary of changes: README | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 6 10:39:01 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 06 Mar 2015 10:39:01 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.18-5-g4441e96 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 4441e96801fdc4c900abae8c0aa0b53e2e26e079 (commit) via 0f814d4c4a285573eef2391c70e21cf8126cafcb (commit) from b400d7c65daaf44f227073ddde7d06986afde786 (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 4441e96801fdc4c900abae8c0aa0b53e2e26e079 Author: Werner Koch Date: Fri Mar 6 09:53:49 2015 +0100 Add host-triplet aliasing feature to mkheader. * src/Makefile.am (lock_obj_pub): Rename i586-pc-linux-gnu to i686-pc-linux-gnu. Remove i486-pc-linux-gnu. * src/mkheader.c (canon_host_triplet): New. (main): Use it. -- config.sub does not map i{4,5,6}86-pc-linux-gnu to one common triplet. However, they all use the same ABI and thus we do not need several versions of the syscfg files. Signed-off-by: Werner Koch diff --git a/README b/README index d0a1d47..be7b7dc 100644 --- a/README +++ b/README @@ -116,7 +116,9 @@ need to figure out these values. You may use these commands: If you are using a VPATH build adjust accordingly. If this all works for you (make sure to run the test programs on the target platform), please send the generated file to the gnupg-devel mailing list so that -we can include it in the next release. +we can include it in the next release. Note that in addition to the +aliasing done by config.sub the src/mkheader build tool does some +extra aliasing to avoid having too much identical syscfg files. diff --git a/src/Makefile.am b/src/Makefile.am index 18a4cb7..99c2c53 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,8 +51,7 @@ lock_obj_pub = \ syscfg/lock-obj-pub.hppa-unknown-linux-gnu.h \ syscfg/lock-obj-pub.i486-pc-gnu.h \ syscfg/lock-obj-pub.i486-pc-kfreebsd-gnu.h \ - syscfg/lock-obj-pub.i486-pc-linux-gnu.h \ - syscfg/lock-obj-pub.i586-pc-linux-gnu.h \ + syscfg/lock-obj-pub.i686-pc-linux-gnu.h \ syscfg/lock-obj-pub.m68k-unknown-linux-gnu.h \ syscfg/lock-obj-pub.mips-unknown-linux-gnu.h \ syscfg/lock-obj-pub.mips64el-unknown-linux-gnuabi64.h \ diff --git a/src/mkheader.c b/src/mkheader.c index 9fe0695..3481771 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -23,7 +23,7 @@ #define LINESIZE 1024 static const char *host_os; -static const char *host_triplet; +static char *host_triplet; static char *srcdir; static const char *hdr_version; static const char *hdr_version_number; @@ -63,6 +63,40 @@ xstrdup (const char *string) } +/* Return a malloced string with TRIPLET. If TRIPLET has an alias + return that instead. In general build-aux/config.sub should do the + aliasing but some returned triplets are anyway identical and thus we + use this function to map it to the canonical form. */ +static char * +canon_host_triplet (const char *triplet) +{ + struct { + const char *name; + const char *alias; + } tbl[] = { + {"i486-pc-linux-gnu", "i686-pc-linux-gnu" }, + {"i586-pc-linux-gnu" }, + + { NULL } + }; + int i; + const char *lastalias = NULL; + + for (i=0; tbl[i].name; i++) + { + if (tbl[i].alias) + lastalias = tbl[i].alias; + if (!strcmp (tbl[i].name, triplet)) + { + if (!lastalias) + break; /* Ooops: first entry has no alias. */ + return xstrdup (lastalias); + } + } + return xstrdup (triplet); +} + + /* Parse the supplied config.h file and extract required info. Returns 0 on success. */ static int @@ -481,6 +515,7 @@ main (int argc, char **argv) const char *fname, *s; char *p1, *p2; const char *config_h; + const char *host_triplet_raw; if (argc) { @@ -496,12 +531,14 @@ main (int argc, char **argv) return 1; } host_os = argv[0]; - host_triplet = argv[1]; + host_triplet_raw = argv[1]; fname = argv[2]; config_h = argv[3]; hdr_version = argv[4]; hdr_version_number = argv[5]; + host_triplet = canon_host_triplet (host_triplet_raw); + srcdir = malloc (strlen (fname) + 2 + 1); if (!srcdir) { @@ -554,8 +591,12 @@ main (int argc, char **argv) if (!strcmp (p1, "configure_input")) { s = strrchr (fname, '/'); - printf ("Do not edit. Generated from %s for %s.", - s? s+1 : fname, host_triplet); + printf ("Do not edit. Generated from %s for:\n%*s", + s? s+1 : fname, (int)(p1 - line) + 13, ""); + if (!strcmp (host_triplet, host_triplet_raw)) + printf ("%s", host_triplet); + else + printf ("%s (%s)", host_triplet, host_triplet_raw); fputs (p2, stdout); } else if (!write_special (fname, lnr, p1)) @@ -593,5 +634,6 @@ main (int argc, char **argv) fclose (fp); + xfree (host_triplet); return 0; } diff --git a/src/syscfg/lock-obj-pub.i586-pc-linux-gnu.h b/src/syscfg/lock-obj-pub.i686-pc-linux-gnu.h similarity index 92% rename from src/syscfg/lock-obj-pub.i586-pc-linux-gnu.h rename to src/syscfg/lock-obj-pub.i686-pc-linux-gnu.h index fc2d132..b97273b 100644 --- a/src/syscfg/lock-obj-pub.i586-pc-linux-gnu.h +++ b/src/syscfg/lock-obj-pub.i686-pc-linux-gnu.h @@ -1,4 +1,4 @@ -## lock-obj-pub.i586-pc-linux-gnu.h +## lock-obj-pub.i686-pc-linux-gnu.h ## File created by gen-posix-lock-obj - DO NOT EDIT ## To be included by mkheader into gpg-error.h commit 0f814d4c4a285573eef2391c70e21cf8126cafcb Author: Werner Koch Date: Tue Feb 3 19:17:36 2015 +0100 w32: Add a manifest to libgpg-error. * src/gpg-error.w32-manifest.in: New. * src/Makefile.am (EXTRA_DIST): Add it. (versioninfo.lo): Depend on it. * src/versioninfo.rc.in: Add it. * configure.ac (AC_CONFIG_FILES): Add it. (BUILD_VERSION): New. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 0f9b194..dc3fb05 100644 --- a/configure.ac +++ b/configure.ac @@ -486,12 +486,13 @@ AC_DEFINE_UNQUOTED(BUILD_REVISION, "$BUILD_REVISION", [GIT commit id revision used to build this package]) changequote(,)dnl -BUILD_FILEVERSION=`echo "$PACKAGE_VERSION"|sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` +BUILD_VERSION=`echo "$PACKAGE_VERSION"|sed 's/\([0-9.]*\).*/\1./'` changequote([,])dnl -BUILD_FILEVERSION="${BUILD_FILEVERSION}0,mym4_revision_dec" +BUILD_VERSION="${BUILD_VERSION}0.mym4_revision_dec" +BUILD_FILEVERSION=`echo "${BUILD_VERSION}" | tr . ,` +AC_SUBST(BUILD_VERSION) AC_SUBST(BUILD_FILEVERSION) - AC_ARG_ENABLE([build-timestamp], AC_HELP_STRING([--enable-build-timestamp], [set an explicit build timestamp for reproducibility. @@ -526,7 +527,7 @@ AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([doc/Makefile po/Makefile.in m4/Makefile]) AC_CONFIG_FILES([src/Makefile tests/Makefile]) AC_CONFIG_FILES([lang/Makefile lang/cl/Makefile lang/cl/gpg-error.asd]) -AC_CONFIG_FILES([src/versioninfo.rc]) +AC_CONFIG_FILES([src/versioninfo.rc src/gpg-error.w32-manifest]) AC_CONFIG_FILES([src/gpg-error-config], [chmod +x src/gpg-error-config]) AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index 403f5d2..18a4cb7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -82,7 +82,8 @@ EXTRA_DIST = mkstrtable.awk err-sources.h.in err-codes.h.in \ mkerrcodes.awk mkerrcodes1.awk mkerrcodes2.awk mkerrcodes.c \ mkheader.c gpg-error.h.in mkw32errmap.c w32-add.h w32ce-add.h \ err-sources.h err-codes.h gpg-error-config.in gpg-error.m4 \ - gpg-error.vers gpg-error.def.in versioninfo.rc.in \ + gpg-error.vers gpg-error.def.in \ + versioninfo.rc.in gpg-error.w32-manifest.in \ $(lock_obj_pub) BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \ @@ -120,6 +121,7 @@ export_symbols = -export-symbols gpg-error.def # no need to use this DLL. Thus we force gcc to link that statically. extra_ltoptions = -XCClinker -static-libgcc +versioninfo.lo : gpg-error.w32-manifest install-def-file: gpg-error.def -$(INSTALL) -d $(DESTDIR)$(libdir) diff --git a/src/gpg-error.w32-manifest.in b/src/gpg-error.w32-manifest.in new file mode 100644 index 0000000..07f6891 --- /dev/null +++ b/src/gpg-error.w32-manifest.in @@ -0,0 +1,17 @@ + + +Error codes and shared functions for GnuPG and others + + + + + + + + + + diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index bcf5893..8a053a9 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -50,3 +50,4 @@ BEGIN END END +1 RT_MANIFEST "gpg-error.w32-manifest" ----------------------------------------------------------------------- Summary of changes: README | 4 +- configure.ac | 9 ++-- src/Makefile.am | 7 +-- src/gpg-error.w32-manifest.in | 17 ++++++++ src/mkheader.c | 50 ++++++++++++++++++++-- ...inux-gnu.h => lock-obj-pub.i686-pc-linux-gnu.h} | 2 +- src/versioninfo.rc.in | 1 + 7 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 src/gpg-error.w32-manifest.in rename src/syscfg/{lock-obj-pub.i586-pc-linux-gnu.h => lock-obj-pub.i686-pc-linux-gnu.h} (92%) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 6 10:47:58 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 06 Mar 2015 10:47:58 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-22-g87a218c 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 87a218c3bf94e2084e189e1833b289ec7f96167e (commit) from 007d9d57da69af95138d203846ba4d2bf3aaf51e (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 87a218c3bf94e2084e189e1833b289ec7f96167e Author: Werner Koch Date: Fri Mar 6 10:46:40 2015 +0100 doc: Some typo fixes. -- diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index d3d1f2a..a0e5566 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -41,7 +41,7 @@ static struct { const char *name; /* Standard name. */ const char *oidstr; /* IETF formatted OID. */ - unsigned int nbits; /* Nominla bit length of the curve. */ + unsigned int nbits; /* Nominal bit length of the curve. */ const char *alias; /* NULL or alternative name of the curve. */ } oidtable[] = { diff --git a/doc/DETAILS b/doc/DETAILS index 4286f45..dcc877a 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -192,7 +192,7 @@ described here. *** Field 15 - S/N of a token - Used in sec/sbb to print the serial number of a token (internal + Used in sec/ssb to print the serial number of a token (internal protect mode 1002) or a '#' if that key is a simple stub (internal protect mode 1001). If the option --with-secret is used and a secret key is available for the public key, a '+' indicates this. @@ -204,7 +204,7 @@ described here. *** Field 17 - Curve name - For pub, sub, sec, and sbb records this field is used for the ECC + For pub, sub, sec, and ssb records this field is used for the ECC curve name. ** Special fields ----------------------------------------------------------------------- Summary of changes: common/openpgp-oid.c | 2 +- doc/DETAILS | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 9 03:07:07 2015 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 09 Mar 2015 03:07:07 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-23-gbb5a1b7 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 bb5a1b7c738d74d5b46340ec7b50000a2d343ca9 (commit) from 87a218c3bf94e2084e189e1833b289ec7f96167e (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 bb5a1b7c738d74d5b46340ec7b50000a2d343ca9 Author: NIIBE Yutaka Date: Mon Mar 9 11:00:03 2015 +0900 scd: fix for 64-bit arch. * agent/pksign.c (agent_pksign_do): Use int. * scd/app-openpgp.c (get_public_key): Likewise. -- On 64-bit architecture, int and size_t might be different. For the first argument for '%b', int is expected. diff --git a/agent/pksign.c b/agent/pksign.c index d737bad..1d3d3d8 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -363,12 +363,13 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, *buf = 0; } - rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))", len, buf); + rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))", + (int)len, buf); } else if (is_EdDSA) { rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(eddsa(r%b)(s%b)))", - len/2, buf, len/2, buf + len/2); + (int)len/2, buf, (int)len/2, buf + len/2); } else if (is_ECDSA) { diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 6583fb2..10bd64e 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1496,7 +1496,7 @@ get_public_key (app_t app, int keyno) if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA) { err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))", - mlen, mbuf, elen, ebuf); + (int)mlen, mbuf, (int)elen, ebuf); if (err) goto leave; @@ -1518,7 +1518,7 @@ get_public_key (app_t app, int keyno) err = gcry_sexp_build (&s_pkey, NULL, "(public-key(ecc(curve%s)(q%b)))", - curve_name, mlen, mbuf); + curve_name, (int)mlen, mbuf); if (err) goto leave; @@ -1541,7 +1541,7 @@ get_public_key (app_t app, int keyno) err = gcry_sexp_build (&s_pkey, NULL, "(public-key(ecc(curve%s)(flags eddsa)(q%b)))", - curve_name, mlen, mbuf); + curve_name, (int)mlen, mbuf); if (err) goto leave; ----------------------------------------------------------------------- Summary of changes: agent/pksign.c | 5 +++-- scd/app-openpgp.c | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 10 15:43:41 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 10 Mar 2015 15:43:41 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-25-g7b5b52f 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 7b5b52f3268b093eebbac3f199fb69bf246d9cd1 (commit) via 14af2be022ccaf826db048fc16959d0222ff1134 (commit) from bb5a1b7c738d74d5b46340ec7b50000a2d343ca9 (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 7b5b52f3268b093eebbac3f199fb69bf246d9cd1 Author: Werner Koch Date: Tue Mar 10 13:44:40 2015 +0100 gpg: Change --print-pka-records into an option. * g10/gpg.c (aPrintPKARecords): Rename to oPrintPKARecords and do not use it as a command. * g10/keylist.c (list_keyblock): List PKA rceords also for secret keys. -- An option allows to use it more flexible. For example to select only secret keys. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index a326233..11d8919 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2114,6 +2114,13 @@ as it is easily machine parsed. The details of this format are documented in the file @file{doc/DETAILS}, which is included in the GnuPG source distribution. + + at item --print-pka-records + at opindex print-pka-records +Modify the output of the list commands to print PKA records suitable +to put into DNS zone files. An ORIGIN line is printed before each +record to allow diverting the records to the corresponding zone file. + @item --fixed-list-mode @opindex fixed-list-mode Do not merge primary user ID and primary key in @option{--with-colon} diff --git a/g10/gpg.c b/g10/gpg.c index deb3966..eb75409 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -132,7 +132,6 @@ enum cmd_and_opt_values aSendKeys, aRecvKeys, aLocateKeys, - aPrintPKARecords, aSearchKeys, aRefreshKeys, aFetchKeys, @@ -383,6 +382,7 @@ enum cmd_and_opt_values oAllowWeakDigestAlgos, oFakedSystemTime, oNoAutostart, + oPrintPKARecords, oNoop }; @@ -409,7 +409,6 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aCheckKeys, "check-sigs",N_("list and check key signatures")), ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")), ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")), - ARGPARSE_c (aPrintPKARecords, "print-pka-records", "@"), ARGPARSE_c (aKeygen, "gen-key", N_("generate a new key pair")), ARGPARSE_c (aQuickKeygen, "quick-gen-key" , @@ -712,6 +711,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oFixedListMode, "fixed-list-mode", "@"), ARGPARSE_s_n (oLegacyListMode, "legacy-list-mode", "@"), ARGPARSE_s_n (oListOnly, "list-only", "@"), + ARGPARSE_s_n (oPrintPKARecords, "print-pka-records", "@"), ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"), ARGPARSE_s_n (oIgnoreValidFrom, "ignore-valid-from", "@"), ARGPARSE_s_n (oIgnoreCrcError, "ignore-crc-error", "@"), @@ -2329,11 +2329,6 @@ main (int argc, char **argv) set_cmd (&cmd, pargs.r_opt); break; - case aPrintPKARecords: - set_cmd (&cmd, pargs.r_opt); - opt.print_pka_records = 1; - break; - case aKeygen: case aFullKeygen: case aEditKey: @@ -2974,6 +2969,7 @@ main (int argc, char **argv) case oFastListMode: opt.fast_list_mode = 1; break; case oFixedListMode: /* Dummy */ break; case oLegacyListMode: opt.legacy_list_mode = 1; break; + case oPrintPKARecords: opt.print_pka_records = 1; break; case oListOnly: opt.list_only=1; break; case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; @@ -3879,13 +3875,6 @@ main (int argc, char **argv) public_key_list (ctrl, sl, 1); free_strlist (sl); break; - case aPrintPKARecords: - sl = NULL; - for (; argc; argc--, argv++) - add_to_strlist2( &sl, *argv, utf8_strings ); - public_key_list (ctrl, sl, 0); - free_strlist (sl); - break; case aQuickKeygen: if (argc != 1 ) diff --git a/g10/keylist.c b/g10/keylist.c index 7f13d8b..03b9bbb 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1647,10 +1647,7 @@ list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr, { reorder_keyblock (keyblock); if (opt.print_pka_records) - { - if (!secret) - list_keyblock_pka (keyblock); - } + list_keyblock_pka (keyblock); else if (opt.with_colons) list_keyblock_colon (keyblock, secret, has_secret, fpr); else commit 14af2be022ccaf826db048fc16959d0222ff1134 Author: Werner Koch Date: Tue Mar 10 15:26:02 2015 +0100 gpg: Add --list-gcrypt-config and "curve" item for --list-config. * common/openpgp-oid.c (curve_supported_p): New. (openpgp_enum_curves): New. * common/t-openpgp-oid.c (test_openpgp_enum_curves): New. (main): Add option --verbose. * g10/gpg.c (opts): Add --list-gcrypt-config. (list_config): Add items "curve" and "curveoid". Remove unused code. -- GnuPG-bug-id: 1917 Signed-off-by: Werner Koch diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index a0e5566..ccb67bb 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -347,3 +347,41 @@ openpgp_oid_to_curve (const char *oidstr) return "?"; } + + +/* Return true if the curve with NAME is supported. */ +static int +curve_supported_p (const char *name) +{ + int result = 0; + gcry_sexp_t keyparms; + + if (!gcry_sexp_build (&keyparms, NULL, "(public-key(ecc(curve %s)))", name)) + { + result = !!gcry_pk_get_curve (keyparms, 0, NULL); + gcry_sexp_release (keyparms); + } + return result; +} + + +/* Enumerate available and supported OpenPGP curves. The caller needs + to set the integer variable at ITERP to zero and keep on calling + this fucntion until NULL is returned. */ +const char * +openpgp_enum_curves (int *iterp) +{ + int idx = *iterp; + + while (idx >= 0 && idx < DIM (oidtable) && oidtable[idx].name) + { + if (curve_supported_p (oidtable[idx].name)) + { + *iterp = idx + 1; + return oidtable[idx].alias? oidtable[idx].alias : oidtable[idx].name; + } + idx++; + } + *iterp = idx; + return NULL; +} diff --git a/common/t-openpgp-oid.c b/common/t-openpgp-oid.c index 5cd778d..afb6ebe 100644 --- a/common/t-openpgp-oid.c +++ b/common/t-openpgp-oid.c @@ -35,6 +35,10 @@ #define BADOID "1.3.6.1.4.1.11591.2.12242973" +static int verbose; + + + static void test_openpgp_oid_from_str (void) { @@ -184,15 +188,51 @@ test_openpgp_oid_is_ed25519 (void) } +static void +test_openpgp_enum_curves (void) +{ + int iter = 0; + const char *name; + int p256 = 0; + int p384 = 0; + int p521 = 0; + + while ((name = openpgp_enum_curves (&iter))) + { + if (verbose) + printf ("curve: %s\n", name); + if (!strcmp (name, "nistp256")) + p256++; + else if (!strcmp (name, "nistp384")) + p384++; + else if (!strcmp (name, "nistp521")) + p521++; + } + + if (p256 != 1 || p384 != 1 || p521 != 1) + { + /* We can only check the basic RFC-6637 requirements. */ + fputs ("standard ECC curve missing\n", stderr); + exit (1); + } +} + + int main (int argc, char **argv) { - (void)argc; - (void)argv; + if (argc) + { argc--; argv++; } + if (argc && !strcmp (argv[0], "--verbose")) + { + verbose = 1; + argc--; argv++; + } test_openpgp_oid_from_str (); test_openpgp_oid_to_str (); test_openpgp_oid_is_ed25519 (); + test_openpgp_enum_curves (); return 0; } diff --git a/common/util.h b/common/util.h index 9103e09..0a54718 100644 --- a/common/util.h +++ b/common/util.h @@ -224,6 +224,7 @@ char *openpgp_oid_to_str (gcry_mpi_t a); int openpgp_oid_is_ed25519 (gcry_mpi_t a); const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits); const char *openpgp_oid_to_curve (const char *oid); +const char *openpgp_enum_curves (int *idxp); diff --git a/doc/DETAILS b/doc/DETAILS index dcc877a..4b82497 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -287,19 +287,22 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: semicolons. The algorithm numbers are as specified in RFC-4880. Note that in contrast to the --status-fd interface these are _not_ the Libgcrypt identifiers. + Using =pubkeyname= prints names instead of numbers. : cfg:pubkey:1;2;3;16;17 - cipher :: The third field contains the symmetric ciphers this version of GnuPG supports, separated by semicolons. The cipher numbers are as specified in RFC-4880. + Using =ciphername= prints names instead of numbers. : cfg:cipher:2;3;4;7;8;9;10 - digest :: The third field contains the digest (hash) algorithms this version of GnuPG supports, separated by semicolons. The digest numbers are as specified in - RFC-4880. + RFC-4880. Using =digestname= prints names instead of + numbers. : cfg:digest:1;2;3;8;9;10 @@ -319,6 +322,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: would result in: : cfg:group:mynames:patti;joe;0x12345678;paige + - curve :: The third field contains the curve names this version + of GnuPG supports, separated by semicolons. Using + =curveoid= prints OIDs instead of numbers. + + : cfg:curve:ed25519;nistp256;nistp384;nistp521 + * Format of the --status-fd output diff --git a/doc/gpg.texi b/doc/gpg.texi index b90f487..a326233 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2945,6 +2945,10 @@ source distribution for the details of which configuration items may be listed. @option{--list-config} is only usable with @option{--with-colons} set. + at item --list-gcrypt-config + at opindex list-gcrypt-config +Display various internal configuration parameters of Libgcrypt. + @item --gpgconf-list @opindex gpgconf-list This command is similar to @option{--list-config} but in general only diff --git a/g10/gpg.c b/g10/gpg.c index ea331d6..deb3966 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -116,6 +116,7 @@ enum cmd_and_opt_values aQuickSignKey, aQuickLSignKey, aListConfig, + aListGcryptConfig, aGPGConfList, aGPGConfTest, aListPackets, @@ -449,6 +450,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aChangePIN, "change-pin", N_("change a card's PIN")), #endif ARGPARSE_c (aListConfig, "list-config", "@"), + ARGPARSE_c (aListGcryptConfig, "list-gcrypt-config", "@"), ARGPARSE_c (aGPGConfList, "gpgconf-list", "@" ), ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@" ), ARGPARSE_c (aListPackets, "list-packets","@"), @@ -1578,8 +1580,11 @@ print_algo_names(int (*checker)(int),const char *(*mapper)(int)) static void list_config(char *items) { - int show_all=(items==NULL); - char *name=NULL; + int show_all = !items; + char *name = NULL; + const char *s; + struct groupitem *giter; + int first, iter; if(!opt.with_colons) return; @@ -1590,18 +1595,16 @@ list_config(char *items) if(show_all || ascii_strcasecmp(name,"group")==0) { - struct groupitem *iter; - - for(iter=opt.grouplist;iter;iter=iter->next) + for (giter = opt.grouplist; giter; giter = giter->next) { strlist_t sl; es_fprintf (es_stdout, "cfg:group:"); - es_write_sanitized (es_stdout, iter->name, strlen(iter->name), + es_write_sanitized (es_stdout, giter->name, strlen(giter->name), ":", NULL); es_putc (':', es_stdout); - for(sl=iter->values;sl;sl=sl->next) + for(sl=giter->values; sl; sl=sl->next) { es_write_sanitized (es_stdout, sl->d, strlen (sl->d), ":;", NULL); @@ -1686,20 +1689,31 @@ list_config(char *items) any=1; } - if(show_all || ascii_strcasecmp(name,"ccid-reader-id")==0) + if (show_all || !ascii_strcasecmp(name,"ccid-reader-id")) { -#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB) \ - && GNUPG_MAJOR_VERSION == 1 + /* We ignore this for GnuPG 1.4 backward compatibility. */ + any=1; + } - char *p, *p2, *list = ccid_get_reader_list (); + if (show_all || !ascii_strcasecmp (name,"curve")) + { + es_printf ("cfg:curve:"); + for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first=0) + es_printf ("%s%s", first?"":";", s); + es_printf ("\n"); + any=1; + } - for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1) + /* Curve OIDs are rarely useful and thus only printed if requested. */ + if (name && !ascii_strcasecmp (name,"curveoid")) + { + es_printf ("cfg:curveoid:"); + for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first = 0) { - *p2 = 0; - es_printf ("cfg:ccid-reader-id:%s\n", p); + s = openpgp_curve_to_oid (s, NULL); + es_printf ("%s%s", first?"":";", s? s:"[?]"); } - free (list); -#endif + es_printf ("\n"); any=1; } @@ -2265,6 +2279,7 @@ main (int argc, char **argv) { case aCheckKeys: case aListConfig: + case aListGcryptConfig: case aGPGConfList: case aGPGConfTest: case aListPackets: @@ -4222,6 +4237,13 @@ main (int argc, char **argv) } break; + case aListGcryptConfig: + /* Fixme: It would be nice to integrate that with + --list-config but unfortunately there is no way yet to have + libgcrypt print it to an estream for further parsing. */ + gcry_control (GCRYCTL_PRINT_CONFIG, stdout); + break; + case aListPackets: opt.list_packets=2; default: ----------------------------------------------------------------------- Summary of changes: common/openpgp-oid.c | 38 +++++++++++++++++++++++++++ common/t-openpgp-oid.c | 44 +++++++++++++++++++++++++++++-- common/util.h | 1 + doc/DETAILS | 11 +++++++- doc/gpg.texi | 11 ++++++++ g10/gpg.c | 71 +++++++++++++++++++++++++++++--------------------- g10/keylist.c | 5 +--- 7 files changed, 144 insertions(+), 37 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 10 21:22:57 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 10 Mar 2015 21:22:57 +0100 Subject: [git] gnupg-doc - branch, master, updated. 35bf6904d86030cd5aee790067d8c5ff3d3f2f5d 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 35bf6904d86030cd5aee790067d8c5ff3d3f2f5d (commit) via dc484dbdf121f0c3cf2ecab7b95b39bb40ec94cc (commit) via aa3feee9ecd35dea767264ff4dbab0f083d5d6d0 (commit) via 649aa795b88cf527237485391a36ec2a06d2f511 (commit) via 2745ebf3c06db75c84c7e97c03a8aaeafcef9b17 (commit) from 1d0089b9bf30e24aabd0b2b63e3f9234e61ef3bd (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 35bf6904d86030cd5aee790067d8c5ff3d3f2f5d Author: Werner Koch Date: Tue Mar 10 21:01:43 2015 +0100 Temporary disable SEPA payments The preorder feature is ready but the tool to insert the actual payments is still in the works. Thus we can't enable them right now. diff --git a/web/donate/index.org b/web/donate/index.org index c63358b..5888d95 100644 --- a/web/donate/index.org +++ b/web/donate/index.org @@ -104,13 +104,6 @@ value="pp" />PayPal - - - - - -   commit dc484dbdf121f0c3cf2ecab7b95b39bb40ec94cc Author: Werner Koch Date: Tue Mar 10 21:10:00 2015 +0100 web: Update frontpage diff --git a/web/index.org b/web/index.org index f1f3ad9..d62593c 100644 --- a/web/index.org +++ b/web/index.org @@ -2,66 +2,6 @@ #+STARTUP: showall #+SETUPFILE: "share/setup.inc" - -* Securing the future of GnuPG - -Work on GnuPG is mostly financed from donations. To continue -maintaining GnuPG so to keep it strong and secure against the ever -increasing mass surveillance we need your support. Until the end of -November we received a total of 6584\thinsp\euro (~5500 net) donations -for this year. Along with the 18000\thinsp\euro net from the [[https://www.gnupg.org/blog/20140512-rewards-sent.html][Goteo -campaign]] this paid for less than 50% of the costs for one -developer. - -#+BEGIN_HTML -
-
-

 

-

- - - - - -

-

-#+END_HTML - -For a critical project of this size two experienced developers are -required for proper operation. This requires gross revenues of at -least 120000 Euro per year. Unfortunately there is currently only one -underpaid full time developer who is barely able to keep up with the -work; see this [[file:blog/20141214-gnupg-and-g10.org][blog entry]] for some backgound. Please help to secure -the future of GnuPG and consider to [[file:donate/index.org][donate]] to this project [[file:donate/index.org][now]]. -(Donating Bitcoins is possible via the Wau Holland Stiftung; see the -[[file:donate/index.org][donation page]] for details.) - -** A big Thanks to all supporters - -Due to this [[http://www.propublica.org/article/the-worlds-email-encryption-software-relies-on-one-guy-who-is-going-broke][ProPublica article]] we received more than 120,000 \euro of -individual donations on a single day. There is even more: The [[http://www.linuxfoundation.org/programs/core-infrastructure-initiative][Core -Infrastructure Initiative]] granted 60,000 $ for 2015. Our payment -service [[https://twitter.com/stripe/status/563449352635432960][Stripe]] and [[https://www.facebook.com/notes/protect-the-graph/supporting-gnu-privacy-guard/1564591893780956][Facebook]] will each give 50,000 $ to the project. -And finally the [[https://www.wauland.de/en/donation.html#61][Wau Holland Stiftung]] is collecting tax deductible -funds for GnuPG (19000 \euro plus 57 BTC). - -As the main author of GnuPG, I like to thank everyone for supporting -the project, be it small or large individual donations, helping users, -providing corporate sponsorship, working on the software, and for all -the encouraging words. - -GnuPG does not stand alone: there are many other projects, often -unknown to most people, which are essential to keep the free Internet -running. Many of them are run by volunteers who spend a lot of unpaid -time on them. They need our support as well. - -/--- Werner, 2015-02-06/ - - - - - * The GNU Privacy Guard #+index: GnuPG #+index: GPG @@ -107,11 +47,18 @@ should use GnuPG for your electronic communication. If you need printed leaflets check out [[https://fsfe.org/contribute/spreadtheword.html#gnupg-leaflet][FSFE?s GnuPG leaflet]]. -* Latest news +* News #+index: News -The following frames report the latest news from GnuPG. A list with -all [[file:news.org][news of previous years]] is also available. +The latest blog entries: +#+begin_html +
    + +
+#+end_html + +The latest release news:\\ +([[file:news.org][all news]]) # For those of you who like reading world?s news with an RSS reader, # GnuPG's latest news are available as [[http://feedvalidator.org/check.cgi?url%3Dhttps://www.gnupg.org/news.en.rss][RSS 2.0 compliant]] feed. Just @@ -160,6 +107,28 @@ features a lot of new things including support for ECC. Read more at the [[file:faq/whats-new-in-2.1.org][feature overview]] page and in the [[http://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000358.html][announcement]] mail. +* A big Thanks to all supporters + +Due to this [[http://www.propublica.org/article/the-worlds-email-encryption-software-relies-on-one-guy-who-is-going-broke][ProPublica article]] we received more than 120,000 \euro of +individual donations on a single day. There was even more: The [[http://www.linuxfoundation.org/programs/core-infrastructure-initiative][Core +Infrastructure Initiative]] granted 60,000 $ for 2015. Our payment +service [[https://twitter.com/stripe/status/563449352635432960][Stripe]] and [[https://www.facebook.com/notes/protect-the-graph/supporting-gnu-privacy-guard/1564591893780956][Facebook]] will each give 50,000 $ to the project. +And finally the [[https://www.wauland.de/en/donation.html#61][Wau Holland Stiftung]] is collecting tax deductible +funds for GnuPG (19000 \euro plus 57 BTC). + +As the main author of GnuPG, I like to thank everyone for supporting +the project, be it small or large individual donations, helping users, +providing corporate sponsorship, working on the software, and for all +the encouraging words. + +GnuPG does not stand alone: there are many other projects, often +unknown to most people, which are essential to keep the free Internet +running. Many of them are run by volunteers who spend a lot of unpaid +time on them. They need our support as well. + +/--- Werner, 2015-02-06/ + +(see also this [[https://gnupg.org/blog/20150310-gnupg-in-february.html][blog]] entry) * COMMENT This is the publishing info used for the GnuPG pages commit aa3feee9ecd35dea767264ff4dbab0f083d5d6d0 Author: Werner Koch Date: Tue Mar 10 21:20:14 2015 +0100 Insert the latest blog entries into the main page. diff --git a/tools/mkkudos.sh b/tools/mkkudos.sh index 6d7e32b..ce2ad45 100755 --- a/tools/mkkudos.sh +++ b/tools/mkkudos.sh @@ -1,5 +1,30 @@ #!/bin/sh +# Update the list of donors and a few other things. +# +# ==================================================================== +# This org-mode snippet is used to insert the progress bar into a HTML +# file: +# +# #+BEGIN_HTML +#
+#
+#

 

+#

+# +# +# +# +# +#

+#

+# #+END_HTML +# +# To use it the code at "Campaign data" below needs to be adjusted as +# well. +# =================================================================== + set -e usage() @@ -52,11 +77,13 @@ done htdocs="/var/www/www/www.gnupg.org/htdocs" donors="$htdocs/donate/donors.dat" donations="$htdocs/donate/donations.dat" +blogheadlinefile="/var/www/www/blog.gnupg.org/htdocs/headlines.txt" if [ $testmode = yes ]; then htdocs="/home/wk/s/gnupg-doc/stage" donors="$htdocs/../scratch/donors.dat" donations="$htdocs/../scratch/donations.dat" + blogheadlinefile="$htdocs/../misc/blog.gnupg.org/headlines.txt" fi @@ -69,6 +96,15 @@ if [ ! -f "$donations" ]; then exit 1 fi +if [ ! -f "$blogheadlinefile" ]; then + echo "mkkudos.sh: '$blogheadlinefile' not found" >&2; + blogheadline="" +else + blogheadline=$(awk -F\| ' + NR<=3 {printf "
  • %s
  • ", $1, $2} + ' "$blogheadlinefile") +fi + tmp=$(head -1 "$donations") monyear=$(echo "$tmp" | awk -F: 'BEGIN { m[1] = "January"; m[2] = "February"; m[3] = "March"; m[4] = "April"; m[5] = "May"; @@ -110,6 +146,7 @@ for file in "$htdocs/donate/"kudos-????.html "$htdocs/donate/"kudos.html \ -v monyear="$monyear" -v euro="$euro" -v euroyr="$euroyr" \ -v euromo="$euromo" \ -v n="$n" -v nyr="$nyr" -v goal="$goal" -v percent="$percent" \ + -v blogheadline="$blogheadline" \ <"$file" >"$file.tmp" ' // {indon=1; print; insert("") } // {indon=0} @@ -151,6 +188,10 @@ for file in "$htdocs/donate/"kudos-????.html "$htdocs/donate/"kudos.html \ percent; next } + // { + printf " %s\n", blogheadline; + next + } !indon { print } function insert (tag) { commit 649aa795b88cf527237485391a36ec2a06d2f511 Author: Werner Koch Date: Tue Mar 10 19:20:37 2015 +0100 blog: Add news for 2/2015 Also fixed headline extraction in the upload script and upload a headlines file. diff --git a/.gitignore b/.gitignore index b05caed..bca1deb 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ scratch/ /web/swdb.lst.sig /misc/blog.gnupg.org/index.html /misc/blog.gnupg.org/20*.html +/misc/blog.gnupg.org/headlines.txt diff --git a/misc/blog.gnupg.org/20150310-gnupg-in-february.org b/misc/blog.gnupg.org/20150310-gnupg-in-february.org new file mode 100644 index 0000000..ea089cd --- /dev/null +++ b/misc/blog.gnupg.org/20150310-gnupg-in-february.org @@ -0,0 +1,115 @@ +# GnuPG News for January 2015 +#+STARTUP: showall +#+AUTHOR: Werner +#+DATE: March 10th, 2015 + +** GnuPG News for February 2015 + +Indeed, very exiting news this month: The financial crisis of The +GnuPG Project is over. Due to an unexpected amount of donations +received in the first days of February we can keep on working for at +least the next 2 or 3 years. + +How did this happen? At the [[https://events.ccc.de/congress/2014/wiki/Main_Page][31C3]] Nico Josattis arranged an Interview +with [[http://juliaangwin.com][Julia Angwin]] who writes for [[http://www.propublica.org][ProPublica]]. Eventually on the 5th +her [[http://www.propublica.org/article/the-worlds-email-encryption-software-relies-on-one-guy-who-is-going-broke][article]] was published and immediately received a lot of attention. +Not only at the ProPublica site but at many other news site as well. +While checking my mail on that evening, I noticed more than thousand +notification mails for donations and even better: that continuous stream of +donations did not stop for the next days. Alone on the first day we +received more than 120,000\thinsp\euro and thus more than our initial goal. +I even had to fix the script building the donation progress bar to not +overflow the right margin the same night. I also received a call from +one of the Stripe founders who offered yearly donations from Stripe +and Facebook each at 50,0000\thinsp$. Amazing. + +I like to *thank everyone* for supporting the project, be it small or +large individual donations, helping users, providing corporate +sponsorship, working on the software, and for all the encouraging +words by mail, blogs, and even postcards. + +Due to that new publicity for GnuPG, I received many requests for +interviews and for several days journalists and photographers visited +me in my office. They wrote several articles for German papers and +radio stations, for example in the [[http://www.taz.de/Verschluesselung-mit-GnuPG/!154635/][taz]], the [[http://www.sueddeutsche.de/digital/verschluesselungssoftware-gnu-pg-wie-ein-mann-das-e-mail-geheimnis-verteidigt-1.2355155][S?ddeutsche Zeitung]], and +the [[http://dw.de/p/1Eebj][Deutsche Welle]]. I hope these articles help to keep up the +awareness for the importance of privacy issues. + +GnuPG does not stand alone: there are many other projects, often +unknown to most people, which are essential to keep the free Internet +running. Many of them are run by volunteers who spend a lot of unpaid +time on them. They need our support as well! + +Now what to do with all that money? Before a final plan can be +drafted, tax issues need to be resolved. Given that g10^code (the +legal entity behind the project) is not a charity, we need to find a +way to stretch the use of the money beyond this year. My tax +advisor is currently looking into this and I will report on the +outcome in another blog entry. + +Regardless of this I started to look out for a second developer and +fortunately [[http://walfield.org][Neal Walfield]] was searching for a job and accepted my +offer to work on GnuPG. Neal is well known for his work on modern +operating systems and I consider him an excellent hacker. I am glad +to have him on board. + +*** Release status + +GnuPG [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000361.html][2.1.2]] was released on the 11th, [[http://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000362.html][2.0.27]] on the 18th, and [[http://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000363.html][1.4.19]] +on the 27th. + +The 1.4.19 release features a fix for a new side channel attack on the +Elgamal encryption (which used to be the default public key encryption +algorithm until 2009). Go ahead and read how Genkin?s group describes +the [[http://www.cs.tau.ac.il/~tromer/radioexp/][details]] of this attack. The release also includes a mitigation +for another SCA to be described in the forthcoming paper /Last-Level +Cache Side-Channel Attacks are Practical/ by Yarom et al. + +Libgcrypt [[http://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000364.html][1.6.3]] was released on the 27th to fix the described SCAs for +GnuPG 2.0 and 2.1. + +*** Released and not yet released changes + +Several segfaults due to NULL-derefs and invalid memory reads when +using garbled keyrings were fixed. These unlikely exploitable bugs +were detected by fuzzing instrumented versions of GnuPG; [[https://blog.fuzzing-project.org/5-Multiple-issues-in-GnuPG-found-through-keyring-fuzzing-TFPA-0012015.html][Hanno B?ck's +report]] has some details. A long standing implementation flaw +copying memory stored values to integers variables was also found and +fixed. These bug fixes have been backported to 2.0 and 1.4; +Daniel Kahn Gillmor was kind enough to help with this. + +The decade old PKA system was modernized. The formerly used TXT +records haven been replaced with CERT records of the IPGP type, and +the local part of the mail address is now hashed and base32 encoded to +support all valid mail addresses. This has been backported to 1.4.19. +The new option =--print-pka-records= for 2.1 can be used to create +zone files for PKA. + +The removal of the PGP-2 support from 2.1 turned out to be more +complicated than expected. Another bug related to this only showed up +and was fixed after the release of 2.1.2. + +To help people not fluent in the spelling alphabet or when using +small fonts the option =--with-icao-spelling= has been added to 2.1: +#+begin_example +pub dsa2048/F2AD85AC1E42B367 2007-12-31 [expires: 2018-12-31] + Key fingerprint = 8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367 + "Eight Zero Six One Five Eight Seven Zero + Foxtrot Five Bravo Alfa Delta Six Niner Zero + Three Three Three Six Eight Six Delta Zero + Foxtrot Two Alfa Delta Eight Five Alfa Charlie + One Echo Four Two Bravo Three Six Seven" +#+end_example + +The dropped support for LDAP keyserver will be re-introduced with +2.1.3. Neal started to work on this and published a detailed description +on how to setup such an [[https://wiki.gnupg.org/LDAPKeyserver][LDAP server]]. + + +** About this news posting + +I try to write a news posting every month. However, other work may +have a higher priority (e.g. security fixes) and thus I won?t promise +any fix publication date. If you have an interesting topic for a news +posting, please feel free to mail me or gnupg-users at . A summary of +the mailing list discussion would be a nice to have. diff --git a/misc/blog.gnupg.org/upload b/misc/blog.gnupg.org/upload index 912a885..bffe8d1 100755 --- a/misc/blog.gnupg.org/upload +++ b/misc/blog.gnupg.org/upload @@ -2,6 +2,12 @@ set -e +opt_upload=yes +if [ x"$1" = x"--no-upload" ]; then + opt_upload=no +fi + + if [ "$(pwd | awk -F/ '{print $NF}')" != "blog.gnupg.org" ]; then echo "upload: not invoked from the blog.gnupg.org directory" >&2; exit 1 @@ -36,7 +42,8 @@ newest=$(head -1 index.tmp) : >index.headlines.tmp cat index.tmp | while read fname; do echo -n "${fname#./}|" >>index.headlines.tmp - sed -n '/^

    ]*>\(.*\)

    ,\1,p' $fname >>index.headlines.tmp + sed -n '/^

    ]*>\(.*\)

    ,\1,p;q}' \ + $fname >>index.headlines.tmp done # Update the index file @@ -80,12 +87,14 @@ echo "upload: Updating feed file" >&2 -# Remove temp file -rm index.headlines.tmp +# Rename headlines file +mv index.headlines.tmp headlines.txt -echo "upload: Uploading files" >&2 -rsync -vr --links --exclude '*~' --exclude upload --exclude '*tmp' \ - --exclude '*.org' \ - . werner at trithemius.gnupg.org:/var/www/www/www.gnupg.org/misc/blog/ +if [ $opt_upload = yes ]; then + echo "upload: Uploading files" >&2 + rsync -vr --links --exclude '*~' --exclude upload --exclude '*tmp' \ + --exclude '*.org' \ + . werner at trithemius.gnupg.org:/var/www/www/www.gnupg.org/misc/blog/ +fi #eof commit 2745ebf3c06db75c84c7e97c03a8aaeafcef9b17 Author: Werner Koch Date: Mon Mar 9 20:35:26 2015 +0100 Prepare for SEPA payments. diff --git a/cgi/procdonate.cgi b/cgi/procdonate.cgi index 3b2ecf4..bb95ca0 100755 --- a/cgi/procdonate.cgi +++ b/cgi/procdonate.cgi @@ -41,6 +41,7 @@ my $currency = ""; my $name = ""; my $mail = ""; my $message = ""; +my $separef = ""; my $errorstr = ""; # We use a dictionary to track error. Those errors will then be @@ -50,6 +51,7 @@ my %errdict = (); # Prototypes sub fail ($); sub get_paypal_approval (); +sub complete_sepa (); # Write a template file. A template is a proper HTML file with @@ -64,7 +66,7 @@ sub get_paypal_approval (); sub write_template ($) { my $fname = shift; - my $errorpanel = ''; + my $errorpanel = $errorstr; my $err_amount = ''; my $err_name = ''; my $err_mail = ''; @@ -85,6 +87,7 @@ sub write_template ($) { $name =~ s/\x22/\x27/g; $mail =~ s/\x22/\x27/g; $message =~ s/\x22/\x27/g; + $separef =~ s/\x22/\x27/g; # Clean possible user provided data $sessid =~ s//$sel_gbp>/ || s/(/$sel_jpy>/ || s//$publishname/ + || s//$separef/ || s//$errorstr/ || s//$err_amount/ || s//$err_name/ @@ -301,9 +308,13 @@ sub write_checkout_page () if ( $paytype eq "cc" ) { write_template("donate/checkout-cc.html"); } - else { + elsif ( $paytype eq "pp" ) { write_template("donate/checkout-pp.html"); } + else { + # For SEPA this is the final page + write_template("donate/checkout-se.html"); + } } @@ -321,6 +332,7 @@ sub write_thanks_page () sub check_donation () { my %data; + my %sepa; my $anyerr = 0; # Note: When re-displaying the page we always use amount other @@ -364,9 +376,16 @@ sub check_donation () # Check the payment type $paytype = $q->param("paytype"); - if ( $paytype ne "cc" and $paytype ne "pp" ) { + if ( $paytype ne "cc" and $paytype ne "pp" and $paytype ne "se" ) { $errdict{"paytype"} = 'No payment type selected.' . - ' Use "Credit Card" or "PayPal".'; + ' Use "Credit Card", "PayPal", or "SEPA".'; + $anyerr = 1; + } + + # SEPA credit transfers are only possible in Euro. + # (yes, this may overwrite an earlier error message). + if ( $paytype eq "se" and $currency ne "EUR" ) { + $errdict{"amount"} = 'SEPA transfers are only possible in EUR.'; $anyerr = 1; } @@ -392,10 +411,13 @@ sub check_donation () payproc ('SESSION create', \%data ) or fail $data{"ERR_Description"}; $sessid = $data{"_SESSID"}; - # Send the checkout page and redirect to paypal + # Send the checkout page or redirect to paypal if ( $paytype eq "pp" ) { get_paypal_approval (); } + elsif ( $paytype eq "se" ) { + complete_sepa (); + } else { write_checkout_page(); } @@ -565,7 +587,7 @@ sub confirm_paypal_checkout () $mail = $data{"Mail"}; $message = $data{"Message"}; - # Store the session after setting the above cars because that call + # Store the session after setting the above vars because that call # clears DATA. payproc ('SESSION put ' . $sessid, \%data) or fail $data{"ERR_Description"}; @@ -618,6 +640,47 @@ EOF } +# Complete the SEPA payment: Check values and show final page. +sub complete_sepa () +{ + my %data; + my %request; + + payproc ('SESSION get ' . $sessid, \%data) + or fail $data{"ERR_Description"}; + + $request{"Currency"} = $data{"Currency"}; + $request{"Amount"} = $data{"Amount"}; + $request{"Desc"} = "GnuPG SEPA donation"; + $request{"Meta[name]"} = $data{"Name"} unless $data{"Name"} eq 'Anonymous'; + if ($data{"Mail"} ne '') { + $request{"Meta[mail]"} = $data{"Mail"}; + } + if ($data{"Message"} ne '') { + $request{"Meta[message]"} = $data{"Message"}; + } + if (not payproc ('SEPAPREORDER', \%request )) { + $errorstr = "Error: " . $request{"ERR_Description"}; + # Back to the main page. + write_main_page (); + return; + } + $separef = $request{"SEPA-Ref"}; + $amount = $request{"Amount"}; + + # Set remaining vars for the checkout page. + $currency = $data{"Currency"}; + $paytype = $data{"Paytype"}; + $stripeamount = $data{"Stripeamount"}; + $euroamount = $data{"Euroamount"}; + $name = $data{"Name"}; + $mail = $data{"Mail"}; + $message = $data{"Message"}; + + write_checkout_page (); +} + + # # Main diff --git a/web/donate/checkout-se.org b/web/donate/checkout-se.org new file mode 100644 index 0000000..9ebd91d --- /dev/null +++ b/web/donate/checkout-se.org @@ -0,0 +1,69 @@ +#+TITLE: GnuPG - Donate - Checkout using SEPA +#+STARTUP: showall +#+SETUPFILE: "../share/setup.inc" + +* Donate - Checkout using SEPA + + Single Euro Payments Area credit transfers can be used to transfer + Euro within the 34 states of the European Union and 6 associated + states. + +#+BEGIN_HTML + + + + + + + + + + + + + +
    Name: 
    Mail: 
    Message: 
    +#+END_HTML + + Please send your donation to this bank account: + +#+BEGIN_HTML + + + + + + + + + + + + + + + + + + + + + +
    Owner: g10 Code GmbH
    IBAN: DE76 3015 0200 0002 1086 03
    BIC: WELADED1KSD
    Reference: 
    Amount:  + EUR
    +#+END_HTML + + Take care to give the reference number so that we can match your + data with your actual donation and list you as donor if desired. + The given reference number expires in 30 days, thus please act in + time. You may send a different amount but please send at least 5 + Euro to cover our bookkeeping costs. Using the reference number for + recurring donations is also possible. + + *Thank you in advance for your donation.* + +#+BEGIN_HTML + +#+END_HTML diff --git a/web/donate/index.org b/web/donate/index.org index 5888d95..c63358b 100644 --- a/web/donate/index.org +++ b/web/donate/index.org @@ -104,6 +104,13 @@ value="pp" />PayPal + + + + + +   ----------------------------------------------------------------------- Summary of changes: .gitignore | 1 + cgi/procdonate.cgi | 75 ++++++++++++-- misc/blog.gnupg.org/20150310-gnupg-in-february.org | 115 +++++++++++++++++++++ misc/blog.gnupg.org/upload | 23 +++-- tools/mkkudos.sh | 41 ++++++++ web/donate/checkout-se.org | 69 +++++++++++++ web/index.org | 95 ++++++----------- 7 files changed, 343 insertions(+), 76 deletions(-) create mode 100644 misc/blog.gnupg.org/20150310-gnupg-in-february.org create mode 100644 web/donate/checkout-se.org hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 11 11:01:55 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 11 Mar 2015 11:01:55 +0100 Subject: [git] gnupg-doc - branch, master, updated. 52ab1ee9c0cf0f600f4685b34bc80bee8af09bec 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 52ab1ee9c0cf0f600f4685b34bc80bee8af09bec (commit) from 35bf6904d86030cd5aee790067d8c5ff3d3f2f5d (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 52ab1ee9c0cf0f600f4685b34bc80bee8af09bec Author: Werner Koch Date: Wed Mar 11 10:54:57 2015 +0100 Reworked the list of donors. diff --git a/tools/mkkudos.sh b/tools/mkkudos.sh index ce2ad45..fb742a8 100755 --- a/tools/mkkudos.sh +++ b/tools/mkkudos.sh @@ -110,20 +110,56 @@ monyear=$(echo "$tmp" | awk -F: 'BEGIN { m[1] = "January"; m[2] = "February"; m[3] = "March"; m[4] = "April"; m[5] = "May"; m[6] = "June"; m[7] = "July"; m[8] = "August"; m[9] = "September"; m[10] = "October"; m[11] = "November"; m[12] = "December"; } - {printf "%s %d", m[$2] , $1}') -euromo=$(echo "$tmp" | awk -F: '{printf "%d €", int($8 + 0.5)}') + {printf "%s %d", m[int($2)] , $1}') +thisyear=$(echo "$tmp" | awk -F: '{print $1}') euroyr=$(echo "$tmp" | awk -F: '{printf "%d €", int($10 + 0.5)}') -n=$(echo "$tmp" | awk -F: '{printf "%d", $7}') nyr=$(echo "$tmp" | awk -F: '{printf "%d", $9}') -euroyr_campaign=$(echo "$tmp" | awk -F: '$1=="2014"{printf "0"; next};{printf "%d", int($10 + 0.5)}') + +dontable=$(awk -F: <"$donations" -v thisyear="$thisyear" ' + BEGIN { m[1] = "January"; + m[2] = "February"; m[3] = "March"; m[4] = "April"; m[5] = "May"; + m[6] = "June"; m[7] = "July"; m[8] = "August"; m[9] = "September"; + m[10] = "October"; m[11] = "November"; m[12] = "December" ; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + printf "\n"; + } + NR==1 { nyear = $9; totalyear = int($10 + 0.5); + } + $1 != thisyear { + printf "\n"; + printf "\n"; + printf "\n", thisyear; + printf " \n", nyear; + printf " \n", totalyear; + printf "\n"; + printf "
    Month#
    %d%d%d
    \n"; + exit 0 + } + { printf "%s\n", m[int($2)]; + printf " %d\n", $7; + printf " %d\n", int($8 + 0.5); + } +') + + # Campaign data goal="120000" -tmp=$(grep '^2014:12:' "$donations") -euro=$(echo "$tmp" | awk -F: '{printf "%d", int($8 + 0.5)}') -euro=$(($euro + $euroyr_campaign)) -percent=$(echo "$euro:$goal" | awk -F: '{ p = (int($1)*100)/int($2); +percent=$(echo "$euroyr:$goal" | awk -F: '{ p = (int($1)*100)/int($2); if(p > 100) { p = 100 }; printf "%d", p}') @@ -142,10 +178,10 @@ for file in "$htdocs/donate/"kudos-????.html "$htdocs/donate/"kudos.html \ fi [ $verbose = yes ] && echo "processing $file" >&2 [ -f "$file.tmp" ] && rm "$file.tmp" - awk -F: -v year=$year -v donors="$donors" \ - -v monyear="$monyear" -v euro="$euro" -v euroyr="$euroyr" \ - -v euromo="$euromo" \ - -v n="$n" -v nyr="$nyr" -v goal="$goal" -v percent="$percent" \ + awk -F: -v year=$year -v donors="$donors" -v dontable="$dontable" \ + -v monyear="$monyear" -v thisyear="$thisyear" \ + -v euro="$euro" -v euroyr="$euroyr" \ + -v nyr="$nyr" -v goal="$goal" -v percent="$percent" \ -v blogheadline="$blogheadline" \ <"$file" >"$file.tmp" ' // {indon=1; print; insert("") } @@ -154,16 +190,14 @@ for file in "$htdocs/donate/"kudos-????.html "$htdocs/donate/"kudos.html \ // {indon=0} // {indon=1; print; insert("goteo13") } // {indon=0} + // {indon=1; print; print dontable } + // {indon=0} // { printf " %s\n", monyear; next } - // { - printf " %s\n", euromo; - next - } - // { - printf " %s\n", n; + // { + printf " %d\n", thisyear; next } // { diff --git a/web/donate/index.org b/web/donate/index.org index 5888d95..f77f7cb 100644 --- a/web/donate/index.org +++ b/web/donate/index.org @@ -166,10 +166,17 @@ ** Recent donors -#+HTML:
      -#+HTML: -#+HTML: -#+HTML:
    • (all)
    • -#+HTML:

    +#+BEGIN_HTML +

    +

    Donations received in + +:  + +

    +#+END_HTML # eof # diff --git a/web/donate/kudos.org b/web/donate/kudos.org index f6ad46c..f1ad914 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -2,6 +2,37 @@ #+STARTUP: showall #+SETUPFILE: "../share/setup.inc" +* Donation Summary + +*** This year + +#+BEGIN_HTML + + +#+END_HTML + + +*** Previous years + +| Year | # | \EUR | net \EUR | +| | | | | +|------+-----+-------+----------| +| 2014 | 801 | 34700 | | +| 2013 | 148 | 5041 | 4145 | +| 2012 | 53 | 5991 | 4963 | +| 2011 | 21 | 553 | 465 | +|------+-----+-------+----------| +| | | 46285 | | +#+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.\\ +#+HTML:
    + +The [[https://gnupg.org/blog/20140512-rewards-sent.html][Goteo crowdfunding]] campaign raised an additional +32641\thinsp\euro (27429 net) in December 2013. + + * List of Donors #+HTML:
      @@ -24,45 +55,6 @@ [[https://www.wauland.de][file:logos/whs-logo.png]] #+HTML:
    -** Donation summary - -#+BEGIN_HTML -

    In - this month -we received - N -donations of - X Euro -.
    -In this year we received - M -donations of - Y Euro -. -

    -#+END_HTML - - -Donations for the previous years: - -| Year | # | \EUR | net \EUR | -| | | | | -|------+-----+-------+----------| -| 2011 | 21 | 553 | 465 | -| 2012 | 53 | 5991 | 4963 | -| 2013 | 148 | 5041 | 4145 | -| 2014 | 801 | 34700 | | -|------+-----+-------+----------| -| | | 46285 | | -#+TBLFM: $LR3=vsum(@I.. at II)::$LR4=vsum(@I.. at II) - -# In 2014 without the 32641.27 (27429.64) from the Goteo campaign - -#+HTML:
    -The "net" column gives the actual value without VAT and credit card -fees.\\ -#+HTML:
    - * Hardware and service donations We have to thank [[https://www.openit.de][OpenIT]] for their long time support of GnuPG. They ----------------------------------------------------------------------- Summary of changes: tools/mkkudos.sh | 70 ++++++++++++++++++++++++++++++++++++++-------------- web/donate/index.org | 17 +++++++++---- web/donate/kudos.org | 70 +++++++++++++++++++++++----------------------------- 3 files changed, 95 insertions(+), 62 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 11 15:07:19 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 11 Mar 2015 15:07:19 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.27-4-g25e2b27 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 25e2b27b0027af9c1ce0cae0cd549c09ed349811 (commit) via 2f3de06ff44daefae9857549fc4ab7ae8bf8e70d (commit) from 936416690e6c889505d84fe96983a66983beae5e (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 25e2b27b0027af9c1ce0cae0cd549c09ed349811 Author: Werner Koch Date: Thu Mar 5 02:33:47 2015 +0100 common: Check option arguments for a valid range * common/argparse.h (ARGPARSE_INVALID_ARG): New. * common/argparse.c: Include limits h and errno.h. (initialize): Add error strings for new error constant. (set_opt_arg): Add range checking. -- Signed-off-by: Werner Koch [ This is a backport of 0d73a242cb53522669cf712b5ece7d1ed05d003a from master to STABLE-BRANCH-2-0 ] Signed-off-by: Daniel Kahn Gillmor diff --git a/jnlib/argparse.c b/jnlib/argparse.c index 184b0f6..49f50ec 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #include "libjnlib-config.h" #include "mischelp.h" @@ -198,6 +201,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) s = _("keyword too long"); else if ( arg->r_opt == ARGPARSE_MISSING_ARG ) s = _("missing argument"); + else if ( arg->r_opt == ARGPARSE_INVALID_ARG ) + s = _("invalid argument"); else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND ) s = _("invalid command"); else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS ) @@ -214,6 +219,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) if ( arg->r_opt == ARGPARSE_MISSING_ARG ) jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s); + else if ( arg->r_opt == ARGPARSE_INVALID_ARG ) + jnlib_log_error (_("invalid argument for option \"%.50s\"\n"), s); else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG ) jnlib_log_error (_("option \"%.50s\" does not expect an " "argument\n"), s ); @@ -524,7 +531,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, p[strlen(p)-1] = 0; } if (!set_opt_arg (arg, opts[idx].flags, p)) - jnlib_free(buffer); + jnlib_free(buffer); } } break; @@ -966,23 +973,54 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) } - +/* Returns: -1 on error, 0 for an integer type and 1 for a non integer + type argument. */ static int -set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s) +set_opt_arg (ARGPARSE_ARGS *arg, unsigned flags, char *s) { int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10; + long l; switch ( (arg->r_type = (flags & ARGPARSE_TYPE_MASK)) ) { - case ARGPARSE_TYPE_INT: - arg->r.ret_int = (int)strtol(s,NULL,base); - return 0; case ARGPARSE_TYPE_LONG: - arg->r.ret_long= strtol(s,NULL,base); + case ARGPARSE_TYPE_INT: + errno = 0; + l = strtol (s, NULL, base); + if ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + if (arg->r_type == ARGPARSE_TYPE_LONG) + arg->r.ret_long = l; + else if ( (l < 0 && l < INT_MIN) || l > INT_MAX ) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + else + arg->r.ret_int = (int)l; return 0; + case ARGPARSE_TYPE_ULONG: - arg->r.ret_ulong= strtoul(s,NULL,base); + while (isascii (*s) && isspace(*s)) + s++; + if (*s == '-') + { + arg->r.ret_ulong = 0; + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + errno = 0; + arg->r.ret_ulong = strtoul (s, NULL, base); + if (arg->r.ret_ulong == ULONG_MAX && errno == ERANGE) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } return 0; + case ARGPARSE_TYPE_STRING: default: arg->r.ret_str = s; diff --git a/jnlib/argparse.h b/jnlib/argparse.h index dd9b30b..74f2040 100644 --- a/jnlib/argparse.h +++ b/jnlib/argparse.h @@ -177,6 +177,7 @@ typedef struct #define ARGPARSE_AMBIGUOUS_COMMAND (-9) #define ARGPARSE_INVALID_ALIAS (-10) #define ARGPARSE_OUT_OF_CORE (-11) +#define ARGPARSE_INVALID_ARG (-12) int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); commit 2f3de06ff44daefae9857549fc4ab7ae8bf8e70d Author: Werner Koch Date: Wed Mar 11 14:58:38 2015 +0100 gpg: New command --list-gcrypt-config. * g10/gpg.c (aListGcryptConfig): New. (main): Implement command. Signed-off-by: Werner Koch diff --git a/g10/gpg.c b/g10/gpg.c index 576b88e..060495e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -109,6 +109,7 @@ enum cmd_and_opt_values aSignKey, aLSignKey, aListConfig, + aListGcryptConfig, aGPGConfList, aGPGConfTest, aListPackets, @@ -431,6 +432,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aChangePIN, "change-pin", N_("change a card's PIN")), #endif ARGPARSE_c (aListConfig, "list-config", "@"), + ARGPARSE_c (aListGcryptConfig, "list-gcrypt-config", "@"), ARGPARSE_c (aGPGConfList, "gpgconf-list", "@" ), ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@" ), ARGPARSE_c (aListPackets, "list-packets","@"), @@ -2153,6 +2155,7 @@ main (int argc, char **argv) { case aCheckKeys: case aListConfig: + case aListGcryptConfig: case aGPGConfList: case aGPGConfTest: case aListPackets: @@ -4064,6 +4067,13 @@ main (int argc, char **argv) } break; + case aListGcryptConfig: + /* Fixme: It would be nice to integrate that with + --list-config but unfortunately there is no way yet to have + libgcrypt print it to an estream for further parsing. */ + gcry_control (GCRYCTL_PRINT_CONFIG, stdout); + break; + case aListPackets: opt.list_packets=2; default: ----------------------------------------------------------------------- Summary of changes: g10/gpg.c | 10 ++++++++++ jnlib/argparse.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-------- jnlib/argparse.h | 1 + 3 files changed, 57 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 11 16:30:24 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 11 Mar 2015 16:30:24 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-26-gefde50f 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 efde50f92af241d8357db83e280a6ece62f6397f (commit) from 7b5b52f3268b093eebbac3f199fb69bf246d9cd1 (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 efde50f92af241d8357db83e280a6ece62f6397f Author: Werner Koch Date: Wed Mar 11 16:28:32 2015 +0100 agent: Improve error reporting from Pinentry. * agent/call-pinentry.c (unlock_pinentry): Add error logging. Map error source of uncommon errors to Pinentry. -- With this change it is possible to detect whether an error like GPG_ERR_ASS_INV_RESPONSE has its origin in a call to Pinentry or comes from another part of gpg-agent. Signed-off-by: Werner Koch diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index a96406f..ef1bfa4 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -133,6 +133,34 @@ unlock_pinentry (int rc) assuan_context_t ctx = entry_ctx; int err; + if (rc) + { + if (DBG_ASSUAN) + log_debug ("error calling pinentry: %s <%s>\n", + gpg_strerror (rc), gpg_strsource (rc)); + + /* Change the source of the error to pinentry so that the final + consumer of the error code knows that the problem is with + pinentry. For backward compatibility we do not do that for + some common error codes. */ + switch (gpg_err_code (rc)) + { + case GPG_ERR_NO_PIN_ENTRY: + case GPG_ERR_CANCELED: + case GPG_ERR_FULLY_CANCELED: + case GPG_ERR_ASS_UNKNOWN_INQUIRE: + case GPG_ERR_ASS_TOO_MUCH_DATA: + case GPG_ERR_NO_PASSPHRASE: + case GPG_ERR_BAD_PASSPHRASE: + case GPG_ERR_BAD_PIN: + break; + + default: + rc = gpg_err_make (GPG_ERR_SOURCE_PINENTRY, gpg_err_code (rc)); + break; + } + } + entry_ctx = NULL; err = npth_mutex_unlock (&entry_lock); if (err) ----------------------------------------------------------------------- Summary of changes: agent/call-pinentry.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 11 17:13:52 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 11 Mar 2015 17:13:52 +0100 Subject: [git] gnupg-doc - branch, master, updated. 39662b50026c9339d374fdbef0c5de62e9c46837 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 39662b50026c9339d374fdbef0c5de62e9c46837 (commit) from 52ab1ee9c0cf0f600f4685b34bc80bee8af09bec (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 39662b50026c9339d374fdbef0c5de62e9c46837 Author: Werner Koch Date: Wed Mar 11 17:11:11 2015 +0100 drafts: Add eddsa-for-openpgp draft This commit is -02 with some grammer fixes from Ladar Levison. Unfortunately the history of earlier source files is lost. diff --git a/.gitignore b/.gitignore index bca1deb..ec7b6c5 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ scratch/ /misc/blog.gnupg.org/index.html /misc/blog.gnupg.org/20*.html /misc/blog.gnupg.org/headlines.txt +/misc/id/eddsa-for-openpgp/draft.txt diff --git a/misc/id/common/reference.ED25519.xml b/misc/id/common/reference.ED25519.xml new file mode 100644 index 0000000..fd1505b --- /dev/null +++ b/misc/id/common/reference.ED25519.xml @@ -0,0 +1,27 @@ + + + + + +High-speed high-security signatures + + + + + + + +This paper shows that a $390 mass-market quad-core 2.4GHz +Intel Westmere (Xeon E5620) CPU can create 109000 signatures per +second and verify 71000 signatures per second on an elliptic curve at a +2128 security level. Public keys are 32 bytes, and signatures are 64 bytes. +These performance figures include strong defenses against software side- +channel attacks: there is no data flow from secret keys to array indices, +and there is no data flow from secret keys to branch conditions. + + + + + diff --git a/misc/id/common/reference.RFC.2119.xml b/misc/id/common/reference.RFC.2119.xml new file mode 100644 index 0000000..3c41c07 --- /dev/null +++ b/misc/id/common/reference.RFC.2119.xml @@ -0,0 +1,44 @@ + + + + + +Key words for use in RFCs to Indicate Requirement Levels + +Harvard University +
    + +1350 Mass. Ave. +Cambridge +MA 02138 +- +1 617 495 3864 +sob at harvard.edu
    + +General +keyword + + + In many standards track documents several words are used to signify + the requirements in the specification. These words are often + capitalized. This document defines these words as they should be + interpreted in IETF documents. Authors who follow these guidelines + should incorporate this phrase near the beginning of their document: + + + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL + NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in + RFC 2119. + + + Note that the force of these words is modified by the requirement + level of the document in which they are used. +
    + + + + + + +
    diff --git a/misc/id/common/reference.RFC.2434.xml b/misc/id/common/reference.RFC.2434.xml new file mode 100644 index 0000000..02be9ea --- /dev/null +++ b/misc/id/common/reference.RFC.2434.xml @@ -0,0 +1,58 @@ + + + + + +Guidelines for Writing an IANA Considerations Section in RFCs + +IBM Corporation +
    + +3039 Cornwallis Ave. +PO Box 12195 - BRQA/502 +Research Triangle Park +NC 27709-2195 +919-254-7798 +narten at raleigh.ibm.com
    + +Maxware +
    + +Pirsenteret +N-7005 Trondheim +Norway ++47 73 54 57 97 +Harald at Alvestrand.no
    + +General +Internet Assigned Numbers Authority +IANA + + + Many protocols make use of identifiers consisting of constants and + other well-known values. Even after a protocol has been defined and + deployment has begun, new values may need to be assigned (e.g., for a + new option type in DHCP, or a new encryption or authentication + algorithm for IPSec). To insure that such quantities have consistent + values and interpretations in different implementations, their + assignment must be administered by a central authority. For IETF + protocols, that role is provided by the Internet Assigned Numbers + Authority (IANA). + + + In order for the IANA to manage a given name space prudently, it + needs guidelines describing the conditions under which new values can + be assigned. If the IANA is expected to play a role in the management + of a name space, the IANA must be given clear and concise + instructions describing that role. This document discusses issues + that should be considered in formulating a policy for assigning + values to a name space and provides guidelines to document authors on + the specific text that must be included in documents that place + demands on the IANA. +
    + + + + + +
    diff --git a/misc/id/common/reference.RFC.4880.xml b/misc/id/common/reference.RFC.4880.xml new file mode 100644 index 0000000..809cd97 --- /dev/null +++ b/misc/id/common/reference.RFC.4880.xml @@ -0,0 +1,23 @@ + + + + + +OpenPGP Message Format + + + + + + + + + + + + +This document is maintained in order to publish all necessary information needed to develop interoperable applications based on the OpenPGP format. It is not a step-by-step cookbook for writing an application. It describes only the format and methods needed to read, check, generate, and write conforming packets crossing any network. It does not deal with storage and implementation questions. It does, however, discuss implementation issues necessary to avoid security flaws.</t><t> OpenPGP software uses a combination of strong public-key and symmetric cryptography to provide security services for electronic communications and data storage. These services include confidentiality, key management, authentication, and digital signatures. This document specifies the message formats used in OpenPGP. [STANDARDS-TRACK] + + + + diff --git a/misc/id/common/reference.RFC.5226.xml b/misc/id/common/reference.RFC.5226.xml new file mode 100644 index 0000000..0af19ad --- /dev/null +++ b/misc/id/common/reference.RFC.5226.xml @@ -0,0 +1,18 @@ + + + + + +Guidelines for Writing an IANA Considerations Section in RFCs + + + + + + +Many protocols make use of identifiers consisting of constants and other well-known values. Even after a protocol has been defined and deployment has begun, new values may need to be assigned (e.g., for a new option type in DHCP, or a new encryption or authentication transform for IPsec). To ensure that such quantities have consistent values and interpretations across all implementations, their assignment must be administered by a central authority. For IETF protocols, that role is provided by the Internet Assigned Numbers Authority (IANA).</t><t> In order for IANA to manage a given namespace prudently, it needs guidelines describing the conditions under which new values can be assigned or when modifications to existing values can be made. If IANA is expected to play a role in the management of a namespace, IANA must be given clear and concise instructions describing that role. This document discusses issues that should be considered in formulating a policy for assigning values to a namespace and provides guidelines for authors on the specific text that must be included in documents that place demands on IANA.</t><t> This document obsoletes RFC 2434. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements. + + + + + diff --git a/misc/id/common/reference.RFC.6637.xml b/misc/id/common/reference.RFC.6637.xml new file mode 100644 index 0000000..d7e8394 --- /dev/null +++ b/misc/id/common/reference.RFC.6637.xml @@ -0,0 +1,15 @@ + + + + + +Elliptic Curve Cryptography (ECC) in OpenPGP + + + + +This document defines an Elliptic Curve Cryptography extension to the OpenPGP public key format and specifies three Elliptic Curves that enjoy broad support by other standards, including standards published by the US National Institute of Standards and Technology. The document specifies the conventions for interoperability between compliant OpenPGP implementations that make use of this extension and these Elliptic Curves. [STANDARDS-TRACK] + + + + diff --git a/misc/id/eddsa-for-openpgp/abstract.mkd b/misc/id/eddsa-for-openpgp/abstract.mkd new file mode 100644 index 0000000..570f428 --- /dev/null +++ b/misc/id/eddsa-for-openpgp/abstract.mkd @@ -0,0 +1,2 @@ +This specification extends OpenPGP with the EdDSA public key algorithm +and describes the use of curve Ed25519. diff --git a/misc/id/eddsa-for-openpgp/back.mkd b/misc/id/eddsa-for-openpgp/back.mkd new file mode 100644 index 0000000..420f564 --- /dev/null +++ b/misc/id/eddsa-for-openpgp/back.mkd @@ -0,0 +1,60 @@ +# Test vectors + +For help implementing this specification a non-normative example is +given. This example assumes that the algorithm id for EdDSA will +be 22. + + +## Sample key + +The secret key used for this example is: + + D: 1a8b1ff05ded48e18bf50166c664ab023ea70003d78d9e41f5758a91d850f8d2 + +Note that this is the raw secret key used as input to the EdDSA +signing operation. The key was created on 2014-08-19 14:28:27 and +thus the fingerprint of the OpenPGP key is: + + C959 BDBA FA32 A2F8 9A15 3B67 8CFD E121 9796 5A9A + +The algorithm specific input parameters without the MPI length headers +are: + + oid: 2b06010401da470f01 + + q: 403f098994bdd916ed4053197934e4a87c80733a1280d62f8010992e43ee3b2406 + +The entire public key packet is thus: + + 98 33 04 53 f3 5f 0b 16 09 2b 06 01 04 01 da 47 + 0f 01 01 07 40 3f 09 89 94 bd d9 16 ed 40 53 19 + 79 34 e4 a8 7c 80 73 3a 12 80 d6 2f 80 10 99 2e + 43 ee 3b 24 06 + +## Sample signature + +The signature is created using the sample key over the input data +"OpenPGP" on 2015-09-16 12:24:53 and thus the input to the hash +function is: + + m: 4f70656e504750040016080006050255f95f9504ff0000000c + +Using the SHA-256 hash algorithm yields the digest: + + d: f6220a3f757814f4c2176ffbb68b00249cd4ccdc059c4b34ad871f30b1740280 + +Which is fed into the EdDSA signature function and yields this signature: + + r: 56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed3366 + + s: d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404 + +Note the MPI encoding rules require that the value of S needs to be +prefixed with a 0x00 octet. The entire signature packet is thus: + + 88 5e 04 00 16 08 00 06 05 02 55 f9 5f 95 00 0a + 09 10 8c fd e1 21 97 96 5a 9a f6 22 01 00 56 f9 + 0c ca 98 e2 10 26 37 bd 98 3f db 16 c1 31 df d2 + 7e d8 2b f4 dd e5 60 6e 0d 75 6a ed 33 66 01 00 + d0 9c 4f a1 15 27 f0 38 e0 f5 7f 22 01 d8 2f 2e + a2 c9 03 32 65 fa 6c eb 48 9e 85 4b ae 61 b4 04 diff --git a/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-00.txt b/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-00.txt new file mode 100644 index 0000000..4b6c8a6 --- /dev/null +++ b/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-00.txt @@ -0,0 +1,392 @@ + + + + +Network Working Group W. Koch +Internet-Draft g10 Code +Intended status: Standards Track August 19, 2014 +Expires: February 20, 2015 + + + EdDSA for OpenPGP + draft-koch-eddsa-for-openpgp-00 + +Abstract + + This specification extends OpenPGP with the EdDSA public key + algorithm and describes the use of curve Ed25519. + +Status of This Memo + + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF). Note that other groups may also distribute + working documents as Internet-Drafts. The list of current Internet- + Drafts is at http://datatracker.ietf.org/drafts/current/. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + This Internet-Draft will expire on February 20, 2015. + +Copyright Notice + + Copyright (c) 2014 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + + + + + +Koch Expires February 20, 2015 [Page 1] + +Internet-Draft EdDSA for OpenPGP August 2014 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Supported Curves . . . . . . . . . . . . . . . . . . . . . . 2 + 3. Point Format . . . . . . . . . . . . . . . . . . . . . . . . 3 + 4. Encoding of Public and Private Keys . . . . . . . . . . . . . 3 + 5. Message Encoding . . . . . . . . . . . . . . . . . . . . . . 4 + 6. Curve OID . . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 7. Security Considerations . . . . . . . . . . . . . . . . . . . 4 + 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 5 + 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 5 + 10. Normative References . . . . . . . . . . . . . . . . . . . . 5 + Appendix A. Test vectors . . . . . . . . . . . . . . . . . . . . 6 + A.1. Sample key . . . . . . . . . . . . . . . . . . . . . . . 6 + A.2. Sample signature . . . . . . . . . . . . . . . . . . . . 6 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 7 + +1. Introduction + + The OpenPGP specification in [RFC4880] defines the RSA, Elgamal, and + DSA public key algorithms. [RFC6637] adds support for Elliptic Curve + Cryptography and specifies the ECDSA and ECDH algorithms. Due to + patent reasons no point compression was defined. + + This document specifies how to use the EdDSA public key signature + algorithm [ED25519] with the OpenPGP standard. It defines a new + signature algorithm named EdDSA and specifies how to use the Ed25519 + curve with EdDSA. This algorithm uses a custom point compression + method. + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. + +2. Supported Curves + + This document references the Curve "Ed25519" which is the Edwards + form of "Curve25519" and specified in the same paper as the "EdDSA" + algorithm ([ED25519]). + + Other curves may be used by using a specific OID for the curve and + its EdDSA parameters. + + The following public key algorithm IDs are added to expand section + 9.1 of [RFC4880], "Public-Key Algorithms": + + + + + + +Koch Expires February 20, 2015 [Page 2] + +Internet-Draft EdDSA for OpenPGP August 2014 + + + +-------+-----------------------------+ + | ID | Description of Algorithm | + +-------+-----------------------------+ + | TBD1 | EdDSA public key algorithm | + +-------+-----------------------------+ + + Compliant applications MUST support EdDSA with the curve Ed25519. + Applications MAY support other curves as long as a dedicated OID for + that curve is used. + +3. Point Format + + The EdDSA algorithm defines a specific point compression format. To + indicate the use of this compression format and to make sure that the + key can be represented in the Multiprecision Internet (MPI) format of + [RFC4880] the octet string specifying the point is prefixed with the + octet 0x40. This encoding is an extension of the encoding given in + [RFC6637] which uses 0x04 to indicate an uncompressed point. + + For example, the length of a public key for the curve Ed25519 is 263 + bit: 7 bit to represent the 0x40 prefix octet and 32 octets for the + native value of the public key. + +4. Encoding of Public and Private Keys + + The following algorithm specific packets are added to Section 5.5.2 + of [RFC4880], "Public-Key Packet Formats", to support EdDSA. + + Algorithm-Specific Fields for EdDSA keys: + + o a variable length field containing a curve OID, formatted as + follows: + + * a one-octet size of the following field; values 0 and 0xFF are + reserved for future extensions, + + * octets representing a curve OID, defined in Section 6. + + o MPI of an EC point representing a public key Q as described under + Point Format above. + + The following algorithm specific packets are added to Section 5.5.3 + of [RFC4880], "Secret-Key Packet Formats", to support EdDSA. + + Algorithm-Specific Fields for EdDSA keys: + + o an MPI of an integer representing the secret key, which is a + scalar of the public EC point. + + + +Koch Expires February 20, 2015 [Page 3] + +Internet-Draft EdDSA for OpenPGP August 2014 + + + The version 4 packet format MUST be used. + +5. Message Encoding + + Section 5.2.3 of [RFC4880], "Version 4 Signature Packet Format" + specifies formats. To support EdDSA no change is required, the MPIs + representing the R and S value are encoded as MPIs in the same way as + done for the DSA and ECDSA algorithms; in particular the Algorithm- + Specific Fields for an EdDSA signature are: + + - MPI of EdDSA value r. + + - MPI of EdDSA value s. + + Note that the compressed version of R and S as specified for EdDSA + ([ED25519]) is used. + + The version 3 signature format MUST NOT be used with EdDSA. + + Although that algorithm allows arbitrary data as input, its use with + OpenPGP requires that a digest of the message is used as input. See + section 5.2.4 of [RFC4880], "Computing Signatures" for details. + Truncation of the resulting digest is never applied; the resulting + digest value is used verbatim as input to the EdDSA algorithm. + +6. Curve OID + + The EdDSA key parameter curve OID is an array of octets that defines + a named curve. The table below specifies the exact sequence of bytes + for each named curve referenced in this document: + + +------------------------+------+------------------------+----------+ + | OID | Len | Encoding in hex format | Name | + +------------------------+------+------------------------+----------+ + | 1.3.6.1.4.1.11591.15.1 | 9 | 2B 06 01 04 01 DA 47 | Ed25519 | + | | | 0F 01 | | + +------------------------+------+------------------------+----------+ + + See [RFC6637] for a description of the OID encoding given in the + second and third columns. + +7. Security Considerations + + The security considerations of [RFC4880] apply accordingly. + + The use of EdDSA with the Ed25519 curve is believed to be as strong + as other curves of the same size. However, a proper implementation + of this algorithm avoids most security problems due to wrong usage. + + + +Koch Expires February 20, 2015 [Page 4] + +Internet-Draft EdDSA for OpenPGP August 2014 + + + The algorithm does not require a unique random number for each + signature created by the same key. + +8. IANA Considerations + + IANA is requested to assign an algorithm number from the OpenPGP + Public-Key Algorithms range, or the "namespace" in the terminology of + [RFC5226], that was created by [RFC4880]. See section 2. + + +-------+-----------------------------+------------+ + | ID | Algorithm | Reference | + +-------+-----------------------------+------------+ + | TBD1 | EdDSA public key algorithm | This doc | + +-------+-----------------------------+------------+ + + [Notes to RFC-Editor: Please remove the table above on publication. + It is desirable not to reuse old or reserved algorithms because some + existing tools might print a wrong description. A higher number is + also an indication for a newer algorithm. As of now 22 is the next + free number.] + +9. Acknowledgments + + The author would like to acknowledge the help of the individuals who + kindly voiced their opinions on the IETF OpenPGP and GnuPG mailing + lists, in particular, the help of Andrey Jivsov, Jon Callas, and + NIIBE Yutaka. + +10. Normative References + + [ED25519] Bernstein, D., Duif, N., Lange, T., Schwabe, P., and B. + Yang, "High-speed high-security signatures", Journal of + Cryptographic Engineering Volume 2, Issue 2, pp. 77-89, + September 2011, + . + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. + Thayer, "OpenPGP Message Format", RFC 4880, November 2007. + + [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an + IANA Considerations Section in RFCs", BCP 26, RFC 5226, + May 2008. + + [RFC6637] Jivsov, A., "Elliptic Curve Cryptography (ECC) in + OpenPGP", RFC 6637, June 2012. + + + +Koch Expires February 20, 2015 [Page 5] + +Internet-Draft EdDSA for OpenPGP August 2014 + + +Appendix A. Test vectors + + To help implementing this specification a non-normative example is + given. This example assumes that the algorithm id for EdDSA will be + 22. + +A.1. Sample key + + The secret key used for this example is: + + D: 1a8b1ff05ded48e18bf50166c664ab023ea70003d78d9e41f5758a91d850f8d2 + + Note that this is the raw secret key as used as input to the EdDSA + signing operation. The key was created on 2014-08-19 14:28:27 and + thus the fingerprint of the OpenPGP key is: + + C959 BDBA FA32 A2F8 9A15 3B67 8CFD E121 9796 5A9A + + The algorithm specific input parameters without the MPI length + headers are: + + oid: 2b06010401da470f01 + + q: 403f098994bdd916ed4053197934e4a87c80733a1280d62f8010992e43ee3b2406 + + The entire public key packet is thus + + 98 33 04 53 f3 5f 0b 16 09 2b 06 01 04 01 da 47 + 0f 01 01 07 40 3f 09 89 94 bd d9 16 ed 40 53 19 + 79 34 e4 a8 7c 80 73 3a 12 80 d6 2f 80 10 99 2e + 43 ee 3b 24 06 + +A.2. Sample signature + + The signature is created using the sample key over the input data + "OpenPGP" on 2015-09-16 12:24:53 and thus the input to the hash + function is + + m: 4f70656e504750040016080006050255f95f9504ff0000000c + + using the SHA-256 hash algorithm yields this digest + + d: f6220a3f757814f4c2176ffbb68b00249cd4ccdc059c4b34ad871f30b1740280 + + which is fed into the EdDSA signature function and yields this + signature: + + r: 56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed3366 + + + +Koch Expires February 20, 2015 [Page 6] + +Internet-Draft EdDSA for OpenPGP August 2014 + + + s: d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404 + + Note that the MPI encoding rules require that the value of S needs to + be prefixed with a 0x00 octet. The entire signature packet is thus + + 88 5e 04 00 16 08 00 06 05 02 55 f9 5f 95 00 0a + 09 10 8c fd e1 21 97 96 5a 9a f6 22 01 00 56 f9 + 0c ca 98 e2 10 26 37 bd 98 3f db 16 c1 31 df d2 + 7e d8 2b f4 dd e5 60 6e 0d 75 6a ed 33 66 01 00 + d0 9c 4f a1 15 27 f0 38 e0 f5 7f 22 01 d8 2f 2e + a2 c9 03 32 65 fa 6c eb 48 9e 85 4b ae 61 b4 04 + +Author's Address + + Werner Koch + g10 Code + + Email: wk at gnupg.org + URI: https://g10code.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Koch Expires February 20, 2015 [Page 7] diff --git a/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-01.txt b/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-01.txt new file mode 100644 index 0000000..4a690eb --- /dev/null +++ b/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-01.txt @@ -0,0 +1,392 @@ + + + + +Network Working Group W. Koch +Internet-Draft g10 Code +Updates: 4880 (if approved) September 8, 2014 +Intended status: Informational +Expires: March 12, 2015 + + + EdDSA for OpenPGP + draft-koch-eddsa-for-openpgp-01 + +Abstract + + This specification extends OpenPGP with the EdDSA public key + algorithm and describes the use of curve Ed25519. + +Status of This Memo + + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF). Note that other groups may also distribute + working documents as Internet-Drafts. The list of current Internet- + Drafts is at http://datatracker.ietf.org/drafts/current/. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + This Internet-Draft will expire on March 12, 2015. + +Copyright Notice + + Copyright (c) 2014 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + + + + +Koch Expires March 12, 2015 [Page 1] + +Internet-Draft EdDSA for OpenPGP September 2014 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Supported Curves . . . . . . . . . . . . . . . . . . . . . . 2 + 3. Point Format . . . . . . . . . . . . . . . . . . . . . . . . 3 + 4. Encoding of Public and Private Keys . . . . . . . . . . . . . 3 + 5. Message Encoding . . . . . . . . . . . . . . . . . . . . . . 4 + 6. Curve OID . . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 7. Security Considerations . . . . . . . . . . . . . . . . . . . 4 + 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 5 + 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 5 + 10. Normative References . . . . . . . . . . . . . . . . . . . . 5 + Appendix A. Test vectors . . . . . . . . . . . . . . . . . . . . 6 + A.1. Sample key . . . . . . . . . . . . . . . . . . . . . . . 6 + A.2. Sample signature . . . . . . . . . . . . . . . . . . . . 6 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 7 + +1. Introduction + + The OpenPGP specification in [RFC4880] defines the RSA, Elgamal, and + DSA public key algorithms. [RFC6637] adds support for Elliptic Curve + Cryptography and specifies the ECDSA and ECDH algorithms. Due to + patent reasons no point compression was defined. + + This document specifies how to use the EdDSA public key signature + algorithm [ED25519] with the OpenPGP standard. It defines a new + signature algorithm named EdDSA and specifies how to use the Ed25519 + curve with EdDSA. This algorithm uses a custom point compression + method. There are three main advantages of the EdDSA algorithm: It + does not require the use of a unique random number for each + signature, there are no padding or truncation issues as with ECDSA, + and it is more resilient to side-channel attacks. + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. + +2. Supported Curves + + This document references the Curve "Ed25519" which is the Edwards + form of "Curve25519" and specified in the same paper as the "EdDSA" + algorithm ([ED25519]). + + Other curves may be used by using a specific OID for the curve and + its EdDSA parameters. + + The following public key algorithm IDs are added to expand section + 9.1 of [RFC4880], "Public-Key Algorithms": + + + +Koch Expires March 12, 2015 [Page 2] + +Internet-Draft EdDSA for OpenPGP September 2014 + + + +-------+-----------------------------+ + | ID | Description of Algorithm | + +-------+-----------------------------+ + | TBD1 | EdDSA public key algorithm | + +-------+-----------------------------+ + + Compliant applications MUST support EdDSA with the curve Ed25519. + Applications MAY support other curves as long as a dedicated OID for + using that curve with EdDSA is used. + +3. Point Format + + The EdDSA algorithm defines a specific point compression format. To + indicate the use of this compression format and to make sure that the + key can be represented in the Multiprecision Internet (MPI) format of + [RFC4880] the octet string specifying the point is prefixed with the + octet 0x40. This encoding is an extension of the encoding given in + [RFC6637] which uses 0x04 to indicate an uncompressed point. + + For example, the length of a public key for the curve Ed25519 is 263 + bit: 7 bit to represent the 0x40 prefix octet and 32 octets for the + native value of the public key. + +4. Encoding of Public and Private Keys + + The following algorithm specific packets are added to Section 5.5.2 + of [RFC4880], "Public-Key Packet Formats", to support EdDSA. + + Algorithm-Specific Fields for EdDSA keys: + + o a variable length field containing a curve OID, formatted as + follows: + + * a one-octet size of the following field; values 0 and 0xFF are + reserved for future extensions, + + * octets representing a curve OID, defined in Section 6. + + o MPI of an EC point representing a public key Q as described under + Point Format above. + + The following algorithm specific packets are added to Section 5.5.3 + of [RFC4880], "Secret-Key Packet Formats", to support EdDSA. + + Algorithm-Specific Fields for EdDSA keys: + + o an MPI of an integer representing the secret key, which is a + scalar of the public EC point. + + + +Koch Expires March 12, 2015 [Page 3] + +Internet-Draft EdDSA for OpenPGP September 2014 + + + The version 4 packet format MUST be used. + +5. Message Encoding + + Section 5.2.3 of [RFC4880], "Version 4 Signature Packet Format" + specifies formats. To support EdDSA no change is required, the MPIs + representing the R and S value are encoded as MPIs in the same way as + done for the DSA and ECDSA algorithms; in particular the Algorithm- + Specific Fields for an EdDSA signature are: + + - MPI of EdDSA value r. + + - MPI of EdDSA value s. + + Note that the compressed version of R and S as specified for EdDSA + ([ED25519]) is used. + + The version 3 signature format MUST NOT be used with EdDSA. + + Although that algorithm allows arbitrary data as input, its use with + OpenPGP requires that a digest of the message is used as input. See + section 5.2.4 of [RFC4880], "Computing Signatures" for details. + Truncation of the resulting digest is never applied; the resulting + digest value is used verbatim as input to the EdDSA algorithm. + +6. Curve OID + + The EdDSA key parameter curve OID is an array of octets that defines + a named curve. The table below specifies the exact sequence of bytes + for each named curve referenced in this document: + + +------------------------+------+------------------------+----------+ + | OID | Len | Encoding in hex format | Name | + +------------------------+------+------------------------+----------+ + | 1.3.6.1.4.1.11591.15.1 | 9 | 2B 06 01 04 01 DA 47 | Ed25519 | + | | | 0F 01 | | + +------------------------+------+------------------------+----------+ + + See [RFC6637] for a description of the OID encoding given in the + second and third columns. + +7. Security Considerations + + The security considerations of [RFC4880] apply accordingly. + + Although technically possible the use of EdDSA with digest algorithms + weaker than SHA-256 (e.g. SHA-1) is not suggested. + + + + +Koch Expires March 12, 2015 [Page 4] + +Internet-Draft EdDSA for OpenPGP September 2014 + + +8. IANA Considerations + + IANA is requested to assign an algorithm number from the OpenPGP + Public-Key Algorithms range, or the "namespace" in the terminology of + [RFC5226], that was created by [RFC4880]. See section 2. + + +-------+-----------------------------+------------+ + | ID | Algorithm | Reference | + +-------+-----------------------------+------------+ + | TBD1 | EdDSA public key algorithm | This doc | + +-------+-----------------------------+------------+ + + [Notes to RFC-Editor: Please remove the table above on publication. + It is desirable not to reuse old or reserved algorithms because some + existing tools might print a wrong description. A higher number is + also an indication for a newer algorithm. As of now 22 is the next + free number.] + +9. Acknowledgments + + The author would like to acknowledge the help of the individuals who + kindly voiced their opinions on the IETF OpenPGP and GnuPG mailing + lists, in particular, the help of Andrey Jivsov, Jon Callas, and + NIIBE Yutaka. + +10. Normative References + + [ED25519] Bernstein, D., Duif, N., Lange, T., Schwabe, P., and B. + Yang, "High-speed high-security signatures", Journal of + Cryptographic Engineering Volume 2, Issue 2, pp. 77-89, + September 2011, + . + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. + Thayer, "OpenPGP Message Format", RFC 4880, November 2007. + + [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an + IANA Considerations Section in RFCs", BCP 26, RFC 5226, + May 2008. + + [RFC6637] Jivsov, A., "Elliptic Curve Cryptography (ECC) in + OpenPGP", RFC 6637, June 2012. + + + + + + +Koch Expires March 12, 2015 [Page 5] + +Internet-Draft EdDSA for OpenPGP September 2014 + + +Appendix A. Test vectors + + To help implementing this specification a non-normative example is + given. This example assumes that the algorithm id for EdDSA will be + 22. + +A.1. Sample key + + The secret key used for this example is: + + D: 1a8b1ff05ded48e18bf50166c664ab023ea70003d78d9e41f5758a91d850f8d2 + + Note that this is the raw secret key as used as input to the EdDSA + signing operation. The key was created on 2014-08-19 14:28:27 and + thus the fingerprint of the OpenPGP key is: + + C959 BDBA FA32 A2F8 9A15 3B67 8CFD E121 9796 5A9A + + The algorithm specific input parameters without the MPI length + headers are: + + oid: 2b06010401da470f01 + + q: 403f098994bdd916ed4053197934e4a87c80733a1280d62f8010992e43ee3b2406 + + The entire public key packet is thus + + 98 33 04 53 f3 5f 0b 16 09 2b 06 01 04 01 da 47 + 0f 01 01 07 40 3f 09 89 94 bd d9 16 ed 40 53 19 + 79 34 e4 a8 7c 80 73 3a 12 80 d6 2f 80 10 99 2e + 43 ee 3b 24 06 + +A.2. Sample signature + + The signature is created using the sample key over the input data + "OpenPGP" on 2015-09-16 12:24:53 and thus the input to the hash + function is + + m: 4f70656e504750040016080006050255f95f9504ff0000000c + + using the SHA-256 hash algorithm yields this digest + + d: f6220a3f757814f4c2176ffbb68b00249cd4ccdc059c4b34ad871f30b1740280 + + which is fed into the EdDSA signature function and yields this + signature: + + r: 56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed3366 + + + +Koch Expires March 12, 2015 [Page 6] + +Internet-Draft EdDSA for OpenPGP September 2014 + + + s: d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404 + + Note that the MPI encoding rules require that the value of S needs to + be prefixed with a 0x00 octet. The entire signature packet is thus + + 88 5e 04 00 16 08 00 06 05 02 55 f9 5f 95 00 0a + 09 10 8c fd e1 21 97 96 5a 9a f6 22 01 00 56 f9 + 0c ca 98 e2 10 26 37 bd 98 3f db 16 c1 31 df d2 + 7e d8 2b f4 dd e5 60 6e 0d 75 6a ed 33 66 01 00 + d0 9c 4f a1 15 27 f0 38 e0 f5 7f 22 01 d8 2f 2e + a2 c9 03 32 65 fa 6c eb 48 9e 85 4b ae 61 b4 04 + +Author's Address + + Werner Koch + g10 Code + + Email: wk at gnupg.org + URI: https://g10code.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Koch Expires March 12, 2015 [Page 7] diff --git a/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-02.txt b/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-02.txt new file mode 100644 index 0000000..8e23a71 --- /dev/null +++ b/misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-02.txt @@ -0,0 +1,392 @@ + + + + +Network Working Group W. Koch +Internet-Draft g10 Code +Updates: 4880 (if approved) March 4, 2015 +Intended status: Informational +Expires: September 5, 2015 + + + EdDSA for OpenPGP + draft-koch-eddsa-for-openpgp-02 + +Abstract + + This specification extends OpenPGP with the EdDSA public key + algorithm and describes the use of curve Ed25519. + +Status of This Memo + + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF). Note that other groups may also distribute + working documents as Internet-Drafts. The list of current Internet- + Drafts is at http://datatracker.ietf.org/drafts/current/. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + This Internet-Draft will expire on September 5, 2015. + +Copyright Notice + + Copyright (c) 2015 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + + + + +Koch Expires September 5, 2015 [Page 1] + +Internet-Draft EdDSA for OpenPGP March 2015 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Supported Curves . . . . . . . . . . . . . . . . . . . . . . 2 + 3. Point Format . . . . . . . . . . . . . . . . . . . . . . . . 3 + 4. Encoding of Public and Private Keys . . . . . . . . . . . . . 3 + 5. Message Encoding . . . . . . . . . . . . . . . . . . . . . . 4 + 6. Curve OID . . . . . . . . . . . . . . . . . . . . . . . . . . 4 + 7. Security Considerations . . . . . . . . . . . . . . . . . . . 4 + 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 5 + 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 5 + 10. Normative References . . . . . . . . . . . . . . . . . . . . 5 + Appendix A. Test vectors . . . . . . . . . . . . . . . . . . . . 6 + A.1. Sample key . . . . . . . . . . . . . . . . . . . . . . . 6 + A.2. Sample signature . . . . . . . . . . . . . . . . . . . . 6 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 7 + +1. Introduction + + The OpenPGP specification in [RFC4880] defines the RSA, Elgamal, and + DSA public key algorithms. [RFC6637] adds support for Elliptic Curve + Cryptography and specifies the ECDSA and ECDH algorithms. Due to + patent reasons no point compression was defined. + + This document specifies how to use the EdDSA public key signature + algorithm [ED25519] with the OpenPGP standard. It defines a new + signature algorithm named EdDSA and specifies how to use the Ed25519 + curve with EdDSA. This algorithm uses a custom point compression + method. There are three main advantages of the EdDSA algorithm: It + does not require the use of a unique random number for each + signature, there are no padding or truncation issues as with ECDSA, + and it is more resilient to side-channel attacks. + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. + +2. Supported Curves + + This document references the Curve "Ed25519" which is the Edwards + form of "Curve25519" and specified in the same paper as the "EdDSA" + algorithm ([ED25519]). + + Other curves may be used by using a specific OID for the curve and + its EdDSA parameters. + + The following public key algorithm IDs are added to expand section + 9.1 of [RFC4880], "Public-Key Algorithms": + + + +Koch Expires September 5, 2015 [Page 2] + +Internet-Draft EdDSA for OpenPGP March 2015 + + + +-------+-----------------------------+ + | ID | Description of Algorithm | + +-------+-----------------------------+ + | TBD1 | EdDSA public key algorithm | + +-------+-----------------------------+ + + Compliant applications MUST support EdDSA with the curve Ed25519. + Applications MAY support other curves as long as a dedicated OID for + using that curve with EdDSA is used. + +3. Point Format + + The EdDSA algorithm defines a specific point compression format. To + indicate the use of this compression format and to make sure that the + key can be represented in the Multiprecision Internet (MPI) format of + [RFC4880] the octet string specifying the point is prefixed with the + octet 0x40. This encoding is an extension of the encoding given in + [RFC6637] which uses 0x04 to indicate an uncompressed point. + + For example, the length of a public key for the curve Ed25519 is 263 + bit: 7 bit to represent the 0x40 prefix octet and 32 octets for the + native value of the public key. + +4. Encoding of Public and Private Keys + + The following algorithm specific packets are added to Section 5.5.2 + of [RFC4880], "Public-Key Packet Formats", to support EdDSA. + + Algorithm-Specific Fields for EdDSA keys: + + o a variable length field containing a curve OID, formatted as + follows: + + * a one-octet size of the following field; values 0 and 0xFF are + reserved for future extensions, + + * octets representing a curve OID, defined in Section 6. + + o MPI of an EC point representing a public key Q as described under + Point Format above. + + The following algorithm specific packets are added to Section 5.5.3 + of [RFC4880], "Secret-Key Packet Formats", to support EdDSA. + + Algorithm-Specific Fields for EdDSA keys: + + o an MPI of an integer representing the secret key, which is a + scalar of the public EC point. + + + +Koch Expires September 5, 2015 [Page 3] + +Internet-Draft EdDSA for OpenPGP March 2015 + + + The version 4 packet format MUST be used. + +5. Message Encoding + + Section 5.2.3 of [RFC4880], "Version 4 Signature Packet Format" + specifies formats. To support EdDSA no change is required, the MPIs + representing the R and S value are encoded as MPIs in the same way as + done for the DSA and ECDSA algorithms; in particular the Algorithm- + Specific Fields for an EdDSA signature are: + + - MPI of EdDSA value r. + + - MPI of EdDSA value s. + + Note that the compressed version of R and S as specified for EdDSA + ([ED25519]) is used. + + The version 3 signature format MUST NOT be used with EdDSA. + + Although that algorithm allows arbitrary data as input, its use with + OpenPGP requires that a digest of the message is used as input. See + section 5.2.4 of [RFC4880], "Computing Signatures" for details. + Truncation of the resulting digest is never applied; the resulting + digest value is used verbatim as input to the EdDSA algorithm. + +6. Curve OID + + The EdDSA key parameter curve OID is an array of octets that defines + a named curve. The table below specifies the exact sequence of bytes + for each named curve referenced in this document: + + +------------------------+------+------------------------+----------+ + | OID | Len | Encoding in hex format | Name | + +------------------------+------+------------------------+----------+ + | 1.3.6.1.4.1.11591.15.1 | 9 | 2B 06 01 04 01 DA 47 | Ed25519 | + | | | 0F 01 | | + +------------------------+------+------------------------+----------+ + + See [RFC6637] for a description of the OID encoding given in the + second and third columns. + +7. Security Considerations + + The security considerations of [RFC4880] apply accordingly. + + Although technically possible the use of EdDSA with digest algorithms + weaker than SHA-256 (e.g. SHA-1) is not suggested. + + + + +Koch Expires September 5, 2015 [Page 4] + +Internet-Draft EdDSA for OpenPGP March 2015 + + +8. IANA Considerations + + IANA is requested to assign an algorithm number from the OpenPGP + Public-Key Algorithms range, or the "namespace" in the terminology of + [RFC5226], that was created by [RFC4880]. See section 2. + + +-------+-----------------------------+------------+ + | ID | Algorithm | Reference | + +-------+-----------------------------+------------+ + | TBD1 | EdDSA public key algorithm | This doc | + +-------+-----------------------------+------------+ + + [Notes to RFC-Editor: Please remove the table above on publication. + It is desirable not to reuse old or reserved algorithms because some + existing tools might print a wrong description. A higher number is + also an indication for a newer algorithm. As of now 22 is the next + free number.] + +9. Acknowledgments + + The author would like to acknowledge the help of the individuals who + kindly voiced their opinions on the IETF OpenPGP and GnuPG mailing + lists, in particular, the help of Andrey Jivsov, Jon Callas, and + NIIBE Yutaka. + +10. Normative References + + [ED25519] Bernstein, D., Duif, N., Lange, T., Schwabe, P., and B. + Yang, "High-speed high-security signatures", Journal of + Cryptographic Engineering Volume 2, Issue 2, pp. 77-89, + September 2011, + . + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. + Thayer, "OpenPGP Message Format", RFC 4880, November 2007. + + [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an + IANA Considerations Section in RFCs", BCP 26, RFC 5226, + May 2008. + + [RFC6637] Jivsov, A., "Elliptic Curve Cryptography (ECC) in + OpenPGP", RFC 6637, June 2012. + + + + + + +Koch Expires September 5, 2015 [Page 5] + +Internet-Draft EdDSA for OpenPGP March 2015 + + +Appendix A. Test vectors + + To help implementing this specification a non-normative example is + given. This example assumes that the algorithm id for EdDSA will be + 22. + +A.1. Sample key + + The secret key used for this example is: + + D: 1a8b1ff05ded48e18bf50166c664ab023ea70003d78d9e41f5758a91d850f8d2 + + Note that this is the raw secret key as used as input to the EdDSA + signing operation. The key was created on 2014-08-19 14:28:27 and + thus the fingerprint of the OpenPGP key is: + + C959 BDBA FA32 A2F8 9A15 3B67 8CFD E121 9796 5A9A + + The algorithm specific input parameters without the MPI length + headers are: + + oid: 2b06010401da470f01 + + q: 403f098994bdd916ed4053197934e4a87c80733a1280d62f8010992e43ee3b2406 + + The entire public key packet is thus + + 98 33 04 53 f3 5f 0b 16 09 2b 06 01 04 01 da 47 + 0f 01 01 07 40 3f 09 89 94 bd d9 16 ed 40 53 19 + 79 34 e4 a8 7c 80 73 3a 12 80 d6 2f 80 10 99 2e + 43 ee 3b 24 06 + +A.2. Sample signature + + The signature is created using the sample key over the input data + "OpenPGP" on 2015-09-16 12:24:53 and thus the input to the hash + function is + + m: 4f70656e504750040016080006050255f95f9504ff0000000c + + using the SHA-256 hash algorithm yields this digest + + d: f6220a3f757814f4c2176ffbb68b00249cd4ccdc059c4b34ad871f30b1740280 + + which is fed into the EdDSA signature function and yields this + signature: + + r: 56f90cca98e2102637bd983fdb16c131dfd27ed82bf4dde5606e0d756aed3366 + + + +Koch Expires September 5, 2015 [Page 6] + +Internet-Draft EdDSA for OpenPGP March 2015 + + + s: d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404 + + Note that the MPI encoding rules require that the value of S needs to + be prefixed with a 0x00 octet. The entire signature packet is thus + + 88 5e 04 00 16 08 00 06 05 02 55 f9 5f 95 00 0a + 09 10 8c fd e1 21 97 96 5a 9a f6 22 01 00 56 f9 + 0c ca 98 e2 10 26 37 bd 98 3f db 16 c1 31 df d2 + 7e d8 2b f4 dd e5 60 6e 0d 75 6a ed 33 66 01 00 + d0 9c 4f a1 15 27 f0 38 e0 f5 7f 22 01 d8 2f 2e + a2 c9 03 32 65 fa 6c eb 48 9e 85 4b ae 61 b4 04 + +Author's Address + + Werner Koch + g10 Code + + Email: wk at gnupg.org + URI: https://g10code.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Koch Expires September 5, 2015 [Page 7] diff --git a/misc/id/eddsa-for-openpgp/middle.mkd b/misc/id/eddsa-for-openpgp/middle.mkd new file mode 100644 index 0000000..9e2de3f --- /dev/null +++ b/misc/id/eddsa-for-openpgp/middle.mkd @@ -0,0 +1,152 @@ +# Introduction + +The OpenPGP specification in [](#RFC4880) defines the RSA, Elgamal, +and DSA public key algorithms. [](#RFC6637) adds support for +Elliptic Curve Cryptography and specifies the ECDSA and ECDH +algorithms. Due to patent reasons no point compression was defined. + +This document specifies how to use the EdDSA public key signature +algorithm [](#ED25519) with the OpenPGP standard. It defines a new +signature algorithm named EdDSA and specifies how to use the Ed25519 +curve with EdDSA. This algorithm uses a custom point compression +method. There are three main advantages of the EdDSA algorithm: It +does not require the use of a unique random number for each signature, +there are no padding or truncation issues as with ECDSA, and it is +more resilient to side-channel attacks. + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [](#RFC2119). + + +# Supported Curves + +This document references the Curve "Ed25519" which is the Edwards form +of "Curve25519" and specified in the same paper as the "EdDSA" +algorithm ([](#ED25519)). + +Other curves may be used by using a specific OID for the curve and its +EdDSA parameters. + +The following public key algorithm IDs are added to expand section 9.1 +of [](#RFC4880), "Public-Key Algorithms": + + ID Description of Algorithm + -- -------------------------- + TBD1 EdDSA public key algorithm + +Compliant applications MUST support EdDSA with the curve Ed25519. +Applications MAY support other curves as long as a dedicated OID for +using that curve with EdDSA is used. + +# Point Format + +The EdDSA algorithm defines a specific point compression format. To +indicate the use of this compression format and to make sure that the +key can be represented in the Multiprecision Integer (MPI) format of +[](#RFC4880) the octet string specifying the point is prefixed with +the octet 0x40. This encoding is an extension of the encoding given +in [](#RFC6637) which uses 0x04 to indicate an uncompressed point. + +For example, the length of a public key for the curve Ed25519 is 263 +bit: 7 bit to represent the 0x40 prefix octet and 32 octets for the +native value of the public key. + +# Encoding of Public and Private Keys + +The following algorithm specific packets are added to Section 5.5.2 +of [](#RFC4880), "Public-Key Packet Formats", to support EdDSA. + +Algorithm-Specific Fields for EdDSA keys: + +- a variable length field containing a curve OID, formatted as + follows: + + - a one-octet size of the following field; values 0 and 0xFF are + reserved for future extensions, + + - octets representing a curve OID, defined in Section 6. + +- MPI of an EC point representing a public key Q as described under + Point Format above. + +The following algorithm specific packets are added to Section 5.5.3 +of [](#RFC4880), "Secret-Key Packet Formats", to support EdDSA. + +Algorithm-Specific Fields for EdDSA keys: + +- an MPI of an integer representing the secret key, which is a + scalar of the public EC point. + +The version 4 packet format MUST be used. + + +# Message Encoding + +Section 5.2.3 of [](#RFC4880), "Version 4 Signature Packet Format" +specifies formats. To support EdDSA no change is required, the MPIs +representing the R and S value are encoded as MPIs in the same way as +done for the DSA and ECDSA algorithms; in particular the +Algorithm-Specific Fields for an EdDSA signature are: + + - MPI of EdDSA value r. + + - MPI of EdDSA value s. + +Note that the compressed version of R and S as specified for EdDSA +([](#ED25519)) is used. + +The version 3 signature format MUST NOT be used with EdDSA. + +Although that algorithm allows arbitrary data as input, its use with +OpenPGP requires that a digest of the message is used as input. See +section 5.2.4 of [](#RFC4880), "Computing Signatures" for details. +Truncation of the resulting digest is never applied; the resulting +digest value is used verbatim as input to the EdDSA algorithm. + + +# Curve OID + +The EdDSA key parameter curve OID is an array of octets that defines a +named curve. The table below specifies the exact sequence of bytes +for each named curve referenced in this document: + + OID Len Encoding in hex format Name + ---------------------- --- -------------------------- ------- + 1.3.6.1.4.1.11591.15.1 9 2B 06 01 04 01 DA 47 0F 01 Ed25519 + +See [](#RFC6637) for a description of the OID encoding given in the +second and third columns. + + +# Security Considerations + +The security considerations of [](#RFC4880) apply accordingly. + +Although technically possible the use of EdDSA with digest algorithms +weaker than SHA-256 (e.g. SHA-1) is not suggested. + + +# IANA Considerations + +IANA is requested to assign an algorithm number from the OpenPGP +Public-Key Algorithms range, or the "namespace" in the terminology of +[](#RFC5226), that was created by [](#RFC4880). See section 2. + + ID Algorithm Reference + -- -------------------------- --------- + TBD1 EdDSA public key algorithm This doc + + [Notes to RFC-Editor: Please remove the table above on publication. + It is desirable not to reuse old or reserved algorithms because + some existing tools might print a wrong description. A higher + number is also an indication for a newer algorithm. As of now + 22 is the next free number.] + + +# Acknowledgments + +The author would like to acknowledge the help of the individuals who +kindly voiced their opinions on the IETF OpenPGP and GnuPG mailing +lists, in particular, the help of Andrey Jivsov, Jon Callas, and NIIBE +Yutaka. diff --git a/misc/id/eddsa-for-openpgp/template.xml b/misc/id/eddsa-for-openpgp/template.xml new file mode 100644 index 0000000..85bb532 --- /dev/null +++ b/misc/id/eddsa-for-openpgp/template.xml @@ -0,0 +1,57 @@ + + + + + + + + + + +]> + + + + + + + + + + + + EdDSA for OpenPGP + + g10 Code +
    + wk at gnupg.org + https://g10code.com +
    +
    + + + Security + + + &pandocAbstract; + +
    + + + &pandocMiddle; + + + + + &ed25519; + &rfc.4880; + &rfc.6637; + &rfc.5226; + &rfc.2119; + + &pandocBack; + +
    ----------------------------------------------------------------------- Summary of changes: .gitignore | 1 + misc/id/common/reference.ED25519.xml | 27 ++ misc/id/common/reference.RFC.2119.xml | 44 +++ misc/id/common/reference.RFC.2434.xml | 58 +++ misc/id/common/reference.RFC.4880.xml | 23 ++ misc/id/common/reference.RFC.5226.xml | 18 + misc/id/common/reference.RFC.6637.xml | 15 + misc/id/eddsa-for-openpgp/abstract.mkd | 2 + misc/id/eddsa-for-openpgp/back.mkd | 60 ++++ .../draft-koch-eddsa-for-openpgp-00.txt | 392 +++++++++++++++++++++ .../draft-koch-eddsa-for-openpgp-01.txt | 392 +++++++++++++++++++++ .../draft-koch-eddsa-for-openpgp-02.txt | 392 +++++++++++++++++++++ misc/id/eddsa-for-openpgp/middle.mkd | 152 ++++++++ misc/id/eddsa-for-openpgp/template.xml | 57 +++ 14 files changed, 1633 insertions(+) create mode 100644 misc/id/common/reference.ED25519.xml create mode 100644 misc/id/common/reference.RFC.2119.xml create mode 100644 misc/id/common/reference.RFC.2434.xml create mode 100644 misc/id/common/reference.RFC.4880.xml create mode 100644 misc/id/common/reference.RFC.5226.xml create mode 100644 misc/id/common/reference.RFC.6637.xml create mode 100644 misc/id/eddsa-for-openpgp/abstract.mkd create mode 100644 misc/id/eddsa-for-openpgp/back.mkd create mode 100644 misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-00.txt create mode 100644 misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-01.txt create mode 100644 misc/id/eddsa-for-openpgp/draft-koch-eddsa-for-openpgp-02.txt create mode 100644 misc/id/eddsa-for-openpgp/middle.mkd create mode 100644 misc/id/eddsa-for-openpgp/template.xml hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 12 13:05:28 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 12 Mar 2015 13:05:28 +0100 Subject: [git] GnuPG - branch, neal/strsplit, created. gnupg-2.1.2-27-gba01f9a 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, neal/strsplit has been created at ba01f9aaa5a4f92cb1a27cefac3f7ae32b824759 (commit) - Log ----------------------------------------------------------------- commit ba01f9aaa5a4f92cb1a27cefac3f7ae32b824759 Author: Neal H. Walfield Date: Thu Mar 12 13:03:50 2015 +0100 common: Add new helper function, strsplit. * common/stringhelp.h (strsplit): New declaration. * common/stringhelp.c (strsplit): New function. * common/t-stringhelp.c (test_strsplit): New function. (main): Call it here. -- diff --git a/common/stringhelp.c b/common/stringhelp.c index 42e1bcb..6bb5929 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -2,6 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, * 2008, 2009, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch + * Copyright (C) 2015 g10 Code GmbH * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -1196,3 +1197,39 @@ xstrconcat (const char *s1, ...) } return result; } + +/* Split a string into fields at DELIM. REPLACEMENT is the character + to replace the delimiter with (normally: '\0' so that each field is + NUL terminated). The caller is responsible for freeing the result. + Note: this function modifies STRING! If you need the original + value, then you should pass a copy to this function. + + If malloc fails, this function returns NULL. */ +char ** +strsplit (char *string, char delim, char replacement, int *count) +{ + int fields = 1; + char *t; + char **result; + + /* First, count the number of fields. */ + for (t = strchr (string, delim); t; t = strchr (t + 1, delim)) + fields ++; + + result = malloc (sizeof (*result) * (fields + 1)); + if (!result) + return NULL; + + result[0] = string; + fields = 1; + for (t = strchr (string, delim); t; t = strchr (t + 1, delim)) + { + result[fields ++] = t + 1; + *t = replacement; + } + + if (count) + *count = fields; + + return result; +} diff --git a/common/stringhelp.h b/common/stringhelp.h index ffef2d5..864a689 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -1,6 +1,7 @@ /* stringhelp.h * Copyright (C) 1998, 1999, 2000, 2001, 2003, * 2006, 2007, 2009 Free Software Foundation, Inc. + * 2015 g10 Code GmbH * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -142,9 +143,9 @@ char *strconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0); /* Ditto, but die on error. */ char *xstrconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0); +char **strsplit (char *string, char delim, char replacement, int *count); /*-- mapstrings.c --*/ const char *map_static_macro_string (const char *string); - #endif /*LIBJNLIB_STRINGHELP_H*/ diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c index dcd5a45..f5b6cd9 100644 --- a/common/t-stringhelp.c +++ b/common/t-stringhelp.c @@ -1,5 +1,6 @@ /* t-stringhelp.c - Regression tests for stringhelp.c * Copyright (C) 2007 Free Software Foundation, Inc. + * 2015 g10 Code GmbH * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -478,6 +479,62 @@ test_make_absfilename_try (void) xfree (cwd); } +static void +test_strsplit (void) +{ + int test_count = 0; + void test (const char *s, char delim, char replacement, + const char *fields_expected[]) + { + char *s2; + int field_count; + char **fields; + int field_count_expected; + int i; + + /* Count the fields. */ + for (field_count_expected = 0; + fields_expected[field_count_expected]; + field_count_expected ++) + ; + + test_count ++; + + /* We need to copy s since strsplit modifies it in place. */ + s2 = xstrdup (s); + fields = strsplit (s2, delim, replacement, &field_count); + + if (field_count != field_count_expected) + fail (test_count * 1000); + + for (i = 0; i < field_count_expected; i ++) + if (strcmp (fields_expected[i], fields[i]) != 0) + { + printf ("For field %d, expected '%s', but got '%s'\n", + i, fields_expected[i], fields[i]); + fail (test_count * 1000 + i + 1); + } + + xfree (s2); + } + + { + const char *expected_result[] = + { "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL }; + test ("a:bc:cde:fghi:jklmn::foo:", ':', '\0', expected_result); + } + + { + const char *expected_result[] = + { "!a!bc!!def!", "a!bc!!def!", "bc!!def!", "!def!", "def!", "", NULL }; + test (",a,bc,,def,", ',', '!', expected_result); + } + + { + const char *expected_result[] = { "", NULL }; + test ("", ':', ',', expected_result); + } +} int main (int argc, char **argv) @@ -491,6 +548,7 @@ main (int argc, char **argv) test_xstrconcat (); test_make_filename_try (); test_make_absfilename_try (); + test_strsplit (); xfree (home_buffer); return 0; ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 12 13:55:50 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 12 Mar 2015 13:55:50 +0100 Subject: [git] GnuPG - branch, neal/strsplit, updated. gnupg-2.1.2-28-gba2f59e 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, neal/strsplit has been updated discards ba01f9aaa5a4f92cb1a27cefac3f7ae32b824759 (commit) via ba2f59e3936c4d7bbb81f0f827c1552fa673faae (commit) via e40636fefa7f9ded8216e3e55606ffc5c34cbce6 (commit) This update added new revisions after undoing existing revisions. That is to say, the old revision is not a strict subset of the new revision. This situation occurs when you --force push a change and generate a repository containing something like this: * -- * -- B -- O -- O -- O (ba01f9aaa5a4f92cb1a27cefac3f7ae32b824759) \ N -- N -- N (ba2f59e3936c4d7bbb81f0f827c1552fa673faae) When this happens we assume that you've already had alert emails for all of the O revisions, and so we here report only the revisions in the N branch from the common base, B. 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 ba2f59e3936c4d7bbb81f0f827c1552fa673faae Author: Neal H. Walfield Date: Thu Mar 12 13:45:27 2015 +0100 common:stringhelp.c: Replace use of jblib_malloc with xmalloc. -- diff --git a/common/stringhelp.c b/common/stringhelp.c index 61386cc..7f40c7f 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -160,7 +160,7 @@ ascii_memistr ( const void *buffer, size_t buflen, const char *sub ) /* This function is similar to strncpy(). However it won't copy more than N - 1 characters and makes sure that a '\0' is appended. With N given as 0, nothing will happen. With DEST given as NULL, memory - will be allocated using jnlib_xmalloc (i.e. if it runs out of core + will be allocated using xmalloc (i.e. if it runs out of core the function terminates). Returns DES or a pointer to the allocated memory. */ @@ -172,7 +172,7 @@ mem2str( char *dest , const void *src , size_t n ) if( n ) { if( !dest ) - dest = jnlib_xmalloc( n ) ; + dest = xmalloc( n ) ; d = dest; s = src ; for(n--; n && *s; n-- ) @@ -320,10 +320,10 @@ make_basename(const char *filepath, const char *inputpath) if ( !(p=strrchr(filepath, ':')) ) #endif { - return jnlib_xstrdup(filepath); + return xstrdup(filepath); } - return jnlib_xstrdup(p+1); + return xstrdup(p+1); #endif } @@ -349,11 +349,11 @@ make_dirname(const char *filepath) if ( !(p=strrchr(filepath, ':')) ) #endif { - return jnlib_xstrdup("."); + return xstrdup("."); } dirname_length = p-filepath; - dirname = jnlib_xmalloc(dirname_length+1); + dirname = xmalloc(dirname_length+1); strncpy(dirname, filepath, dirname_length); dirname[dirname_length] = 0; @@ -386,9 +386,9 @@ get_pwdir (int xmode, const char *name) if (pwd) { if (xmode) - result = jnlib_xstrdup (pwd->pw_dir); + result = xstrdup (pwd->pw_dir); else - result = jnlib_strdup (pwd->pw_dir); + result = xtrystrdup (pwd->pw_dir); } #else /*!HAVE_PWD_H*/ /* No support at all. */ @@ -452,10 +452,10 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) char *user; if (xmode) - user = jnlib_xstrdup (first_part+1); + user = xstrdup (first_part+1); else { - user = jnlib_strdup (first_part+1); + user = xtrystrdup (first_part+1); if (!user) return NULL; } @@ -465,7 +465,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) skip = 1 + strlen (user); home = home_buffer = get_pwdir (xmode, user); - jnlib_free (user); + xfree (user); if (home) n += strlen (home); else @@ -474,13 +474,13 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) } if (xmode) - name = jnlib_xmalloc (n); + name = xmalloc (n); else { - name = jnlib_malloc (n); + name = xtrymalloc (n); if (!name) { - jnlib_free (home_buffer); + xfree (home_buffer); return NULL; } } @@ -490,7 +490,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) else p = stpcpy (name, first_part); - jnlib_free (home_buffer); + xfree (home_buffer); for (argc=0; argv[argc]; argc++) p = stpcpy (stpcpy (p, "/"), argv[argc]); @@ -520,18 +520,18 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) strerror (errno)); exit(2); } - jnlib_free (name); + xfree (name); return NULL; } n = strlen (home) + 1 + strlen (name) + 1; if (xmode) - home_buffer = jnlib_xmalloc (n); + home_buffer = xmalloc (n); else { - home_buffer = jnlib_malloc (n); + home_buffer = xtrymalloc (n); if (!home_buffer) { - jnlib_free (name); + xfree (name); return NULL; } } @@ -543,7 +543,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) p = home_buffer + (p - name + 1); } strcpy (stpcpy (stpcpy (p, home), "/"), name); - jnlib_free (name); + xfree (name); name = home_buffer; /* Let's do a simple compression to catch the most common case of using "." for gpg's --homedir option. */ @@ -701,7 +701,7 @@ sanitize_buffer (const void *p_arg, size_t n, int delim) p = save_p; n = save_n; /* And now make the string */ - d = buffer = jnlib_xmalloc( buflen ); + d = buffer = xmalloc( buflen ); for ( ; n; n--, p++ ) { if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) { @@ -1064,10 +1064,10 @@ do_percent_escape (const char *str, const char *extra, int die) if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i]))) j++; if (die) - ptr = jnlib_xmalloc (i + 2 * j + 1); + ptr = xmalloc (i + 2 * j + 1); else { - ptr = jnlib_malloc (i + 2 * j + 1); + ptr = xtrymalloc (i + 2 * j + 1); if (!ptr) return NULL; } @@ -1142,7 +1142,7 @@ do_strconcat (const char *s1, va_list arg_ptr) argc++; } needed++; - buffer = jnlib_malloc (needed); + buffer = xtrymalloc (needed); if (buffer) { for (p = buffer, argc=0; argv[argc]; argc++) @@ -1162,7 +1162,7 @@ strconcat (const char *s1, ...) char *result; if (!s1) - result = jnlib_strdup (""); + result = xtrystrdup (""); else { va_start (arg_ptr, s1); @@ -1181,7 +1181,7 @@ xstrconcat (const char *s1, ...) char *result; if (!s1) - result = jnlib_xstrdup (""); + result = xstrdup (""); else { va_start (arg_ptr, s1); commit e40636fefa7f9ded8216e3e55606ffc5c34cbce6 Author: Neal H. Walfield Date: Thu Mar 12 13:03:50 2015 +0100 common: Add new helper function, strsplit. * common/stringhelp.h (strsplit): New declaration. * common/stringhelp.c (strsplit): New function. * common/t-stringhelp.c (test_strsplit): New function. (main): Call it here. -- diff --git a/common/stringhelp.c b/common/stringhelp.c index 42e1bcb..61386cc 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -2,6 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, * 2008, 2009, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch + * Copyright (C) 2015 g10 Code GmbH * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -48,6 +49,7 @@ # include #endif +#include "util.h" #include "libjnlib-config.h" #include "utf8conv.h" #include "sysutils.h" @@ -1196,3 +1198,39 @@ xstrconcat (const char *s1, ...) } return result; } + +/* Split a string into fields at DELIM. REPLACEMENT is the character + to replace the delimiter with (normally: '\0' so that each field is + NUL terminated). The caller is responsible for freeing the result. + Note: this function modifies STRING! If you need the original + value, then you should pass a copy to this function. + + If malloc fails, this function returns NULL. */ +char ** +strsplit (char *string, char delim, char replacement, int *count) +{ + int fields = 1; + char *t; + char **result; + + /* First, count the number of fields. */ + for (t = strchr (string, delim); t; t = strchr (t + 1, delim)) + fields ++; + + result = xtrycalloc (sizeof (*result), (fields + 1)); + if (! result) + return NULL; + + result[0] = string; + fields = 1; + for (t = strchr (string, delim); t; t = strchr (t + 1, delim)) + { + result[fields ++] = t + 1; + *t = replacement; + } + + if (count) + *count = fields; + + return result; +} diff --git a/common/stringhelp.h b/common/stringhelp.h index ffef2d5..864a689 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -1,6 +1,7 @@ /* stringhelp.h * Copyright (C) 1998, 1999, 2000, 2001, 2003, * 2006, 2007, 2009 Free Software Foundation, Inc. + * 2015 g10 Code GmbH * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -142,9 +143,9 @@ char *strconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0); /* Ditto, but die on error. */ char *xstrconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0); +char **strsplit (char *string, char delim, char replacement, int *count); /*-- mapstrings.c --*/ const char *map_static_macro_string (const char *string); - #endif /*LIBJNLIB_STRINGHELP_H*/ diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c index dcd5a45..f5b6cd9 100644 --- a/common/t-stringhelp.c +++ b/common/t-stringhelp.c @@ -1,5 +1,6 @@ /* t-stringhelp.c - Regression tests for stringhelp.c * Copyright (C) 2007 Free Software Foundation, Inc. + * 2015 g10 Code GmbH * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -478,6 +479,62 @@ test_make_absfilename_try (void) xfree (cwd); } +static void +test_strsplit (void) +{ + int test_count = 0; + void test (const char *s, char delim, char replacement, + const char *fields_expected[]) + { + char *s2; + int field_count; + char **fields; + int field_count_expected; + int i; + + /* Count the fields. */ + for (field_count_expected = 0; + fields_expected[field_count_expected]; + field_count_expected ++) + ; + + test_count ++; + + /* We need to copy s since strsplit modifies it in place. */ + s2 = xstrdup (s); + fields = strsplit (s2, delim, replacement, &field_count); + + if (field_count != field_count_expected) + fail (test_count * 1000); + + for (i = 0; i < field_count_expected; i ++) + if (strcmp (fields_expected[i], fields[i]) != 0) + { + printf ("For field %d, expected '%s', but got '%s'\n", + i, fields_expected[i], fields[i]); + fail (test_count * 1000 + i + 1); + } + + xfree (s2); + } + + { + const char *expected_result[] = + { "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL }; + test ("a:bc:cde:fghi:jklmn::foo:", ':', '\0', expected_result); + } + + { + const char *expected_result[] = + { "!a!bc!!def!", "a!bc!!def!", "bc!!def!", "!def!", "def!", "", NULL }; + test (",a,bc,,def,", ',', '!', expected_result); + } + + { + const char *expected_result[] = { "", NULL }; + test ("", ':', ',', expected_result); + } +} int main (int argc, char **argv) @@ -491,6 +548,7 @@ main (int argc, char **argv) test_xstrconcat (); test_make_filename_try (); test_make_absfilename_try (); + test_strsplit (); xfree (home_buffer); return 0; ----------------------------------------------------------------------- Summary of changes: common/stringhelp.c | 57 +++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 12 20:23:48 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 12 Mar 2015 20:23:48 +0100 Subject: [git] GnuPG - branch, neal/strsplit, updated. gnupg-2.1.2-28-g04c84a4 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, neal/strsplit has been updated discards ba2f59e3936c4d7bbb81f0f827c1552fa673faae (commit) via 04c84a42db517df5a890fff3f7a097aeff99bbcf (commit) This update added new revisions after undoing existing revisions. That is to say, the old revision is not a strict subset of the new revision. This situation occurs when you --force push a change and generate a repository containing something like this: * -- * -- B -- O -- O -- O (ba2f59e3936c4d7bbb81f0f827c1552fa673faae) \ N -- N -- N (04c84a42db517df5a890fff3f7a097aeff99bbcf) When this happens we assume that you've already had alert emails for all of the O revisions, and so we here report only the revisions in the N branch from the common base, B. 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 04c84a42db517df5a890fff3f7a097aeff99bbcf Author: Neal H. Walfield Date: Thu Mar 12 13:45:27 2015 +0100 common:stringhelp.c: Replace use of jblib_malloc with xtrymalloc, etc. -- diff --git a/common/stringhelp.c b/common/stringhelp.c index 61386cc..7f40c7f 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -160,7 +160,7 @@ ascii_memistr ( const void *buffer, size_t buflen, const char *sub ) /* This function is similar to strncpy(). However it won't copy more than N - 1 characters and makes sure that a '\0' is appended. With N given as 0, nothing will happen. With DEST given as NULL, memory - will be allocated using jnlib_xmalloc (i.e. if it runs out of core + will be allocated using xmalloc (i.e. if it runs out of core the function terminates). Returns DES or a pointer to the allocated memory. */ @@ -172,7 +172,7 @@ mem2str( char *dest , const void *src , size_t n ) if( n ) { if( !dest ) - dest = jnlib_xmalloc( n ) ; + dest = xmalloc( n ) ; d = dest; s = src ; for(n--; n && *s; n-- ) @@ -320,10 +320,10 @@ make_basename(const char *filepath, const char *inputpath) if ( !(p=strrchr(filepath, ':')) ) #endif { - return jnlib_xstrdup(filepath); + return xstrdup(filepath); } - return jnlib_xstrdup(p+1); + return xstrdup(p+1); #endif } @@ -349,11 +349,11 @@ make_dirname(const char *filepath) if ( !(p=strrchr(filepath, ':')) ) #endif { - return jnlib_xstrdup("."); + return xstrdup("."); } dirname_length = p-filepath; - dirname = jnlib_xmalloc(dirname_length+1); + dirname = xmalloc(dirname_length+1); strncpy(dirname, filepath, dirname_length); dirname[dirname_length] = 0; @@ -386,9 +386,9 @@ get_pwdir (int xmode, const char *name) if (pwd) { if (xmode) - result = jnlib_xstrdup (pwd->pw_dir); + result = xstrdup (pwd->pw_dir); else - result = jnlib_strdup (pwd->pw_dir); + result = xtrystrdup (pwd->pw_dir); } #else /*!HAVE_PWD_H*/ /* No support at all. */ @@ -452,10 +452,10 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) char *user; if (xmode) - user = jnlib_xstrdup (first_part+1); + user = xstrdup (first_part+1); else { - user = jnlib_strdup (first_part+1); + user = xtrystrdup (first_part+1); if (!user) return NULL; } @@ -465,7 +465,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) skip = 1 + strlen (user); home = home_buffer = get_pwdir (xmode, user); - jnlib_free (user); + xfree (user); if (home) n += strlen (home); else @@ -474,13 +474,13 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) } if (xmode) - name = jnlib_xmalloc (n); + name = xmalloc (n); else { - name = jnlib_malloc (n); + name = xtrymalloc (n); if (!name) { - jnlib_free (home_buffer); + xfree (home_buffer); return NULL; } } @@ -490,7 +490,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) else p = stpcpy (name, first_part); - jnlib_free (home_buffer); + xfree (home_buffer); for (argc=0; argv[argc]; argc++) p = stpcpy (stpcpy (p, "/"), argv[argc]); @@ -520,18 +520,18 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) strerror (errno)); exit(2); } - jnlib_free (name); + xfree (name); return NULL; } n = strlen (home) + 1 + strlen (name) + 1; if (xmode) - home_buffer = jnlib_xmalloc (n); + home_buffer = xmalloc (n); else { - home_buffer = jnlib_malloc (n); + home_buffer = xtrymalloc (n); if (!home_buffer) { - jnlib_free (name); + xfree (name); return NULL; } } @@ -543,7 +543,7 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) p = home_buffer + (p - name + 1); } strcpy (stpcpy (stpcpy (p, home), "/"), name); - jnlib_free (name); + xfree (name); name = home_buffer; /* Let's do a simple compression to catch the most common case of using "." for gpg's --homedir option. */ @@ -701,7 +701,7 @@ sanitize_buffer (const void *p_arg, size_t n, int delim) p = save_p; n = save_n; /* And now make the string */ - d = buffer = jnlib_xmalloc( buflen ); + d = buffer = xmalloc( buflen ); for ( ; n; n--, p++ ) { if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) { @@ -1064,10 +1064,10 @@ do_percent_escape (const char *str, const char *extra, int die) if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i]))) j++; if (die) - ptr = jnlib_xmalloc (i + 2 * j + 1); + ptr = xmalloc (i + 2 * j + 1); else { - ptr = jnlib_malloc (i + 2 * j + 1); + ptr = xtrymalloc (i + 2 * j + 1); if (!ptr) return NULL; } @@ -1142,7 +1142,7 @@ do_strconcat (const char *s1, va_list arg_ptr) argc++; } needed++; - buffer = jnlib_malloc (needed); + buffer = xtrymalloc (needed); if (buffer) { for (p = buffer, argc=0; argv[argc]; argc++) @@ -1162,7 +1162,7 @@ strconcat (const char *s1, ...) char *result; if (!s1) - result = jnlib_strdup (""); + result = xtrystrdup (""); else { va_start (arg_ptr, s1); @@ -1181,7 +1181,7 @@ xstrconcat (const char *s1, ...) char *result; if (!s1) - result = jnlib_xstrdup (""); + result = xstrdup (""); else { va_start (arg_ptr, s1); ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 13 14:24:24 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Fri, 13 Mar 2015 14:24:24 +0100 Subject: [git] GnuPG - branch, neal/dirmngr-ldap, created. gnupg-2.1.2-32-gc0f9efb 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, neal/dirmngr-ldap has been created at c0f9efbd0d2ec58ad5cd5f5de4de80359f401633 (commit) - Log ----------------------------------------------------------------- commit c0f9efbd0d2ec58ad5cd5f5de4de80359f401633 Author: Neal H. Walfield Date: Fri Mar 13 14:24:04 2015 +0100 Add new function ldap_uri_p. * dirmngr/ldap-parse-uri.h (ldap_uri_p): New declaration. * dirmngr/ldap-parse-uri.c (ldap_uri_p): New function. * dirmngr/t-ldap-parse-uri.c (test_ldap_uri_p): New function. (main): Call it. -- diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c index 448d3be..c34f5ef 100644 --- a/dirmngr/ldap-parse-uri.c +++ b/dirmngr/ldap-parse-uri.c @@ -30,6 +30,37 @@ #include "util.h" #include "http.h" +/* Returns 1 if the string is an LDAP URL (begins with ldap:, ldaps: + or ldapi:). */ +int +ldap_uri_p (const char *url) +{ + char *colon = strchr (url, ':'); + if (! colon) + return 0; + else + { + int offset = (uintptr_t) colon - (uintptr_t) url; + + if (/* All lower case. */ + (offset == 4 && memcmp (url, "ldap", 4) == 0) + || (offset == 5 + && (memcmp (url, "ldaps", 5) == 0 + && memcmp (url, "ldapi", 5) == 0)) + /* Mixed case. */ + || ((url[0] == 'l' || url[0] == 'L') + && (url[1] == 'd' || url[1] == 'D') + && (url[2] == 'a' || url[2] == 'A') + && (url[3] == 'p' || url[3] == 'P') + && (url[4] == ':' + || ((url[4] == 's' || url[4] == 'S' + || url[4] == 'i' || url[4] == 'i') + && url[5] == ':')))) + return 1; + return 0; + } +} + /* Parse a URI and put the result into *purip. On success the caller must use http_release_parsed_uri() to releases the resources. diff --git a/dirmngr/ldap-parse-uri.h b/dirmngr/ldap-parse-uri.h index 1459c4f..c5b3d84 100644 --- a/dirmngr/ldap-parse-uri.h +++ b/dirmngr/ldap-parse-uri.h @@ -23,6 +23,8 @@ #include "util.h" #include "http.h" +extern int ldap_uri_p (const char *url); + extern gpg_error_t ldap_parse_uri (parsed_uri_t *ret_uri, const char *uri); #endif diff --git a/dirmngr/t-ldap-parse-uri.c b/dirmngr/t-ldap-parse-uri.c index e6fc4f2..829c326 100644 --- a/dirmngr/t-ldap-parse-uri.c +++ b/dirmngr/t-ldap-parse-uri.c @@ -24,6 +24,60 @@ #include "t-support.h" static void +test_ldap_uri_p (void) +{ + struct test + { + const char *uri; + int result; + }; + + struct test tests[] = { + { "ldap://foo", 1 }, + { "ldap://", 1 }, + { "ldap:", 1 }, + { "ldap", 0 }, + { "ldapfoobar", 0 }, + + { "ldaps://foo", 1 }, + { "ldaps://", 1 }, + { "ldaps:", 1 }, + { "ldaps", 0 }, + { "ldapsfoobar", 0 }, + + { "ldapi://foo", 1 }, + { "ldapi://", 1 }, + { "ldapi:", 1 }, + { "ldapi", 0 }, + { "ldapifoobar", 0 }, + + { "LDAP://FOO", 1 }, + { "LDAP://", 1 }, + { "LDAP:", 1 }, + { "LDAP", 0 }, + { "LDAPFOOBAR", 0 } + }; + + int test_count; + + void check (struct test *test) + { + int result = ldap_uri_p (test->uri); + if (result != test->result) + { + printf ("'%s' is %san LDAP schema, but ldap_uri_p says opposite.\n", + test->uri, test->result ? "" : "not "); + fail(1000 * test_count); + } + } + + for (test_count = 1; + test_count <= sizeof (tests) / sizeof (tests[0]); + test_count ++) + check (&tests[test_count - 1]); +} + +static void test_ldap_parse_uri (void) { struct test @@ -156,6 +210,7 @@ main (int argc, char **argv) (void)argc; (void)argv; + test_ldap_uri_p (); test_ldap_parse_uri (); return 0; commit f224ee7d7725d94d5528aeffd90ee33fb578fcdd Author: Neal H. Walfield Date: Fri Mar 13 13:44:18 2015 +0100 Move copy_stream function so it is more generally available. * dirmngr/ks-action.c (copy_stream): Move function from here... * dirmngr/misc.c (copy_stream): ... to here and drop the static qualifier. * dirmngr/misc.h (copy_stream): Add declaration. -- diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index e4cd8f1..8e2f520 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -31,25 +31,6 @@ #include "ks-action.h" -/* Copy all data from IN to OUT. */ -static gpg_error_t -copy_stream (estream_t in, estream_t out) -{ - char buffer[512]; - size_t nread; - - while (!es_read (in, buffer, sizeof buffer, &nread)) - { - if (!nread) - return 0; /* EOF */ - if (es_write (out, buffer, nread, NULL)) - break; - - } - return gpg_error_from_syserror (); -} - - /* Called by the engine's help functions to print the actual help. */ gpg_error_t ks_print_help (ctrl_t ctrl, const char *text) diff --git a/dirmngr/misc.c b/dirmngr/misc.c index 53d0099..93f051c 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -619,3 +619,21 @@ armor_data (char **r_string, const void *data, size_t datalen) *r_string = buffer; return 0; } + +/* Copy all data from IN to OUT. */ +gpg_error_t +copy_stream (estream_t in, estream_t out) +{ + char buffer[512]; + size_t nread; + + while (!es_read (in, buffer, sizeof buffer, &nread)) + { + if (!nread) + return 0; /* EOF */ + if (es_write (out, buffer, nread, NULL)) + break; + + } + return gpg_error_from_syserror (); +} diff --git a/dirmngr/misc.h b/dirmngr/misc.h index e98b791..d8c53d3 100644 --- a/dirmngr/misc.h +++ b/dirmngr/misc.h @@ -85,5 +85,7 @@ gpg_error_t create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp); responsible for freeing *R_STRING. */ gpg_error_t armor_data (char **r_string, const void *data, size_t datalen); +/* Copy all data from IN to OUT. */ +gpg_error_t copy_stream (estream_t in, estream_t out); #endif /* MISC_H */ commit 4753f38aef6d46181b9bb98f5f23d17447423871 Author: Neal H. Walfield Date: Fri Mar 13 13:42:00 2015 +0100 Move armor_data to misc.c. * dirmngr/ks-engine-hkp.c (armor_data): Move function from here... * dirmngr/misc.c (armor_data): ... to here and drop static qualifier. * dirmngr/misc.h: New declaration. -- diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index ea607cb..79313ec 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1103,64 +1103,6 @@ handle_send_request_error (gpg_error_t err, const char *request, return retry; } -static gpg_error_t -armor_data (char **r_string, const void *data, size_t datalen) -{ - gpg_error_t err; - struct b64state b64state; - estream_t fp; - long length; - char *buffer; - size_t nread; - - *r_string = NULL; - - fp = es_fopenmem (0, "rw,samethread"); - if (!fp) - return gpg_error_from_syserror (); - - if ((err=b64enc_start_es (&b64state, fp, "PGP PUBLIC KEY BLOCK")) - || (err=b64enc_write (&b64state, data, datalen)) - || (err = b64enc_finish (&b64state))) - { - es_fclose (fp); - return err; - } - - /* FIXME: To avoid the extra buffer allocation estream should - provide a function to snatch the internal allocated memory from - such a memory stream. */ - length = es_ftell (fp); - if (length < 0) - { - err = gpg_error_from_syserror (); - es_fclose (fp); - return err; - } - - buffer = xtrymalloc (length+1); - if (!buffer) - { - err = gpg_error_from_syserror (); - es_fclose (fp); - return err; - } - - es_rewind (fp); - if (es_read (fp, buffer, length, &nread)) - { - err = gpg_error_from_syserror (); - es_fclose (fp); - return err; - } - buffer[nread] = 0; - es_fclose (fp); - - *r_string = buffer; - return 0; -} - - /* Search the keyserver identified by URI for keys matching PATTERN. On success R_FP has an open stream to read the data. */ diff --git a/dirmngr/misc.c b/dirmngr/misc.c index 25652a2..53d0099 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -562,3 +562,60 @@ create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp) *r_reader = reader; return 0; } + +gpg_error_t +armor_data (char **r_string, const void *data, size_t datalen) +{ + gpg_error_t err; + struct b64state b64state; + estream_t fp; + long length; + char *buffer; + size_t nread; + + *r_string = NULL; + + fp = es_fopenmem (0, "rw,samethread"); + if (!fp) + return gpg_error_from_syserror (); + + if ((err=b64enc_start_es (&b64state, fp, "PGP PUBLIC KEY BLOCK")) + || (err=b64enc_write (&b64state, data, datalen)) + || (err = b64enc_finish (&b64state))) + { + es_fclose (fp); + return err; + } + + /* FIXME: To avoid the extra buffer allocation estream should + provide a function to snatch the internal allocated memory from + such a memory stream. */ + length = es_ftell (fp); + if (length < 0) + { + err = gpg_error_from_syserror (); + es_fclose (fp); + return err; + } + + buffer = xtrymalloc (length+1); + if (!buffer) + { + err = gpg_error_from_syserror (); + es_fclose (fp); + return err; + } + + es_rewind (fp); + if (es_read (fp, buffer, length, &nread)) + { + err = gpg_error_from_syserror (); + es_fclose (fp); + return err; + } + buffer[nread] = 0; + es_fclose (fp); + + *r_string = buffer; + return 0; +} diff --git a/dirmngr/misc.h b/dirmngr/misc.h index 2dc2985..e98b791 100644 --- a/dirmngr/misc.h +++ b/dirmngr/misc.h @@ -80,6 +80,10 @@ char *host_and_port_from_url (const char *url, int *port); /* Create a KSBA reader object and connect it to the estream FP. */ gpg_error_t create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp); +/* Encode the binary data in {DATA,DATALEN} as ASCII-armored data and + stored it as a NUL-terminated string in *R_STRING. The caller is + responsible for freeing *R_STRING. */ +gpg_error_t armor_data (char **r_string, const void *data, size_t datalen); #endif /* MISC_H */ commit 31edb58cad6fa47cbe802474dd5761068eff4f6d Author: Neal H. Walfield Date: Fri Mar 13 13:39:40 2015 +0100 Add function ldap_parse_uri. * dirmngr/Makefile.am (module_tests): New variable. (noinst_PROGRAMS): New primary. Set it to $(module_tests). (TESTS): New variable. Set it to $(module_tests). (t_common_src): New variable. (t_common_ldadd): Likewise. (t_ldap_parse_uri_SOURCES): New primary. (t_ldap_parse_uri_LDADD): Likewise. * dirmngr/ldap-parse-uri.c: New file. * dirmngr/ldap-parse-uri.h: Likewise. * dirmngr/t-ldap-parse-uri.c: Likewise. * dirmngr/t-support.h: Likewise. -- diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 2d8d336..c0918a7 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -27,6 +27,9 @@ if USE_LDAPWRAPPER libexec_PROGRAMS = dirmngr_ldap endif +noinst_PROGRAMS = $(module_tests) +TESTS = $(module_tests) + AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common include $(top_srcdir)/am/cmacros.am @@ -99,4 +102,14 @@ no-libgcrypt.c : $(top_srcdir)/tools/no-libgcrypt.c cat $(top_srcdir)/tools/no-libgcrypt.c > no-libgcrypt.c +t_common_src = t-support.h +# We need libcommontls, because we use the http functions. +t_common_ldadd = $(libcommontls) $(libcommon) no-libgcrypt.o $(GPG_ERROR_LIBS) + +module_tests = t-ldap-parse-uri +t_ldap_parse_uri_SOURCES = \ + t-ldap-parse-uri.c ldap-parse-uri.c ldap-parse-uri.h \ + $(t_common_src) +t_ldap_parse_uri_LDADD = $(ldaplibs) $(t_common_ldadd) + $(PROGRAMS) : $(libcommon) $(libcommonpth) $(libcommontls) $(libcommontlsnpth) diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c new file mode 100644 index 0000000..448d3be --- /dev/null +++ b/dirmngr/ldap-parse-uri.c @@ -0,0 +1,156 @@ +/* ldap-parse-uri.c - Parse an LDAP URI. + * Copyright (C) 2015 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 + +#ifdef HAVE_W32_SYSTEM +# include "ldap-url.h" +#else +# include +#endif + +#include "util.h" +#include "http.h" + +/* Parse a URI and put the result into *purip. On success the + caller must use http_release_parsed_uri() to releases the resources. + + uri->path is the base DN (or NULL for the default). + uri->auth is the bindname (or NULL for none). + The uri->query variable "password" is the password. + + Note: any specified scope, any attributes, any filter and any + unknown extensions are simply ignored. */ +gpg_error_t +ldap_parse_uri (parsed_uri_t *purip, const char *uri) +{ + gpg_err_code_t err = 0; + parsed_uri_t puri; + + int result; + LDAPURLDesc *lud = NULL; + + char *scheme = NULL; + char *host = NULL; + char *dn = NULL; + char *bindname = NULL; + char *password = NULL; + + char **s; + + char *p; + int len; + + result = ldap_url_parse (uri, &lud); + if (result != 0) + { + log_error ("Unable to parse LDAP uri '%s'\n", uri); + err = GPG_ERR_ASS_GENERAL; + goto out; + } + + scheme = lud->lud_scheme; + host = lud->lud_host; + dn = lud->lud_dn; + + for (s = lud->lud_exts; s && *s; s ++) + { + if (strncmp (*s, "bindname=", 9) == 0) + { + if (bindname) + log_error ("bindname given multiple times in URL '%s', ignoring.\n", + uri); + else + bindname = *s + 9; + } + else if (strncmp (*s, "password=", 9) == 0) + { + if (password) + log_error ("password given multiple times in URL '%s', ignoring.\n", + uri); + else + password = *s + 9; + } + else + log_error ("Unhandled extension (%s) in URL '%s', ignoring.", + *s, uri); + } + + len = 0; + void add (char *s) + { + if (s) + len += strlen (s) + 1; + } + add (scheme); + add (host); + add (dn); + add (bindname); + add (password); + + puri = xtrycalloc (1, sizeof *puri + len); + if (! puri) + { + err = gpg_err_code_from_syserror (); + goto out; + } + + p = puri->buffer; + + char *copy (char *s) + { + if (! s) + return NULL; + else + { + char *start = p; + p = stpcpy (p, s) + 1; + return start; + } + } + + puri->scheme = copy (scheme); + puri->host = copy (host); + puri->path = copy (dn); + puri->auth = copy (bindname); + + if (password) + { + puri->query = calloc (sizeof (*puri->query), 1); + puri->query->name = "password"; + puri->query->value = copy (password); + puri->query->valuelen = strlen (password) + 1; + } + + puri->use_tls = strcmp (puri->scheme, "ldaps") == 0; + puri->port = lud->lud_port; + + out: + if (lud) + ldap_free_urldesc (lud); + + if (err) + http_release_parsed_uri (puri); + else + *purip = puri; + + return gpg_err_make (default_errsource, err); +} diff --git a/dirmngr/ldap-parse-uri.h b/dirmngr/ldap-parse-uri.h new file mode 100644 index 0000000..1459c4f --- /dev/null +++ b/dirmngr/ldap-parse-uri.h @@ -0,0 +1,28 @@ +/* ldap-parse-uri.h - Parse an LDAP URI. + * Copyright (C) 2015 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 DIRMNGR_LDAP_PARSE_URI_H +#define DIRMNGR_LDAP_PARSE_URI_H + +#include "util.h" +#include "http.h" + +extern gpg_error_t ldap_parse_uri (parsed_uri_t *ret_uri, const char *uri); + +#endif diff --git a/dirmngr/t-ldap-parse-uri.c b/dirmngr/t-ldap-parse-uri.c new file mode 100644 index 0000000..e6fc4f2 --- /dev/null +++ b/dirmngr/t-ldap-parse-uri.c @@ -0,0 +1,162 @@ +/* t-ldap-parse-uri.c - Regression tests for ldap-parse-uri.c. + * Copyright (C) 2015 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 "ldap-parse-uri.h" + +#include "t-support.h" + +static void +test_ldap_parse_uri (void) +{ + struct test + { + const char *uri; + const char *scheme; + const char *host; + const int port; + const int use_tls; + const char *path; /* basedn. */ + const char *auth; /* binddn. */ + const char *password; /* query[1]. */ + }; + + struct test tests[] = { + { "ldap://", "ldap", NULL, 389, 0, NULL, NULL, NULL }, + { "ldap://host", "ldap", "host", 389, 0, NULL, NULL, NULL }, + { "ldap://host:100", "ldap", "host", 100, 0, NULL, NULL, NULL }, + { "ldaps://host", "ldaps", "host", 636, 1, NULL, NULL, NULL }, + { "ldap://host/ou%3DPGP%20Keys%2Cdc%3DEXAMPLE%2Cdc%3DORG", + "ldap", "host", 389, 0, "ou=PGP Keys,dc=EXAMPLE,dc=ORG" }, + { "ldap://host/????bindname=uid%3Duser%2Cou%3DPGP%20Users%2Cdc%3DEXAMPLE%2Cdc%3DORG,password=foobar", + "ldap", "host", 389, 0, "", + "uid=user,ou=PGP Users,dc=EXAMPLE,dc=ORG", "foobar" } + }; + + int test_count; + + void check (struct test *test) + { + gpg_error_t err; + parsed_uri_t puri; + + err = ldap_parse_uri (&puri, test->uri); + if (err) + { + printf ("Parsing '%s' failed (%d).\n", test->uri, err); + fail (test_count * 1000 + 0); + } + + int cmp (const char *a, const char *b) + { + if (! a) + a = ""; + if (! b) + b = ""; + + return strcmp (a, b) == 0; + } + + if (! cmp(test->scheme, puri->scheme)) + { + printf ("scheme mismatch: got '%s', expected '%s'.\n", + puri->scheme, test->scheme); + fail (test_count * 1000 + 1); + } + + if (! cmp(test->host, puri->host)) + { + printf ("host mismatch: got '%s', expected '%s'.\n", + puri->host, test->host); + fail (test_count * 1000 + 2); + } + + if (test->port != puri->port) + { + printf ("port mismatch: got '%d', expected '%d'.\n", + puri->port, test->port); + fail (test_count * 1000 + 3); + } + + if (test->use_tls != puri->use_tls) + { + printf ("use_tls mismatch: got '%d', expected '%d'.\n", + puri->use_tls, test->use_tls); + fail (test_count * 1000 + 4); + } + + if (! cmp(test->path, puri->path)) + { + printf ("path mismatch: got '%s', expected '%s'.\n", + puri->path, test->path); + fail (test_count * 1000 + 5); + } + + if (! cmp(test->auth, puri->auth)) + { + printf ("auth mismatch: got '%s', expected '%s'.\n", + puri->auth, test->auth); + fail (test_count * 1000 + 6); + } + + if (! test->password && ! puri->query) + /* Ok. */ + ; + else if (test->password && ! puri->query) + { + printf ("password mismatch: got NULL, expected '%s'.\n", + test->auth); + fail (test_count * 1000 + 7); + } + else if (! test->password && puri->query) + { + printf ("password mismatch: got something, expected NULL.\n"); + fail (test_count * 1000 + 8); + } + else if (! (test->password && puri->query + && puri->query->name && puri->query->value + && strcmp (puri->query->name, "password") == 0 + && cmp (puri->query->value, test->password))) + { + printf ("password mismatch: got '%s:%s', expected 'password:%s'.\n", + puri->query->name, puri->query->value, + test->password); + fail (test_count * 1000 + 9); + } + + http_release_parsed_uri (puri); + } + + for (test_count = 1; + test_count <= sizeof (tests) / sizeof (tests[0]); + test_count ++) + check (&tests[test_count - 1]); +} + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + test_ldap_parse_uri (); + + return 0; +} diff --git a/dirmngr/t-support.h b/dirmngr/t-support.h new file mode 100644 index 0000000..99fd267 --- /dev/null +++ b/dirmngr/t-support.h @@ -0,0 +1,42 @@ +/* t-support.h - Helper for the regression tests + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * This file is part of JNLIB, which is a subsystem of GnuPG. + * + * JNLIB is free software; you can redistribute it and/or modify it + * under the terms of either + * + * - the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * or + * + * - the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * or both in parallel, as here. + * + * JNLIB 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 copies of the GNU General Public License + * and the GNU Lesser General Public License along with this program; + * if not, see . + */ + +#ifndef DIRMNGR_T_SUPPORT_H +#define DIRMNGR_T_SUPPORT_H 1 + +/* Macros to print the result of a test. */ +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + exit (1); \ + } while(0) + + +#endif /* DIRMNGR_T_SUPPORT_H */ ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 15 13:36:45 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 15 Mar 2015 13:36:45 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-33-g4bc3a2e 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 4bc3a2e954afc2ba7dbe79ba5f740184b7d4cd73 (commit) via 3a35c9740ab792068ec4b3732ecfaa17bf4fc7f0 (commit) via 3529dd8bb5bafc4e02915648d5f409bd27a9cc37 (commit) via 95415bdec77a608e6052ba3e2a5d857a8e8f7689 (commit) via c59b410cf1d5676de7061e5a183c01227aa8e760 (commit) via ef0a3abf7305133d071bf1a94a7f461082f9a9aa (commit) via 35db798c2df7f31b52a9dd9d55ea60ae1f325be9 (commit) from efde50f92af241d8357db83e280a6ece62f6397f (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 4bc3a2e954afc2ba7dbe79ba5f740184b7d4cd73 Author: Werner Koch Date: Sun Mar 15 13:33:26 2015 +0100 g13: Fix pointer wrap check. * g13/utils.c (find_tuple, next_tuple): Cast pointer to size_t before doing an overflow check. -- Detected by Stack 0.3: bug: anti-simplify model: | %cmp4 = icmp ult i8* %add.ptr3, %s.0, !dbg !568 --> false stack: - /home/wk/s/gnupg/g13/utils.c:127:0 ncore: 1 core: - /home/wk/s/gnupg/g13/utils.c:127:0 - pointer overflow diff --git a/g13/utils.c b/g13/utils.c index 6fe3e5a..4ab4799 100644 --- a/g13/utils.c +++ b/g13/utils.c @@ -124,14 +124,16 @@ find_tuple (tupledesc_t tupledesc, unsigned int tag, size_t *r_length) s_end = s + tupledesc->datalen; while (s < s_end) { - if (s+3 >= s_end || s + 3 < s) + /* We use addresses for the overflow check to avoid undefined + behaviour. size_t should work with all flat memory models. */ + if ((size_t)s+3 >= (size_t)s_end || (size_t)s + 3 < (size_t)s) break; t = s[0] << 8; t |= s[1]; n = s[2] << 8; n |= s[3]; s += 4; - if (s + n > s_end || s + n < s) + if ((size_t)s + n > (size_t)s_end || (size_t)s + n < (size_t)s) break; if (t == tag) { @@ -159,14 +161,14 @@ next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length) s_end = s + tupledesc->datalen; s += tupledesc->pos; if (s < s_end - && !(s+3 >= s_end || s + 3 < s)) + && !((size_t)s + 3 >= (size_t)s_end || (size_t)s + 3 < (size_t)s)) { t = s[0] << 8; t |= s[1]; n = s[2] << 8; n |= s[3]; s += 4; - if (!(s + n > s_end || s + n < s)) + if (!((size_t)s + n > (size_t)s_end || (size_t)s + n < (size_t)s)) { tupledesc->pos = (s + n) - tupledesc->data; *r_tag = t; commit 3a35c9740ab792068ec4b3732ecfaa17bf4fc7f0 Author: Werner Koch Date: Sun Mar 15 13:11:44 2015 +0100 agent: Remove useless conditions in command.c. * agent/command.c (cmd_setkeydesc): Remove NULL check. (cmd_get_passphrase): Ditto. (cmd_clear_passphrase): Ditto. (cmd_get_confirmation): Ditto. (cmd_getval): Ditto. (cmd_putval): Ditto. -- Detected by Stack 0.3. diff --git a/agent/command.c b/agent/command.c index ca28e9b..96fbf19 100644 --- a/agent/command.c +++ b/agent/command.c @@ -718,7 +718,7 @@ cmd_setkeydesc (assuan_context_t ctx, char *line) if (p) *p = 0; /* We ignore any garbage; we might late use it for other args. */ - if (!desc || !*desc) + if (!*desc) return set_error (GPG_ERR_ASS_PARAMETER, "no description given"); /* Note, that we only need to replace the + characters and should @@ -1481,7 +1481,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) } } } - if (!cacheid || !*cacheid || strlen (cacheid) > 50) + if (!*cacheid || strlen (cacheid) > 50) return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID"); if (!desc) return set_error (GPG_ERR_ASS_PARAMETER, "no description given"); @@ -1596,7 +1596,7 @@ cmd_clear_passphrase (assuan_context_t ctx, char *line) p = strchr (cacheid, ' '); if (p) *p = 0; /* ignore garbage */ - if (!cacheid || !*cacheid || strlen (cacheid) > 50) + if (!*cacheid || strlen (cacheid) > 50) return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID"); agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER, @@ -1635,7 +1635,7 @@ cmd_get_confirmation (assuan_context_t ctx, char *line) if (p) *p = 0; /* We ignore any garbage -may be later used for other args. */ - if (!desc || !*desc) + if (!*desc) return set_error (GPG_ERR_ASS_PARAMETER, "no description given"); if (!strcmp (desc, "X")) @@ -2568,7 +2568,7 @@ cmd_getval (assuan_context_t ctx, char *line) if (*p) return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments"); } - if (!key || !*key) + if (!*key) return set_error (GPG_ERR_ASS_PARAMETER, "no key given"); @@ -2635,7 +2635,7 @@ cmd_putval (assuan_context_t ctx, char *line) valuelen = percent_plus_unescape_inplace (value, 0); } } - if (!key || !*key) + if (!*key) return set_error (GPG_ERR_ASS_PARAMETER, "no key given"); commit 3529dd8bb5bafc4e02915648d5f409bd27a9cc37 Author: Werner Koch Date: Sun Mar 15 13:04:48 2015 +0100 agent: Fix length test in sshcontrol parser. * agent/command-ssh.c (ssh_search_control_file): Check S before upcasing it. -- In contradiction to the comment we did not check the length of HEXGRIP and thus the GPG_ERR_INV_LENGTH was never triggered. Detected by Stack 0.3: bug: anti-simplify model: | %cmp8 = icmp ne i32 %i.0, 40, !dbg !986 --> false stack: - /home/wk/s/gnupg/agent/command-ssh.c:1226:0 ncore: 2 core: - /home/wk/s/gnupg/agent/command-ssh.c:1225:0 - buffer overflow - /home/wk/s/gnupg/agent/command-ssh.c:1225:0 - buffer overflow diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 2b51207..fffdb00 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1220,7 +1220,7 @@ ssh_search_control_file (ssh_control_file_t cf, /* We need to make sure that HEXGRIP is all uppercase. The easiest way to do this and also check its length is by copying to a second buffer. */ - for (i=0, s=hexgrip; i < 40; s++, i++) + for (i=0, s=hexgrip; i < 40 && *s; s++, i++) uphexgrip[i] = *s >= 'a'? (*s & 0xdf): *s; uphexgrip[i] = 0; if (i != 40) commit 95415bdec77a608e6052ba3e2a5d857a8e8f7689 Author: Werner Koch Date: Sun Mar 15 12:57:13 2015 +0100 agent: Remove useless conditions. * agent/genkey.c (agent_ask_new_passphrase): Remove useless condition. * agent/command-ssh.c (ssh_identity_register): Ditto. -- Detected by Stack 0.3: bug: anti-simplify model: | %tobool22 = icmp ne i8* %arraydecay21, null, !dbg !717 --> true stack: - /home/wk/s/gnupg/agent/genkey.c:385:0 ncore: 1 core: - /home/wk/s/gnupg/agent/genkey.c:362:0 - pointer overflow bug: anti-simplify model: | %tobool35 = icmp ne i8* %arraydecay34, null, !dbg !1053 --> true stack: - /home/wk/s/gnupg/agent/command-ssh.c:3120:0 ncore: 1 core: - /home/wk/s/gnupg/agent/command-ssh.c:3103:0 - pointer overflow diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 51d2c54..2b51207 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -3117,7 +3117,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, /* Unless the passphrase is empty or the pinentry told us that it already did the repetition check, ask to confirm it. */ - if (pi->pin && *pi->pin && !pi->repeat_okay) + if (*pi->pin && !pi->repeat_okay) { err = agent_askpin (ctrl, description2, NULL, NULL, pi2); if (err == -1) diff --git a/agent/genkey.c b/agent/genkey.c index d7b6007..ecf676e 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -382,7 +382,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt, } /* Unless the passphrase is empty or the pinentry told us that it already did the repetition check, ask to confirm it. */ - if (pi->pin && *pi->pin && !pi->repeat_okay) + if (*pi->pin && !pi->repeat_okay) { err = agent_askpin (ctrl, text2, NULL, NULL, pi2); if (err == -1) commit c59b410cf1d5676de7061e5a183c01227aa8e760 Author: Werner Koch Date: Sun Mar 15 12:30:06 2015 +0100 gpg: Remove useless condition. * g10/keylist.c (list_keyblock_colon): Remove useless condition (PK). (list_keyblock_print): Likewise. -- PK is already derefed above and thus testing for PK is dead code. Detected by Stack 0.3: bug: anti-simplify model: | %tobool200 = icmp ne %struct.PKT_public_key* %3, null, !dbg !1498 --> true stack: - /home/wk/s/gnupg/g10/keylist.c:1367:0 ncore: 1 core: - /home/wk/s/gnupg/g10/keylist.c:1319:0 - null pointer dereference bug: anti-simplify model: | %tobool102 = icmp ne %struct.PKT_public_key* %4, null, !dbg !1462 --> true stack: - /home/wk/s/gnupg/g10/keylist.c:978:0 ncore: 1 core: - /home/wk/s/gnupg/g10/keylist.c:955:0 - null pointer dereference bug: anti-simplify model: | %tobool128 = icmp ne %struct.PKT_public_key* %4, null, !dbg !1469 --> true stack: - /home/wk/s/gnupg/g10/keylist.c:990:0 ncore: 1 core: - /home/wk/s/gnupg/g10/keylist.c:955:0 - null pointer dereference diff --git a/g10/keylist.c b/g10/keylist.c index 03b9bbb..925109a 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -975,7 +975,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque) { PKT_user_id *uid = node->pkt->pkt.user_id; - if (pk && (uid->is_expired || uid->is_revoked) + if ((uid->is_expired || uid->is_revoked) && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS)) { skip_sigs = 1; @@ -988,7 +988,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque) dump_attribs (uid, pk); if ((uid->is_revoked || uid->is_expired) - || ((opt.list_options & LIST_SHOW_UID_VALIDITY) && pk)) + || (opt.list_options & LIST_SHOW_UID_VALIDITY)) { const char *validity; int indent; @@ -1364,7 +1364,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr) { int uid_validity; - if (pk && !ulti_hack) + if (!ulti_hack) uid_validity = get_validity_info (pk, uid); else uid_validity = 'u'; commit ef0a3abf7305133d071bf1a94a7f461082f9a9aa Author: Werner Koch Date: Sun Mar 15 12:15:55 2015 +0100 scd: Fix possible NULL deref in apdu.c * scd/apdu.c (control_pcsc_direct): Take care of BUFLEN being NULL. (control_pcsc_wrapped): Ditto. -- pcsc_vendor_specific_init calls the above with BUFFER and BUFLEN as NULL. Reported by Stack 0.3: bug: anti-dce model: | control_pcsc.exit77: %retval.0.i.i76 = phi i32 [ %rc.0.i.i.i73, \ %pcsc_error_to_sw.exit.i.i74 ], [ 0, %if.end.i.i75 ] %tobool198 = icmp ne i32 %retval.0.i.i76, 0, !dbg !728 br i1 %tobool198, label %if.then199, label %if.end200, !dbg !728 stack: - /home/wk/s/gnupg/scd/apdu.c:1882:0 ncore: 1 core: - /home/wk/s/gnupg/scd/apdu.c:1309:0 - buffer overflow diff --git a/scd/apdu.c b/scd/apdu.c index 5e7d27b..53cc4b9 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -1307,7 +1307,7 @@ control_pcsc_direct (int slot, pcsc_dword_t ioctl_code, long err; err = pcsc_control (reader_table[slot].pcsc.card, ioctl_code, - cntlbuf, len, buffer, *buflen, buflen); + cntlbuf, len, buffer, buflen? *buflen:0, buflen); if (err) { log_error ("pcsc_control failed: %s (0x%lx)\n", @@ -1375,14 +1375,18 @@ control_pcsc_wrapped (int slot, pcsc_dword_t ioctl_code, full_len = len; - n = *buflen < len ? *buflen : len; + if (buflen) + n = *buflen < len ? *buflen : len; + else + n = 0; if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n) { log_error ("error receiving PC/SC CONTROL response: %s\n", i? strerror (errno) : "premature EOF"); goto command_failed; } - *buflen = n; + if (buflen) + *buflen = n; full_len -= len; if (full_len) commit 35db798c2df7f31b52a9dd9d55ea60ae1f325be9 Author: Werner Koch Date: Sun Mar 15 12:07:21 2015 +0100 common: Make openpgp_oid_to_str more robust. * common/openpgp-oid.c (openpgp_oid_to_str): Take care of gcry_mpi_get_opaque returning NULL. Remove useless condition !BUF. -- It is possible that an opaque MPI stores just a NULL pointer. Take care of that before incrementing the pointer. We return an error in this case because at least a length byte is required. Found due to hint from stack 0.3: bug: anti-simplify model: | %tobool15 = icmp ne i8* %incdec.ptr, null, !dbg !567 --> true stack: - /home/wk/s/gnupg/common/openpgp-oid.c:220:0 ncore: 1 core: - /home/wk/s/gnupg/common/openpgp-oid.c:212:0 - pointer overflow Signed-off-by: Werner Koch diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index ccb67bb..7a75801 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -192,7 +192,9 @@ openpgp_oid_to_str (gcry_mpi_t a) valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1)); - if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + if (!a + || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE) + || !(buf = gcry_mpi_get_opaque (a, &lengthi))) { gpg_err_set_errno (EINVAL); return NULL; @@ -217,7 +219,7 @@ openpgp_oid_to_str (gcry_mpi_t a) string = p = xtrymalloc (length*(1+3)+2+1); if (!string) return NULL; - if (!buf || !length) + if (!length) { *p = 0; return string; ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 4 ++-- agent/command.c | 12 ++++++------ agent/genkey.c | 2 +- common/openpgp-oid.c | 6 ++++-- g10/keylist.c | 6 +++--- g13/utils.c | 10 ++++++---- scd/apdu.c | 10 +++++++--- 7 files changed, 29 insertions(+), 21 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Mar 15 14:23:51 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 15 Mar 2015 14:23:51 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-34-g1a9f13b 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 1a9f13bc663daa75c5009f6a0bf7d7483f12cce0 (commit) from 4bc3a2e954afc2ba7dbe79ba5f740184b7d4cd73 (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 1a9f13bc663daa75c5009f6a0bf7d7483f12cce0 Author: Werner Koch Date: Sun Mar 15 14:01:36 2015 +0100 gpg: Fix possible dead code elimination. * g10/encrypt.c: Change condition for detecting a real file. -- Detected by Stack 3.0: bug: anti-dce model: | %tobool155 = icmp ne i32 %call154, 0, !dbg !1298 --> true ************************************************************ land.lhs.true156: %96 = icmp eq i8* %filename, null call void @opt.bugon(i1 %96), !dbg !1298, !bug !1250 %97 = load i8* %filename, align 1, !dbg !1298 %conv157 = sext i8 %97 to i32, !dbg !1298 %tobool158 = icmp ne i32 %conv157, 0, !dbg !1298 br i1 %tobool158, label %land.lhs.true159, label %if.else177,\ !dbg !1298 stack: - /home/wk/s/gnupg/g10/encrypt.c:639:0 ncore: 1 core: - /home/wk/s/gnupg/g10/encrypt.c:639:0 - null pointer dereference diff --git a/g10/encrypt.c b/g10/encrypt.c index 8d2b325..7b5028d 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -453,6 +453,9 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, * supplied). Either FILENAME or FILEFD must be given, but not both. * The caller may provide a checked list of public keys in * PROVIDED_PKS; if not the function builds a list of keys on its own. + * + * Note that FILEFD is currently only used by cmd_encrypt in the the + * not yet finished server.c. */ int encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, @@ -476,7 +479,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, int do_compress; if (filefd != -1 && filename) - return gpg_error (GPG_ERR_INV_ARG); + return gpg_error (GPG_ERR_INV_ARG); /* Both given. */ do_compress = !!opt.compress_algo; @@ -635,8 +638,9 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (!opt.no_literal) pt = setup_plaintext_name (filename, inp); - if (filefd != -1 - && !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) + /* Get the size of the file if possible, i.e., if it is a real file. */ + if (filename && *filename + && !iobuf_is_pipe_filename (filename) && !opt.textmode ) { off_t tmpsize; int overflow; ----------------------------------------------------------------------- Summary of changes: g10/encrypt.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 16 08:40:27 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 16 Mar 2015 08:40:27 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.18-6-gb5cb32f 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 b5cb32f979a80904ea58fc7531e43e2be2270573 (commit) from 4441e96801fdc4c900abae8c0aa0b53e2e26e079 (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 b5cb32f979a80904ea58fc7531e43e2be2270573 Author: Werner Koch Date: Mon Mar 16 08:34:57 2015 +0100 Remove useless conditions. * src/estream.c (fname_set_internal): Remove useless condition. * src/mkheader.c (main): Ditto. -- Detected by Stack 0.3. diff --git a/src/estream.c b/src/estream.c index 42609ee..3c7d05f 100644 --- a/src/estream.c +++ b/src/estream.c @@ -4347,12 +4347,9 @@ fname_set_internal (estream_t stream, const char *fname, int quote) quote = !!quote; stream->intern->printable_fname = mem_alloc (strlen (fname) + quote + 1); - if (fname) - { - if (quote) - stream->intern->printable_fname[0] = '\\'; - strcpy (stream->intern->printable_fname+quote, fname); - } + if (quote) + stream->intern->printable_fname[0] = '\\'; + strcpy (stream->intern->printable_fname+quote, fname); } diff --git a/src/mkheader.c b/src/mkheader.c index 3481771..380c7e3 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -606,7 +606,7 @@ main (int argc, char **argv) putchar ('@'); fputs (p2, stdout); } - else if (p2 && *p2) + else if (*p2) { fputs (p2, stdout); } ----------------------------------------------------------------------- Summary of changes: src/estream.c | 9 +++------ src/mkheader.c | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 16 09:51:10 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 16 Mar 2015 09:51:10 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-175-g97db8e1 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 97db8e1a6400d711da65eff93bb418cf55bba12e (commit) via 0a9cdb8ae092d050ca12a7a4f2f50e25b82154ec (commit) via fbb97dcf763e28e81e01092ad4c934b3eaf88cc8 (commit) from 5e66a4f8d5a63f58caeee367433dd8dd32346083 (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 97db8e1a6400d711da65eff93bb418cf55bba12e Author: Werner Koch Date: Mon Mar 16 09:32:44 2015 +0100 Indentation fix. -- diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c index 652683c..62e79bb 100644 --- a/cipher/cipher-ocb.c +++ b/cipher/cipher-ocb.c @@ -300,8 +300,9 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf, /* Checksumming for encrypt and decrypt. */ -static void ocb_checksum(unsigned char *chksum, const unsigned char *plainbuf, - size_t nblks) +static void +ocb_checksum (unsigned char *chksum, const unsigned char *plainbuf, + size_t nblks) { while (nblks > 0) { commit 0a9cdb8ae092d050ca12a7a4f2f50e25b82154ec Author: Werner Koch Date: Mon Mar 16 09:29:27 2015 +0100 mpi: Remove useless condition. * mpi/mpi-pow.c: Remove condition rp==mp. -- MP has already been allocated and thus can't match RP. The followinf assert would have been triggred anyway due to the prior allocation. Detected by Stack 0.3. diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 70bf9e8..0be153f 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -507,7 +507,8 @@ _gcry_mpi_powm (gcry_mpi_t res, } - /* Make BASE, EXPO and MOD not overlap with RES. */ + /* Make BASE, EXPO not overlap with RES. We don't need to check MOD + because that has already been copied to the MP var. */ if ( rp == bp ) { /* RES and BASE are identical. Allocate temp. space for BASE. */ @@ -523,14 +524,6 @@ _gcry_mpi_powm (gcry_mpi_t res, ep = ep_marker = mpi_alloc_limb_space( esize, esec ); MPN_COPY(ep, rp, esize); } - if ( rp == mp ) - { - /* RES and MOD are identical. Allocate temporary space for MOD.*/ - gcry_assert (!mp_marker); - mp_nlimbs = msec?msize:0; - mp = mp_marker = mpi_alloc_limb_space( msize, msec ); - MPN_COPY(mp, rp, msize); - } /* Copy base to the result. */ if (res->alloced < size) commit fbb97dcf763e28e81e01092ad4c934b3eaf88cc8 Author: Werner Koch Date: Mon Mar 16 09:01:24 2015 +0100 cipher: Remove useless NULL check. * cipher/hash-common.c (_gcry_md_block_write): Remove NUL check for hd->buf. -- HD->BUF is not allocated but part of the struct. HD has already be dereferenced twice thus the check does not make sense. Detected by Stack 0.3: bug: anti-simplify model: | %cmp4 = icmp eq i8* %arraydecay, null, !dbg !29 --> false stack: - /home/wk/s/libgcrypt/cipher/hash-common.c:114:0 ncore: 1 core: - /home/wk/s/libgcrypt/cipher/hash-common.c:108:0 - null pointer dereference Signed-off-by: Werner Koch diff --git a/cipher/hash-common.c b/cipher/hash-common.c index 9a007e1..6743f09 100644 --- a/cipher/hash-common.c +++ b/cipher/hash-common.c @@ -111,7 +111,7 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen) if (sizeof(hd->buf) < blocksize) BUG(); - if (hd->buf == NULL || hd->bwrite == NULL) + if (!hd->bwrite) return; if (hd->count == blocksize) /* Flush the buffer. */ ----------------------------------------------------------------------- Summary of changes: cipher/cipher-ocb.c | 5 +++-- cipher/hash-common.c | 2 +- mpi/mpi-pow.c | 11 ++--------- 3 files changed, 6 insertions(+), 12 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 16 11:07:30 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 16 Mar 2015 11:07:30 +0100 Subject: [git] gnupg-doc - branch, master, updated. 570e1bc920b08f25fec300d1eaee5de11a6e21d1 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 570e1bc920b08f25fec300d1eaee5de11a6e21d1 (commit) via ec21c78a14d963b228ce50311b0050c657ecad73 (commit) from 39662b50026c9339d374fdbef0c5de62e9c46837 (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 570e1bc920b08f25fec300d1eaee5de11a6e21d1 Author: Werner Koch Date: Mon Mar 16 11:06:17 2015 +0100 Improve layout of donation summary tables. * tools/mkkudos.sh (dontable): Use class wideright. * web/donate/kudos.org: Add flag table_data_wideright. * web/share/gpgweb.el (gpgweb-postprocess-html): Prosprocess files with that flag. * web/share/site.css (th,td.wideright): New. diff --git a/tools/mkkudos.sh b/tools/mkkudos.sh index fb742a8..2678bdb 100755 --- a/tools/mkkudos.sh +++ b/tools/mkkudos.sh @@ -131,8 +131,8 @@ dontable=$(awk -F: <"$donations" -v thisyear="$thisyear" ' printf "\n"; printf "\n"; printf "Month\n"; - printf "#\n"; - printf "€\n"; + printf "#\n"; + printf "€\n"; printf "\n"; printf "\n"; printf "\n"; @@ -143,15 +143,16 @@ dontable=$(awk -F: <"$donations" -v thisyear="$thisyear" ' printf "\n"; printf "\n"; printf "%d\n", thisyear; - printf " %d\n", nyear; - printf " %d\n", totalyear; + printf " %d\n", nyear; + printf " %d\n", totalyear; printf "\n"; printf "\n"; exit 0 } { printf "%s\n", m[int($2)]; - printf " %d\n", $7; - printf " %d\n", int($8 + 0.5); + printf " %d\n", $7; + printf " %d\n", + int($8 + 0.5); } ') diff --git a/web/donate/kudos.org b/web/donate/kudos.org index f1ad914..808fb41 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -2,6 +2,8 @@ #+STARTUP: showall #+SETUPFILE: "../share/setup.inc" +#+HTML: + * Donation Summary *** This year @@ -15,7 +17,7 @@ *** Previous years | Year | # | \EUR | net \EUR | -| | | | | +| | | | | |------+-----+-------+----------| | 2014 | 801 | 34700 | | | 2013 | 148 | 5041 | 4145 | diff --git a/web/share/gpgweb.el b/web/share/gpgweb.el index c11d27b..55402fb 100644 --- a/web/share/gpgweb.el +++ b/web/share/gpgweb.el @@ -363,6 +363,15 @@ string of the source file or nil if not available." "href=\"\\(https://www.gnupg.org\\)/.*\"" nil t) (replace-match "" t t nil 1)) + ; If the wideright flag is used, change and + ; attributes. + (goto-char (point-min)) + (when (search-forward "" nil t) + (goto-char (point-min)) + (while (re-search-forward + "^ Date: Wed Mar 11 20:48:34 2015 +0100 blog: Typo fix. diff --git a/misc/blog.gnupg.org/20150310-gnupg-in-february.org b/misc/blog.gnupg.org/20150310-gnupg-in-february.org index ea089cd..4fe8680 100644 --- a/misc/blog.gnupg.org/20150310-gnupg-in-february.org +++ b/misc/blog.gnupg.org/20150310-gnupg-in-february.org @@ -10,7 +10,7 @@ GnuPG Project is over. Due to an unexpected amount of donations received in the first days of February we can keep on working for at least the next 2 or 3 years. -How did this happen? At the [[https://events.ccc.de/congress/2014/wiki/Main_Page][31C3]] Nico Josattis arranged an Interview +How did this happen? At the [[https://events.ccc.de/congress/2014/wiki/Main_Page][31C3]] Nico Josuttis arranged an Interview with [[http://juliaangwin.com][Julia Angwin]] who writes for [[http://www.propublica.org][ProPublica]]. Eventually on the 5th her [[http://www.propublica.org/article/the-worlds-email-encryption-software-relies-on-one-guy-who-is-going-broke][article]] was published and immediately received a lot of attention. Not only at the ProPublica site but at many other news site as well. ----------------------------------------------------------------------- Summary of changes: misc/blog.gnupg.org/20150310-gnupg-in-february.org | 2 +- tools/mkkudos.sh | 13 +++++++------ web/donate/kudos.org | 4 +++- web/share/gpgweb.el | 9 +++++++++ web/share/site.css | 10 ++++++++++ 5 files changed, 30 insertions(+), 8 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 16 11:53:26 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 16 Mar 2015 11:53:26 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-177-gdb8ae36 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 db8ae3616987fa288173446398a107e31e2e28aa (commit) via f0f60c1a04d664936bcf52e8f46705bdc63e7ad9 (commit) from 97db8e1a6400d711da65eff93bb418cf55bba12e (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 db8ae3616987fa288173446398a107e31e2e28aa Author: Werner Koch Date: Mon Mar 16 11:50:23 2015 +0100 Use well defined type instead of size_t in secmem.c * src/secmem.c (ptr_into_pool_p): Replace size_t by uintptr_t. -- This is more or less cosmetic. Signed-off-by: Werner Koch diff --git a/src/secmem.c b/src/secmem.c index df15df0..d75c14c 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -105,14 +105,13 @@ static int ptr_into_pool_p (const void *p) { /* We need to convert pointers to addresses. This is required by - C-99 6.5.8 to avoid undefined behaviour. Using size_t is at - least only implementation defined. See also + C-99 6.5.8 to avoid undefined behaviour. See also http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html */ - size_t p_addr = (size_t)p; - size_t pool_addr = (size_t)pool; + uintptr_t p_addr = (uintptr_t)p; + uintptr_t pool_addr = (uintptr_t)pool; - return p_addr >= pool_addr && p_addr < pool_addr+pool_size; + return p_addr >= pool_addr && p_addr < pool_addr + pool_size; } /* Update the stats. */ commit f0f60c1a04d664936bcf52e8f46705bdc63e7ad9 Author: Werner Koch Date: Mon Mar 16 11:32:07 2015 +0100 Make uintptr_t global available. * cipher/bufhelp.h: Move include for uintptr_t to ... * src/types.h: here. Check that config.h has been included. Signed-off-by: Werner Koch diff --git a/cipher/bithelp.h b/cipher/bithelp.h index 2220bc8..258ab2f 100644 --- a/cipher/bithelp.h +++ b/cipher/bithelp.h @@ -4,7 +4,7 @@ * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser general Public License as + * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * @@ -14,11 +14,10 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * License along with this program; if not, see . */ -#ifndef G10_BITHELP_H -#define G10_BITHELP_H +#ifndef GCRYPT_BITHELP_H +#define GCRYPT_BITHELP_H #include "types.h" @@ -122,4 +121,4 @@ _gcry_ctz64(u64 x) #endif /*HAVE_U64_TYPEDEF*/ -#endif /*G10_BITHELP_H*/ +#endif /*GCRYPT_BITHELP_H*/ diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index a372acb..c6bedc5 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -4,7 +4,7 @@ * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser general Public License as + * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * @@ -14,21 +14,11 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * License along with this program; if not, see . */ -#ifndef G10_BUFHELP_H -#define G10_BUFHELP_H +#ifndef GCRYPT_BUFHELP_H +#define GCRYPT_BUFHELP_H -#include - -#ifdef HAVE_STDINT_H -# include /* uintptr_t */ -#elif defined(HAVE_INTTYPES_H) -# include -#else -/* In this case, uintptr_t is provided by config.h. */ -#endif #include "bithelp.h" @@ -409,4 +399,4 @@ static inline void buf_put_le64(void *_buf, u64 val) #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ -#endif /*G10_BITHELP_H*/ +#endif /*GCRYPT_BUFHELP_H*/ diff --git a/src/types.h b/src/types.h index 561b74d..dcdba4f 100644 --- a/src/types.h +++ b/src/types.h @@ -21,6 +21,9 @@ #ifndef GCRYPT_TYPES_H #define GCRYPT_TYPES_H +#ifndef _GCRYPT_CONFIG_H_INCLUDED +# error config.h must be included before types.h +#endif /* The AC_CHECK_SIZEOF() in configure fails for some machines. * we provide some fallback values here */ @@ -40,6 +43,16 @@ #include +/* Provide uintptr_t */ +#ifdef HAVE_STDINT_H +# include /* uintptr_t */ +#elif defined(HAVE_INTTYPES_H) +# include +#else +/* In this case, uintptr_t is provided by config.h. */ +#endif + + #ifndef HAVE_BYTE_TYPEDEF # undef byte /* In case there is a macro with that name. */ ----------------------------------------------------------------------- Summary of changes: cipher/bithelp.h | 11 +++++------ cipher/bufhelp.h | 20 +++++--------------- src/secmem.c | 9 ++++----- src/types.h | 13 +++++++++++++ 4 files changed, 27 insertions(+), 26 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 16 13:42:25 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 16 Mar 2015 13:42:25 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.5.3-5-g8cfcdfe 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 8cfcdfe5564f87362e5ec1bfdca5c14aed9c45f0 (commit) via 119f27032b822ace8c012b96f9e41bcf23251a54 (commit) from 428ea7696585bc24d127b903840554ca659069b6 (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 8cfcdfe5564f87362e5ec1bfdca5c14aed9c45f0 Author: Werner Koch Date: Mon Mar 16 13:40:34 2015 +0100 Fix potential crash in trace macro. * src/signers.c (gpgme_signers_add): Avoid deref of a NULL KEY in the trace macro. * src/engine-spawn.c (engspawn_release): Remove always true condition. * src/engine-gpg.c (gpg_release): Ditto. Signed-off-by: Werner Koch diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 30c3bfb..57aea8b 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -396,8 +396,7 @@ gpg_release (void *engine) { struct arg_and_data_s *next = gpg->arglist->next; - if (gpg->arglist) - free (gpg->arglist); + free (gpg->arglist); gpg->arglist = next; } diff --git a/src/engine-spawn.c b/src/engine-spawn.c index 28a14be..eb4e038 100644 --- a/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -355,8 +355,7 @@ engspawn_release (void *engine) { struct datalist_s *next = esp->arglist->next; - if (esp->arglist) - free (esp->arglist); + free (esp->arglist); esp->arglist = next; } diff --git a/src/signers.c b/src/signers.c index f43fafc..f540d70 100644 --- a/src/signers.c +++ b/src/signers.c @@ -66,7 +66,7 @@ gpgme_error_t gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key) { TRACE_BEG2 (DEBUG_CTX, "gpgme_signers_add", ctx, - "key=%p (%s)", key, (key->subkeys && key->subkeys->fpr) ? + "key=%p (%s)", key, (key && key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid"); if (!ctx || !key) commit 119f27032b822ace8c012b96f9e41bcf23251a54 Author: Werner Koch Date: Mon Mar 16 13:38:10 2015 +0100 Fix one byte too short malloc. * src/engine-spawn.c (add_data): Fix malloc -- Bummer. Why did I subtracted one from the size? Did I assume a dynamically allocated structure with a string field which was not going to be used? Very strange. Not a real problem though because malloc will anyway round up the allocation to at least the next word size. Detected by Stack 0.3. diff --git a/src/engine-spawn.c b/src/engine-spawn.c index 8ffc628..28a14be 100644 --- a/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -120,7 +120,7 @@ add_data (engine_spawn_t esp, gpgme_data_t data, int dup_to, int inbound) assert (esp); assert (data); - a = malloc (sizeof *a - 1); + a = malloc (sizeof *a); if (!a) return gpg_error_from_syserror (); a->next = NULL; ----------------------------------------------------------------------- Summary of changes: src/engine-gpg.c | 3 +-- src/engine-spawn.c | 5 ++--- src/signers.c | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 16 20:18:22 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 16 Mar 2015 20:18:22 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-37-gab17f7b 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 ab17f7b6c392782718f57eaea94fc18a0ff49389 (commit) via bcc8250bc5b9a357c6d1444f03e334edec573ede (commit) via 8bc1debfefb7cd4b0be724317793d59dea37d677 (commit) from 1a9f13bc663daa75c5009f6a0bf7d7483f12cce0 (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 ab17f7b6c392782718f57eaea94fc18a0ff49389 Author: Werner Koch Date: Mon Mar 16 20:14:58 2015 +0100 gpg: Create all MPIs with RFC-4880 correct length headers. * g10/build-packet.c (gpg_mpi_write): Strip leading zeroes. -- This used not to work with opaque MPI as returned by Libgcrypt from ECC operations. This patch fixes this. Signed-off-by: Werner Koch diff --git a/g10/build-packet.c b/g10/build-packet.c index e984e3e..269c63c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -164,10 +164,28 @@ gpg_mpi_write (iobuf_t out, gcry_mpi_t a) if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) { unsigned int nbits; - const void *p; + const unsigned char *p; unsigned char lenhdr[2]; + /* gcry_log_debugmpi ("a", a); */ p = gcry_mpi_get_opaque (a, &nbits); + if (p) + { + /* Strip leading zero bits. */ + for (; nbits >= 8 && !*p; p++, nbits -= 8) + ; + if (nbits >= 8 && !(*p & 0x80)) + if (--nbits >= 7 && !(*p & 0x40)) + if (--nbits >= 6 && !(*p & 0x20)) + if (--nbits >= 5 && !(*p & 0x10)) + if (--nbits >= 4 && !(*p & 0x08)) + if (--nbits >= 3 && !(*p & 0x04)) + if (--nbits >= 2 && !(*p & 0x02)) + if (--nbits >= 1 && !(*p & 0x01)) + --nbits; + } + /* gcry_log_debug (" [%u bit]\n", nbits); */ + /* gcry_log_debughex (" ", p, (nbits+7)/8); */ lenhdr[0] = nbits >> 8; lenhdr[1] = nbits; rc = iobuf_write (out, lenhdr, 2); commit bcc8250bc5b9a357c6d1444f03e334edec573ede Author: Werner Koch Date: Mon Mar 16 19:57:11 2015 +0100 gpg: Allow printing of MPI values in --list-mode. * g10/parse-packet.c (set_packet_list_mode): Set mpi_print_mode. * g10/misc.c (mpi_print): Do not print an extra leading zero. -- This was in older versions possible using "--debug 4" but that was disabled in 2.1 due to a conflict using this values also for Libgcrypt. Now the values are dumped either with --debug 4 or using --list-packets along with --verbose. Because OpenPGP only uses unsigned integers an extra leading zero will not be printed anymore. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 11d8919..741271e 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -333,8 +333,9 @@ listed too. @item --list-packets @opindex list-packets -List only the sequence of packets. This is mainly -useful for debugging. +List only the sequence of packets. This is mainly useful for +debugging. When used with option @option{--verbose} the actual MPI +values are dumped and not only their lengths. @item --card-edit diff --git a/g10/misc.c b/g10/misc.c index 4cff2dc..654908d 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1636,7 +1636,8 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) int mpi_print (estream_t fp, gcry_mpi_t a, int mode) { - int n=0; + int n = 0; + size_t nwritten; if (!a) return es_fprintf (fp, "[MPI_NULL]"); @@ -1654,19 +1655,19 @@ mpi_print (estream_t fp, gcry_mpi_t a, int mode) n += es_fprintf (fp, "[invalid opaque value]"); else { - nbits = (nbits + 7)/8; - for (; nbits; nbits--, p++) - n += es_fprintf (fp, "%02X", *p); + if (!es_write_hexstring (fp, p, (nbits + 7)/8, 0, &nwritten)) + n += nwritten; } } else { unsigned char *buffer; + size_t buflen; - if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a)) + if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &buflen, a)) BUG (); - es_fputs (buffer, fp); - n += strlen (buffer); + if (!es_write_hexstring (fp, buffer, buflen, 0, &nwritten)) + n += nwritten; gcry_free (buffer); } return n; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 6232086..d6a6d10 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -112,7 +112,7 @@ read_32 (IOBUF inp) /* Read an external representation of an mpi and return the MPI. The * external format is a 16 bit unsigned value stored in network byte * order, giving the number of bits for the following integer. The - * integer is stored with MSB first (left padded with zeroes to align + * integer is stored with MSB first (left padded with zero bits to align * on a byte boundary). */ static gcry_mpi_t mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) @@ -177,24 +177,38 @@ set_packet_list_mode (int mode) { int old = list_mode; list_mode = mode; - /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */ - /* We use stdout print only if invoked by the --list-packets command + + /* We use stdout only if invoked by the --list-packets command but switch to stderr in all other cases. This breaks the previous behaviour but that seems to be more of a bug than intentional. I don't believe that any application makes use of this long standing annoying way of printing to stdout except when doing a --list-packets. If this assumption fails, it will be easy to add an option for the listing stream. Note that we initialize - it only once; mainly because some code may switch the option - value later back to 1 and we want to have all output to the same - stream. + it only once; mainly because there is code which switches + opt.list_mode back to 1 and we want to have all output to the + same stream. The MPI_PRINT_MODE will be enabled if the + corresponding debug flag is set or if we are in --list-packets + and --verbose is given. Using stderr is not actually very clean because it bypasses the logging code but it is a special thing anyway. I am not sure whether using log_stream() would be better. Perhaps we should - enable the list mdoe only with a special option. */ + enable the list mode only with a special option. */ if (!listfp) - listfp = opt.list_packets == 2 ? es_stdout : es_stderr; + { + if (opt.list_packets == 2) + { + listfp = es_stdout; + if (opt.verbose) + mpi_print_mode = 1; + } + else + listfp = es_stderr; + + if (opt.debug && DBG_MPI_VALUE) + mpi_print_mode = 1; + } return old; } commit 8bc1debfefb7cd4b0be724317793d59dea37d677 Author: Werner Koch Date: Mon Mar 16 19:51:06 2015 +0100 gpg: Fix broken write of opaque MPI length header. * g10/build-packet.c (gpg_mpi_write): Use a char array for the length. Signed-off-by: Werner Koch diff --git a/g10/build-packet.c b/g10/build-packet.c index 557dffe..e984e3e 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -165,7 +165,7 @@ gpg_mpi_write (iobuf_t out, gcry_mpi_t a) { unsigned int nbits; const void *p; - unsigned int lenhdr[2]; + unsigned char lenhdr[2]; p = gcry_mpi_get_opaque (a, &nbits); lenhdr[0] = nbits >> 8; ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 5 +++-- g10/build-packet.c | 22 ++++++++++++++++++++-- g10/misc.c | 15 ++++++++------- g10/parse-packet.c | 30 ++++++++++++++++++++++-------- 4 files changed, 53 insertions(+), 19 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 17 11:25:25 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 17 Mar 2015 11:25:25 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-40-g9078b75 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 9078b75a73600fc6b7b5502ceee8de032bb9c446 (commit) via eb5f2c0af6691229300ac120ee44815cb27ed38e (commit) via e0398fb110b588ffb860878a5dc89c1e25500843 (commit) from ab17f7b6c392782718f57eaea94fc18a0ff49389 (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 9078b75a73600fc6b7b5502ceee8de032bb9c446 Author: Werner Koch Date: Tue Mar 17 11:22:28 2015 +0100 common: Add feature to ease using argparse's usage(). * common/argparse.c (show_help): Take care of flag value (usage): Ditto. -- It is common that the long usage note starts with the short usage note. The new flag feature allows to combine both. Signed-off-by: Werner Koch diff --git a/common/argparse.c b/common/argparse.c index a4d1552..e31b67e 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -1239,6 +1239,14 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags) show_version (); writestrings (0, "\n", NULL); + s = strusage (42); + if (s && *s == '1') + { + s = strusage (40); + writestrings (1, s, NULL); + if (*s && s[strlen(s)] != '\n') + writestrings (1, "\n", NULL); + } s = strusage(41); writestrings (0, s, "\n", NULL); if ( opts[0].description ) @@ -1432,6 +1440,14 @@ usage (int level) } else if (level == 2) { + p = strusage (42); + if (p && *p == '1') + { + p = strusage (40); + writestrings (1, p, NULL); + if (*p && p[strlen(p)] != '\n') + writestrings (1, "\n", NULL); + } writestrings (0, strusage(41), "\n", NULL); exit (0); } @@ -1455,6 +1471,10 @@ usage (int level) *30..39: Additional program info (with LFs) * 40: short usage note (with LF) * 41: long usage note (with LF) + * 42: Flag string: + * First char is '1': + * The short usage notes needs to be printed + * before the long usage note. */ const char * strusage( int level ) commit eb5f2c0af6691229300ac120ee44815cb27ed38e Author: Werner Koch Date: Tue Mar 17 09:19:55 2015 +0100 common: Allow standalone build of argparse.c * common/argparse.h: Remove types.h - not required. * common/argparse.c: Change to allow standalone use. Signed-off-by: Werner Koch diff --git a/common/argparse.c b/common/argparse.c index b067314..a4d1552 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -1,6 +1,6 @@ /* [argparse.c wk 17.06.97] Argument Parser for option handling - * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc. - * Copyright (C) 1997-2001, 2006-2008, 2013 Werner Koch + * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc. + * Copyright (C) 1997-2001, 2006-2008, 2013-2015 Werner Koch * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -29,6 +29,11 @@ * if not, see . */ +/* This file may be used as part of GnuPG or standalone. A GnuPG + build is detected by the presence of the macro GNUPG_MAJOR_VERSION. + Some feature are only availalbe in the GnuPG build mode. + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -41,20 +46,114 @@ #include #include -#include "libjnlib-config.h" -#include "mischelp.h" -#include "stringhelp.h" -#include "logging.h" -#ifdef JNLIB_NEED_UTF8CONV -#include "utf8conv.h" -#endif +#ifdef GNUPG_MAJOR_VERSION +# include "libjnlib-config.h" +# include "mischelp.h" +# include "stringhelp.h" +# include "logging.h" +# ifdef JNLIB_NEED_UTF8CONV +# include "utf8conv.h" +# endif +#endif /*GNUPG_MAJOR_VERSION*/ + #include "argparse.h" +/* GnuPG uses GPLv3+ but a standalone version of this defaults to + GPLv2+ because that is the license of this file. Change this if + you include it in a program which uses GPLv3. If you don't want to + set a a copyright string for your usage() you may also hardcode it + here. */ +#ifndef GNUPG_MAJOR_VERSION + +# define ARGPARSE_GPL_VERSION 2 +# define ARGPARSE_CRIGHT_STR "Copyright (C) YEAR NAME" + +#else /* Used by GnuPG */ + +# define ARGPARSE_GPL_VERSION 3 +# define ARGPARSE_CRIGHT_STR "Copyright (C) 2015 Free Software Foundation, Inc." + +#endif /*GNUPG_MAJOR_VERSION*/ + +/* Replacements for standalone builds. */ +#ifndef GNUPG_MAJOR_VERSION +# ifndef _ +# define _(a) (a) +# endif +# ifndef DIM +# define DIM(v) (sizeof(v)/sizeof((v)[0])) +# endif +# define jnlib_malloc(a) malloc ((a)) +# define jnlib_realloc(a,b) realloc ((a), (b)) +# define jnlib_strdup(a) strdup ((a)) +# define jnlib_free(a) free ((a)) +# define jnlib_log_error my_log_error +# define jnlib_log_bug my_log_bug +# define trim_spaces(a) my_trim_spaces ((a)) +# define map_static_macro_string(a) (a) +#endif /*!GNUPG_MAJOR_VERSION*/ + + +#define ARGPARSE_STR(v) #v +#define ARGPARSE_STR2(v) ARGPARSE_STR(v) + + +/* Replacements for standalone builds. */ +#ifndef GNUPG_MAJOR_VERSION +static void +my_log_error (const char *fmt, ...) +{ + va_list arg_ptr ; + + va_start (arg_ptr, fmt); + fprintf (stderr, "%s: ", strusage (11)); + vfprintf (stderr, fmt, arg_ptr); + va_end (arg_ptr); +} + +static void +my_log_bug (const char *fmt, ...) +{ + va_list arg_ptr ; + + va_start (arg_ptr, fmt); + fprintf (stderr, "%s: Ohhhh jeeee: ", strusage (11)); + vfprintf (stderr, fmt, arg_ptr); + va_end (arg_ptr); + abort (); +} + +static char * +my_trim_spaces (char *str) +{ + char *string, *p, *mark; + + string = str; + /* Find first non space character. */ + for (p=string; *p && isspace (*(unsigned char*)p) ; p++) + ; + /* Move characters. */ + for ((mark = NULL); (*string = *p); string++, p++) + if (isspace (*(unsigned char*)p)) + { + if (!mark) + mark = string; + } + else + mark = NULL; + if (mark) + *mark = '\0' ; /* Remove trailing spaces. */ + + return str ; +} + +#endif /*!GNUPG_MAJOR_VERSION*/ + /********************************* * @Summary arg_parse - * #include + * #include "argparse.h" * * typedef struct { * char *argc; pointer to argc (value subject to change) @@ -1367,12 +1466,19 @@ strusage( int level ) switch ( level ) { - case 10: p = ("License GPLv3+: GNU GPL version 3 or later " - ""); + + case 10: +#if ARGPARSE_GPL_VERSION == 3 + p = ("License GPLv3+: GNU GPL version 3 or later " + ""); +#else + p = ("License GPLv2+: GNU GPL version 2 or later " + ""); +#endif break; case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2015 Free Software Foundation, Inc."; break; + case 14: p = ARGPARSE_CRIGHT_STR; break; case 15: p = "This is free software: you are free to change and redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n"; @@ -1380,7 +1486,9 @@ strusage( int level ) case 16: p = "This is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" -"the Free Software Foundation; either version 3 of the License, or\n" +"the Free Software Foundation; either version " +ARGPARSE_STR2(ARGPARSE_GPL_VERSION) +" of the License, or\n" "(at your option) any later version.\n\n" "It is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" @@ -1414,7 +1522,7 @@ static struct { int myopt; int echo; int a_long_one; -}opt; +} opt; int main(int argc, char **argv) @@ -1422,7 +1530,7 @@ main(int argc, char **argv) ARGPARSE_OPTS opts[] = { ARGPARSE_x('v', "verbose", NONE, 0, "Laut sein"), ARGPARSE_s_n('e', "echo" , ("Zeile ausgeben, damit wir sehen, " - "was wir ein gegeben haben")), + "was wir eingegeben haben")), ARGPARSE_s_n('d', "debug", "Debug\nfalls mal etwas\nschief geht"), ARGPARSE_s_s('o', "output", 0 ), ARGPARSE_o_s('c', "cross-ref", "cross-reference erzeugen\n" ), @@ -1430,43 +1538,50 @@ main(int argc, char **argv) ARGPARSE_s_n('s', "street","|Stra?e|set the name of the street to Stra?e"), ARGPARSE_o_i('m', "my-option", 0), ARGPARSE_s_n(500, "a-long-option", 0 ), - ARGPARSE_end + ARGPARSE_end() }; - ARGPARSE_ARGS pargs = { &argc, &argv, 2|4|32 }; - int i; + ARGPARSE_ARGS pargs = { &argc, &argv, (ARGPARSE_FLAG_ALL + | ARGPARSE_FLAG_MIXED + | ARGPARSE_FLAG_ONEDASH) }; + int i; - while( arg_parse ( &pargs, opts) ) { - switch( pargs.r_opt ) { - case -1 : printf( "arg='%s'\n", pargs.r.ret_str); break; - case 'v': opt.verbose++; break; - case 'e': opt.echo++; break; - case 'd': opt.debug++; break; - case 'o': opt.outfile = pargs.r.ret_str; break; - case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - case 500: opt.a_long_one++; break; - default : pargs.err = ARGPARSE_PRINT_WARNING; break; + while (arg_parse (&pargs, opts)) + { + switch (pargs.r_opt) + { + case ARGPARSE_IS_ARG : + printf ("arg='%s'\n", pargs.r.ret_str); + break; + case 'v': opt.verbose++; break; + case 'e': opt.echo++; break; + case 'd': opt.debug++; break; + case 'o': opt.outfile = pargs.r.ret_str; break; + case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; + case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; + case 500: opt.a_long_one++; break; + default : pargs.err = ARGPARSE_PRINT_WARNING; break; } } - for(i=0; i < argc; i++ ) - printf("%3d -> (%s)\n", i, argv[i] ); - puts("Options:"); - if( opt.verbose ) - printf(" verbose=%d\n", opt.verbose ); - if( opt.debug ) - printf(" debug=%d\n", opt.debug ); - if( opt.outfile ) - printf(" outfile='%s'\n", opt.outfile ); - if( opt.crf ) - printf(" crffile='%s'\n", opt.crf ); - if( opt.myopt ) - printf(" myopt=%d\n", opt.myopt ); - if( opt.a_long_one ) - printf(" a-long-one=%d\n", opt.a_long_one ); - if( opt.echo ) - printf(" echo=%d\n", opt.echo ); - return 0; + for (i=0; i < argc; i++ ) + printf ("%3d -> (%s)\n", i, argv[i] ); + puts ("Options:"); + if (opt.verbose) + printf (" verbose=%d\n", opt.verbose ); + if (opt.debug) + printf (" debug=%d\n", opt.debug ); + if (opt.outfile) + printf (" outfile='%s'\n", opt.outfile ); + if (opt.crf) + printf (" crffile='%s'\n", opt.crf ); + if (opt.myopt) + printf (" myopt=%d\n", opt.myopt ); + if (opt.a_long_one) + printf (" a-long-one=%d\n", opt.a_long_one ); + if (opt.echo) + printf (" echo=%d\n", opt.echo ); + + return 0; } -#endif +#endif /*TEST*/ /**** bottom of file ****/ diff --git a/common/argparse.h b/common/argparse.h index 471cf74..b4dc253 100644 --- a/common/argparse.h +++ b/common/argparse.h @@ -32,7 +32,6 @@ #define LIBJNLIB_ARGPARSE_H #include -#include "types.h" typedef struct { @@ -193,12 +192,12 @@ typedef struct #define ARGPARSE_INVALID_ARG (-12) -int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -int optfile_parse( FILE *fp, const char *filename, unsigned *lineno, +int arg_parse (ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); +int optfile_parse (FILE *fp, const char *filename, unsigned *lineno, ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -void usage( int level ); -const char *strusage( int level ); -void set_strusage( const char *(*f)( int ) ); +void usage (int level); +const char *strusage (int level); +void set_strusage (const char *(*f)( int )); void argparse_register_outfnc (int (*fnc)(int, const char *)); #endif /*LIBJNLIB_ARGPARSE_H*/ commit e0398fb110b588ffb860878a5dc89c1e25500843 Author: Werner Koch Date: Tue Mar 17 09:18:23 2015 +0100 Typo fix. -- diff --git a/common/mapstrings.c b/common/mapstrings.c index 91795d5..5c5bec9 100644 --- a/common/mapstrings.c +++ b/common/mapstrings.c @@ -132,7 +132,7 @@ find_macro (const char *string, const char **begptr, /* If STRING includes known @FOO@ macros, replace these macros and return a new static string. Warning: STRING must have been - allocated statically. Note that this function allocated memory + allocated statically. Note that this function allocates memory which will not be released (similar to gettext). */ const char * map_static_macro_string (const char *string) ----------------------------------------------------------------------- Summary of changes: common/argparse.c | 233 +++++++++++++++++++++++++++++++++++++++++----------- common/argparse.h | 11 ++- common/mapstrings.c | 2 +- 3 files changed, 190 insertions(+), 56 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 17 11:30:16 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 17 Mar 2015 11:30:16 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.0-6-g2f7b275 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 2f7b275b2b5d31df48f02ab2913ba3ff2e74b7a4 (commit) via 8fa3ca90bfbaa84314443fab9865742b78eb85a9 (commit) from bb423620fca82159e60ab25de3c608a0243088b0 (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 2f7b275b2b5d31df48f02ab2913ba3ff2e74b7a4 Author: Werner Koch Date: Tue Mar 17 11:28:40 2015 +0100 Get rid of getopt_long and improve --help output. * pinentry/argparse.c, pinentry/argparse.h: New. Taken from GnuPG master. * pinentry/Makefile.am (libpinentry_a_SOURCES): Add them. * pinentry/pinentry.c: Include argparse.h. (usage): Remove. (my_strusage): New. (pinentry_parse_opts): Rewrite. Do not return a value. Change call callers. -- getopt_long is not generally available, for example it is missing on AIX. Instead of adding replacement code we use the option parser from GnuPG and thus also gain a better --version and --help. Signed-off-by: Werner Koch diff --git a/curses/pinentry-curses.c b/curses/pinentry-curses.c index 823206e..20a5c93 100644 --- a/curses/pinentry-curses.c +++ b/curses/pinentry-curses.c @@ -1,18 +1,18 @@ /* pinentry-curses.c - A secure curses dialog for PIN entry. Copyright (C) 2002 g10 Code GmbH - + This file is part of PINENTRY. - + PINENTRY is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + PINENTRY is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -31,17 +31,12 @@ pinentry_cmd_handler_t pinentry_cmd_handler = curses_cmd_handler; -int +int main (int argc, char *argv[]) { pinentry_init ("pinentry-curses"); - /* Consumes all arguments. */ - if (pinentry_parse_opts (argc, argv)) - { - printf ("pinentry-curses (pinentry) " VERSION "\n"); - exit (EXIT_SUCCESS); - } + pinentry_parse_opts (argc, argv); if (pinentry_loop ()) return 1; diff --git a/gtk+-2/pinentry-gtk-2.c b/gtk+-2/pinentry-gtk-2.c index 1a8c083..0063c3f 100644 --- a/gtk+-2/pinentry-gtk-2.c +++ b/gtk+-2/pinentry-gtk-2.c @@ -689,12 +689,7 @@ main (int argc, char *argv[]) gtk_init (&argc, &argv); #endif - /* Consumes all arguments. */ - if (pinentry_parse_opts (argc, argv)) - { - printf(PGMNAME " " VERSION "\n"); - exit(EXIT_SUCCESS); - } + pinentry_parse_opts (argc, argv); if (pinentry_loop ()) return 1; diff --git a/gtk/pinentry-gtk.c b/gtk/pinentry-gtk.c index 00bd531..4f9c116 100644 --- a/gtk/pinentry-gtk.c +++ b/gtk/pinentry-gtk.c @@ -1,4 +1,4 @@ -/* gpinentry.c +/* gpinentry.c * Copyright (C) 2001, 2002 g10 Code GmbH * Copyright (C) 1999 Robert Bihlmeyer * @@ -6,12 +6,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -33,7 +33,7 @@ #ifdef HAVE_GETOPT_H #include -#else +#else #include "getopt.h" #endif /* HAVE_GETOPT_H */ @@ -56,7 +56,7 @@ static GtkWidget *entry, *insure, *time_out; #if 0 /* not used */ /* ok - Return to the command handler routine. */ -static void +static void ok (GtkWidget *w, gpointer data) { gtk_main_quit (); @@ -65,7 +65,7 @@ ok (GtkWidget *w, gpointer data) /* unselect - work around a bug in GTK+ that permits word-selection to work on the invisible passphrase */ -static void +static void unselect(GtkWidget *w, GdkEventButton *e) { static gint lastpos; @@ -82,14 +82,14 @@ unselect(GtkWidget *w, GdkEventButton *e) /* constrain_size - constrain size of the window the window should not shrink beyond the requisition, and should not grow vertically */ -static void +static void constrain_size(GtkWidget *win, GtkRequisition *req, gpointer data) { static gint width, height; GdkGeometry geo; if (req->width == width && req->height == height) - return; + return; width = req->width; height = req->height; geo.min_width = width; @@ -101,19 +101,19 @@ constrain_size(GtkWidget *win, GtkRequisition *req, gpointer data) } /* grab_keyboard - grab the keyboard for maximum security */ -static void +static void grab_keyboard(GtkWidget *win, GdkEvent *event, gpointer data) { if (!pinentry->grab) return; - if (gdk_keyboard_grab(win->window, FALSE, gdk_event_get_time(event))) + if (gdk_keyboard_grab(win->window, FALSE, gdk_event_get_time(event))) { g_error("could not grab keyboard"); } } /* ungrab_keyboard - remove grab */ -static void +static void ungrab_keyboard(GtkWidget *win, GdkEvent *event, gpointer data) { gdk_keyboard_ungrab(gdk_event_get_time(event)); @@ -172,7 +172,7 @@ button_clicked (GtkWidget *widget, gpointer data) } -static void +static void enter_callback (GtkWidget *widget, GtkWidget *anentry) { button_clicked (widget, "ok"); @@ -270,7 +270,7 @@ create_window (int confirm_mode) style = gtk_style_copy(gtk_widget_get_style(w)); style->fg[GTK_STATE_NORMAL] = color[0]; gtk_widget_set_style(w, style); - } + } } ebox = gtk_hbox_new (FALSE, 5); @@ -300,22 +300,22 @@ create_window (int confirm_mode) { sbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(box), sbox, FALSE, FALSE, 0); - + w = gtk_label_new ("Forget secret after"); gtk_box_pack_start(GTK_BOX(sbox), w, FALSE, FALSE, 0); gtk_widget_show(w); - + time_out = gtk_spin_button_new (GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, HUGE_VAL, 1, 60, 60)),2,0); gtk_box_pack_start (GTK_BOX(sbox), time_out, FALSE, FALSE, 0); gtk_widget_show (time_out); - + w = gtk_label_new ("seconds"); - gtk_box_pack_start (GTK_BOX(sbox), w, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(sbox), w, FALSE, FALSE, 0); gtk_widget_show (w); gtk_widget_show (sbox); - + insure = gtk_check_button_new_with_label ("ask before giving out secret"); gtk_box_pack_start (GTK_BOX(box), insure, FALSE, FALSE, 0); @@ -328,7 +328,7 @@ create_window (int confirm_mode) bbox = gtk_hbutton_box_new(); gtk_box_pack_start (GTK_BOX(box), bbox, TRUE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (bbox), 5); - + w = gtk_button_new_with_label (pinentry->ok ? pinentry->ok : "OK"); gtk_container_add (GTK_CONTAINER(bbox), w); if (!confirm_mode) @@ -348,14 +348,14 @@ create_window (int confirm_mode) } gtk_widget_show (w); - + if (!pinentry->one_button) { - w = gtk_button_new_with_label (pinentry->cancel + w = gtk_button_new_with_label (pinentry->cancel ? pinentry->cancel : "Cancel"); gtk_container_add (GTK_CONTAINER(bbox), w); gtk_accel_group_add (acc, GDK_Escape, 0, 0, GTK_OBJECT(w), "clicked"); - gtk_signal_connect (GTK_OBJECT(w), "clicked", + gtk_signal_connect (GTK_OBJECT(w), "clicked", confirm_mode? confirm_button_clicked: button_clicked, NULL); GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); @@ -399,7 +399,7 @@ gtk_cmd_handler (pinentry_t pe) pinentry_cmd_handler_t pinentry_cmd_handler = gtk_cmd_handler; -int +int main (int argc, char *argv[]) { pinentry_init (PGMNAME); @@ -413,12 +413,7 @@ main (int argc, char *argv[]) gtk_init (&argc, &argv); #endif - /* Consumes all arguments. */ - if (pinentry_parse_opts (argc, argv)) - { - printf ("pinentry-gtk (pinentry) " VERSION "\n"); - exit (EXIT_SUCCESS); - } + pinentry_parse_opts (argc, argv); if (pinentry_loop ()) return 1; diff --git a/pinentry/Makefile.am b/pinentry/Makefile.am index 5516d52..c3926b2 100644 --- a/pinentry/Makefile.am +++ b/pinentry/Makefile.am @@ -31,5 +31,5 @@ noinst_LIBRARIES = libpinentry.a $(pinentry_curses) AM_CPPFLAGS = -I$(top_srcdir)/assuan -I$(top_srcdir)/secmem -libpinentry_a_SOURCES = pinentry.h pinentry.c +libpinentry_a_SOURCES = pinentry.h pinentry.c argparse.c argparse.h libpinentry_curses_a_SOURCES = pinentry-curses.h pinentry-curses.c diff --git a/pinentry/argparse.c b/pinentry/argparse.c new file mode 100644 index 0000000..e31b67e --- /dev/null +++ b/pinentry/argparse.c @@ -0,0 +1,1607 @@ +/* [argparse.c wk 17.06.97] Argument Parser for option handling + * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc. + * Copyright (C) 1997-2001, 2006-2008, 2013-2015 Werner Koch + * + * This file is part of JNLIB, which is a subsystem of GnuPG. + * + * JNLIB is free software; you can redistribute it and/or modify it + * under the terms of either + * + * - the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * or + * + * - the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * or both in parallel, as here. + * + * JNLIB 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 copies of the GNU General Public License + * and the GNU Lesser General Public License along with this program; + * if not, see . + */ + +/* This file may be used as part of GnuPG or standalone. A GnuPG + build is detected by the presence of the macro GNUPG_MAJOR_VERSION. + Some feature are only availalbe in the GnuPG build mode. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef GNUPG_MAJOR_VERSION +# include "libjnlib-config.h" +# include "mischelp.h" +# include "stringhelp.h" +# include "logging.h" +# ifdef JNLIB_NEED_UTF8CONV +# include "utf8conv.h" +# endif +#endif /*GNUPG_MAJOR_VERSION*/ + +#include "argparse.h" + +/* GnuPG uses GPLv3+ but a standalone version of this defaults to + GPLv2+ because that is the license of this file. Change this if + you include it in a program which uses GPLv3. If you don't want to + set a a copyright string for your usage() you may also hardcode it + here. */ +#ifndef GNUPG_MAJOR_VERSION + +# define ARGPARSE_GPL_VERSION 2 +# define ARGPARSE_CRIGHT_STR "Copyright (C) YEAR NAME" + +#else /* Used by GnuPG */ + +# define ARGPARSE_GPL_VERSION 3 +# define ARGPARSE_CRIGHT_STR "Copyright (C) 2015 Free Software Foundation, Inc." + +#endif /*GNUPG_MAJOR_VERSION*/ + +/* Replacements for standalone builds. */ +#ifndef GNUPG_MAJOR_VERSION +# ifndef _ +# define _(a) (a) +# endif +# ifndef DIM +# define DIM(v) (sizeof(v)/sizeof((v)[0])) +# endif +# define jnlib_malloc(a) malloc ((a)) +# define jnlib_realloc(a,b) realloc ((a), (b)) +# define jnlib_strdup(a) strdup ((a)) +# define jnlib_free(a) free ((a)) +# define jnlib_log_error my_log_error +# define jnlib_log_bug my_log_bug +# define trim_spaces(a) my_trim_spaces ((a)) +# define map_static_macro_string(a) (a) +#endif /*!GNUPG_MAJOR_VERSION*/ + + +#define ARGPARSE_STR(v) #v +#define ARGPARSE_STR2(v) ARGPARSE_STR(v) + + +/* Replacements for standalone builds. */ +#ifndef GNUPG_MAJOR_VERSION +static void +my_log_error (const char *fmt, ...) +{ + va_list arg_ptr ; + + va_start (arg_ptr, fmt); + fprintf (stderr, "%s: ", strusage (11)); + vfprintf (stderr, fmt, arg_ptr); + va_end (arg_ptr); +} + +static void +my_log_bug (const char *fmt, ...) +{ + va_list arg_ptr ; + + va_start (arg_ptr, fmt); + fprintf (stderr, "%s: Ohhhh jeeee: ", strusage (11)); + vfprintf (stderr, fmt, arg_ptr); + va_end (arg_ptr); + abort (); +} + +static char * +my_trim_spaces (char *str) +{ + char *string, *p, *mark; + + string = str; + /* Find first non space character. */ + for (p=string; *p && isspace (*(unsigned char*)p) ; p++) + ; + /* Move characters. */ + for ((mark = NULL); (*string = *p); string++, p++) + if (isspace (*(unsigned char*)p)) + { + if (!mark) + mark = string; + } + else + mark = NULL; + if (mark) + *mark = '\0' ; /* Remove trailing spaces. */ + + return str ; +} + +#endif /*!GNUPG_MAJOR_VERSION*/ + + + +/********************************* + * @Summary arg_parse + * #include "argparse.h" + * + * typedef struct { + * char *argc; pointer to argc (value subject to change) + * char ***argv; pointer to argv (value subject to change) + * unsigned flags; Global flags (DO NOT CHANGE) + * int err; print error about last option + * 1 = warning, 2 = abort + * int r_opt; return option + * int r_type; type of return value (0 = no argument found) + * union { + * int ret_int; + * long ret_long + * ulong ret_ulong; + * char *ret_str; + * } r; Return values + * struct { + * int idx; + * const char *last; + * void *aliases; + * } internal; DO NOT CHANGE + * } ARGPARSE_ARGS; + * + * typedef struct { + * int short_opt; + * const char *long_opt; + * unsigned flags; + * } ARGPARSE_OPTS; + * + * int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts ); + * + * @Description + * This is my replacement for getopt(). See the example for a typical usage. + * Global flags are: + * Bit 0 : Do not remove options form argv + * Bit 1 : Do not stop at last option but return other args + * with r_opt set to -1. + * Bit 2 : Assume options and real args are mixed. + * Bit 3 : Do not use -- to stop option processing. + * Bit 4 : Do not skip the first arg. + * Bit 5 : allow usage of long option with only one dash + * Bit 6 : ignore --version + * all other bits must be set to zero, this value is modified by the + * function, so assume this is write only. + * Local flags (for each option): + * Bit 2-0 : 0 = does not take an argument + * 1 = takes int argument + * 2 = takes string argument + * 3 = takes long argument + * 4 = takes ulong argument + * Bit 3 : argument is optional (r_type will the be set to 0) + * Bit 4 : allow 0x etc. prefixed values. + * Bit 6 : Ignore this option + * Bit 7 : This is a command and not an option + * You stop the option processing by setting opts to NULL, the function will + * then return 0. + * @Return Value + * Returns the args.r_opt or 0 if ready + * r_opt may be -2/-7 to indicate an unknown option/command. + * @See Also + * ArgExpand + * @Notes + * You do not need to process the options 'h', '--help' or '--version' + * because this function includes standard help processing; but if you + * specify '-h', '--help' or '--version' you have to do it yourself. + * The option '--' stops argument processing; if bit 1 is set the function + * continues to return normal arguments. + * To process float args or unsigned args you must use a string args and do + * the conversion yourself. + * @Example + * + * ARGPARSE_OPTS opts[] = { + * { 'v', "verbose", 0 }, + * { 'd', "debug", 0 }, + * { 'o', "output", 2 }, + * { 'c', "cross-ref", 2|8 }, + * { 'm', "my-option", 1|8 }, + * { 300, "ignored-long-option, ARGPARSE_OP_IGNORE}, + * { 500, "have-no-short-option-for-this-long-option", 0 }, + * {0} }; + * ARGPARSE_ARGS pargs = { &argc, &argv, 0 } + * + * while( ArgParse( &pargs, &opts) ) { + * switch( pargs.r_opt ) { + * case 'v': opt.verbose++; break; + * case 'd': opt.debug++; break; + * case 'o': opt.outfile = pargs.r.ret_str; break; + * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; + * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; + * case 500: opt.a_long_one++; break + * default : pargs.err = 1; break; -- force warning output -- + * } + * } + * if( argc > 1 ) + * log_fatal( "Too many args"); + * + */ + +typedef struct alias_def_s *ALIAS_DEF; +struct alias_def_s { + ALIAS_DEF next; + char *name; /* malloced buffer with name, \0, value */ + const char *value; /* ptr into name */ +}; + + +/* Object to store the names for the --ignore-invalid-option option. + This is a simple linked list. */ +typedef struct iio_item_def_s *IIO_ITEM_DEF; +struct iio_item_def_s +{ + IIO_ITEM_DEF next; + char name[1]; /* String with the long option name. */ +}; + +static const char *(*strusage_handler)( int ) = NULL; +static int (*custom_outfnc) (int, const char *); + +static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s); +static void show_help(ARGPARSE_OPTS *opts, unsigned flags); +static void show_version(void); +static int writestrings (int is_error, const char *string, ...) +#if __GNUC__ >= 4 + __attribute__ ((sentinel(0))) +#endif + ; + + +void +argparse_register_outfnc (int (*fnc)(int, const char *)) +{ + custom_outfnc = fnc; +} + + +/* Write STRING and all following const char * arguments either to + stdout or, if IS_ERROR is set, to stderr. The list of strings must + be terminated by a NULL. */ +static int +writestrings (int is_error, const char *string, ...) +{ + va_list arg_ptr; + const char *s; + int count = 0; + + if (string) + { + s = string; + va_start (arg_ptr, string); + do + { + if (custom_outfnc) + custom_outfnc (is_error? 2:1, s); + else + fputs (s, is_error? stderr : stdout); + count += strlen (s); + } + while ((s = va_arg (arg_ptr, const char *))); + va_end (arg_ptr); + } + return count; +} + + +static void +flushstrings (int is_error) +{ + if (custom_outfnc) + custom_outfnc (is_error? 2:1, NULL); + else + fflush (is_error? stderr : stdout); +} + + +static void +initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) +{ + if( !(arg->flags & (1<<15)) ) + { + /* Initialize this instance. */ + arg->internal.idx = 0; + arg->internal.last = NULL; + arg->internal.inarg = 0; + arg->internal.stopped = 0; + arg->internal.aliases = NULL; + arg->internal.cur_alias = NULL; + arg->internal.iio_list = NULL; + arg->err = 0; + arg->flags |= 1<<15; /* Mark as initialized. */ + if ( *arg->argc < 0 ) + jnlib_log_bug ("invalid argument for arg_parse\n"); + } + + + if (arg->err) + { + /* Last option was erroneous. */ + const char *s; + + if (filename) + { + if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG ) + s = _("argument not expected"); + else if ( arg->r_opt == ARGPARSE_READ_ERROR ) + s = _("read error"); + else if ( arg->r_opt == ARGPARSE_KEYWORD_TOO_LONG ) + s = _("keyword too long"); + else if ( arg->r_opt == ARGPARSE_MISSING_ARG ) + s = _("missing argument"); + else if ( arg->r_opt == ARGPARSE_INVALID_ARG ) + s = _("invalid argument"); + else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND ) + s = _("invalid command"); + else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS ) + s = _("invalid alias definition"); + else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE ) + s = _("out of core"); + else + s = _("invalid option"); + jnlib_log_error ("%s:%u: %s\n", filename, *lineno, s); + } + else + { + s = arg->internal.last? arg->internal.last:"[??]"; + + if ( arg->r_opt == ARGPARSE_MISSING_ARG ) + jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s); + else if ( arg->r_opt == ARGPARSE_INVALID_ARG ) + jnlib_log_error (_("invalid argument for option \"%.50s\"\n"), s); + else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG ) + jnlib_log_error (_("option \"%.50s\" does not expect an " + "argument\n"), s ); + else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND ) + jnlib_log_error (_("invalid command \"%.50s\"\n"), s); + else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_OPTION ) + jnlib_log_error (_("option \"%.50s\" is ambiguous\n"), s); + else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_COMMAND ) + jnlib_log_error (_("command \"%.50s\" is ambiguous\n"),s ); + else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE ) + jnlib_log_error ("%s\n", _("out of core\n")); + else + jnlib_log_error (_("invalid option \"%.50s\"\n"), s); + } + if (arg->err != ARGPARSE_PRINT_WARNING) + exit (2); + arg->err = 0; + } + + /* Zero out the return value union. */ + arg->r.ret_str = NULL; + arg->r.ret_long = 0; +} + + +static void +store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) +{ + /* TODO: replace this dummy function with a rea one + * and fix the probelms IRIX has with (ALIAS_DEV)arg.. + * used as lvalue + */ + (void)arg; + (void)name; + (void)value; +#if 0 + ALIAS_DEF a = jnlib_xmalloc( sizeof *a ); + a->name = name; + a->value = value; + a->next = (ALIAS_DEF)arg->internal.aliases; + (ALIAS_DEF)arg->internal.aliases = a; +#endif +} + + +/* Return true if KEYWORD is in the ignore-invalid-option list. */ +static int +ignore_invalid_option_p (ARGPARSE_ARGS *arg, const char *keyword) +{ + IIO_ITEM_DEF item = arg->internal.iio_list; + + for (; item; item = item->next) + if (!strcmp (item->name, keyword)) + return 1; + return 0; +} + + +/* Add the keywords up to the next LF to the list of to be ignored + options. After returning FP will either be at EOF or the next + character read wll be the first of a new line. The function + returns 0 on success or true on malloc failure. */ +static int +ignore_invalid_option_add (ARGPARSE_ARGS *arg, FILE *fp) +{ + IIO_ITEM_DEF item; + int c; + char name[100]; + int namelen = 0; + int ready = 0; + enum { skipWS, collectNAME, skipNAME, addNAME} state = skipWS; + + while (!ready) + { + c = getc (fp); + if (c == '\n') + ready = 1; + else if (c == EOF) + { + c = '\n'; + ready = 1; + } + again: + switch (state) + { + case skipWS: + if (!isascii (c) || !isspace(c)) + { + namelen = 0; + state = collectNAME; + goto again; + } + break; + + case collectNAME: + if (isspace (c)) + { + state = addNAME; + goto again; + } + else if (namelen < DIM(name)-1) + name[namelen++] = c; + else /* Too long. */ + state = skipNAME; + break; + + case skipNAME: + if (isspace (c)) + { + state = skipWS; + goto again; + } + break; + + case addNAME: + name[namelen] = 0; + if (!ignore_invalid_option_p (arg, name)) + { + item = jnlib_malloc (sizeof *item + namelen); + if (!item) + return 1; + strcpy (item->name, name); + item->next = (IIO_ITEM_DEF)arg->internal.iio_list; + arg->internal.iio_list = item; + } + state = skipWS; + goto again; + } + } + return 0; +} + + +/* Clear the entire ignore-invalid-option list. */ +static void +ignore_invalid_option_clear (ARGPARSE_ARGS *arg) +{ + IIO_ITEM_DEF item, tmpitem; + + for (item = arg->internal.iio_list; item; item = tmpitem) + { + tmpitem = item->next; + jnlib_free (item); + } + arg->internal.iio_list = NULL; +} + + + +/**************** + * Get options from a file. + * Lines starting with '#' are comment lines. + * Syntax is simply a keyword and the argument. + * Valid keywords are all keywords from the long_opt list without + * the leading dashes. The special keywords "help", "warranty" and "version" + * are not valid here. + * The special keyword "alias" may be used to store alias definitions, + * which are later expanded like long options. + * The option + * ignore-invalid-option OPTIONNAMEs + * is recognized and updates a list of option which should be ignored if they + * are not defined. + * Caller must free returned strings. + * If called with FP set to NULL command line args are parse instead. + * + * Q: Should we allow the syntax + * keyword = value + * and accept for boolean options a value of 1/0, yes/no or true/false? + * Note: Abbreviation of options is here not allowed. + */ +int +optfile_parse (FILE *fp, const char *filename, unsigned *lineno, + ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) +{ + int state, i, c; + int idx=0; + char keyword[100]; + char *buffer = NULL; + size_t buflen = 0; + int in_alias=0; + + if (!fp) /* Divert to to arg_parse() in this case. */ + return arg_parse (arg, opts); + + initialize (arg, filename, lineno); + + /* Find the next keyword. */ + state = i = 0; + for (;;) + { + c = getc (fp); + if (c == '\n' || c== EOF ) + { + if ( c != EOF ) + ++*lineno; + if (state == -1) + break; + else if (state == 2) + { + keyword[i] = 0; + for (i=0; opts[i].short_opt; i++ ) + { + if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword)) + break; + } + idx = i; + arg->r_opt = opts[idx].short_opt; + if ((opts[idx].flags & ARGPARSE_OPT_IGNORE)) + { + state = i = 0; + continue; + } + else if (!opts[idx].short_opt ) + { + if (!strcmp (keyword, "ignore-invalid-option")) + { + /* No argument - ignore this meta option. */ + state = i = 0; + continue; + } + else if (ignore_invalid_option_p (arg, keyword)) + { + /* This invalid option is in the iio list. */ + state = i = 0; + continue; + } + arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) + ? ARGPARSE_INVALID_COMMAND + : ARGPARSE_INVALID_OPTION); + } + else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK)) + arg->r_type = 0; /* Does not take an arg. */ + else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL) ) + arg->r_type = 0; /* Arg is optional. */ + else + arg->r_opt = ARGPARSE_MISSING_ARG; + + break; + } + else if (state == 3) + { + /* No argument found. */ + if (in_alias) + arg->r_opt = ARGPARSE_MISSING_ARG; + else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK)) + arg->r_type = 0; /* Does not take an arg. */ + else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL)) + arg->r_type = 0; /* No optional argument. */ + else + arg->r_opt = ARGPARSE_MISSING_ARG; + + break; + } + else if (state == 4) + { + /* Has an argument. */ + if (in_alias) + { + if (!buffer) + arg->r_opt = ARGPARSE_UNEXPECTED_ARG; + else + { + char *p; + + buffer[i] = 0; + p = strpbrk (buffer, " \t"); + if (p) + { + *p++ = 0; + trim_spaces (p); + } + if (!p || !*p) + { + jnlib_free (buffer); + arg->r_opt = ARGPARSE_INVALID_ALIAS; + } + else + { + store_alias (arg, buffer, p); + } + } + } + else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK)) + arg->r_opt = ARGPARSE_UNEXPECTED_ARG; + else + { + char *p; + + if (!buffer) + { + keyword[i] = 0; + buffer = jnlib_strdup (keyword); + if (!buffer) + arg->r_opt = ARGPARSE_OUT_OF_CORE; + } + else + buffer[i] = 0; + + if (buffer) + { + trim_spaces (buffer); + p = buffer; + if (*p == '"') + { + /* Remove quotes. */ + p++; + if (*p && p[strlen(p)-1] == '\"' ) + p[strlen(p)-1] = 0; + } + if (!set_opt_arg (arg, opts[idx].flags, p)) + jnlib_free(buffer); + } + } + break; + } + else if (c == EOF) + { + ignore_invalid_option_clear (arg); + if (ferror (fp)) + arg->r_opt = ARGPARSE_READ_ERROR; + else + arg->r_opt = 0; /* EOF. */ + break; + } + state = 0; + i = 0; + } + else if (state == -1) + ; /* Skip. */ + else if (state == 0 && isascii (c) && isspace(c)) + ; /* Skip leading white space. */ + else if (state == 0 && c == '#' ) + state = 1; /* Start of a comment. */ + else if (state == 1) + ; /* Skip comments. */ + else if (state == 2 && isascii (c) && isspace(c)) + { + /* Check keyword. */ + keyword[i] = 0; + for (i=0; opts[i].short_opt; i++ ) + if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword)) + break; + idx = i; + arg->r_opt = opts[idx].short_opt; + if ((opts[idx].flags & ARGPARSE_OPT_IGNORE)) + { + state = 1; /* Process like a comment. */ + } + else if (!opts[idx].short_opt) + { + if (!strcmp (keyword, "alias")) + { + in_alias = 1; + state = 3; + } + else if (!strcmp (keyword, "ignore-invalid-option")) + { + if (ignore_invalid_option_add (arg, fp)) + { + arg->r_opt = ARGPARSE_OUT_OF_CORE; + break; + } + state = i = 0; + ++*lineno; + } + else if (ignore_invalid_option_p (arg, keyword)) + state = 1; /* Process like a comment. */ + else + { + arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) + ? ARGPARSE_INVALID_COMMAND + : ARGPARSE_INVALID_OPTION); + state = -1; /* Skip rest of line and leave. */ + } + } + else + state = 3; + } + else if (state == 3) + { + /* Skip leading spaces of the argument. */ + if (!isascii (c) || !isspace(c)) + { + i = 0; + keyword[i++] = c; + state = 4; + } + } + else if (state == 4) + { + /* Collect the argument. */ + if (buffer) + { + if (i < buflen-1) + buffer[i++] = c; + else + { + char *tmp; + size_t tmplen = buflen + 50; + + tmp = jnlib_realloc (buffer, tmplen); + if (tmp) + { + buflen = tmplen; + buffer = tmp; + buffer[i++] = c; + } + else + { + jnlib_free (buffer); + arg->r_opt = ARGPARSE_OUT_OF_CORE; + break; + } + } + } + else if (i < DIM(keyword)-1) + keyword[i++] = c; + else + { + size_t tmplen = DIM(keyword) + 50; + buffer = jnlib_malloc (tmplen); + if (buffer) + { + buflen = tmplen; + memcpy(buffer, keyword, i); + buffer[i++] = c; + } + else + { + arg->r_opt = ARGPARSE_OUT_OF_CORE; + break; + } + } + } + else if (i >= DIM(keyword)-1) + { + arg->r_opt = ARGPARSE_KEYWORD_TOO_LONG; + state = -1; /* Skip rest of line and leave. */ + } + else + { + keyword[i++] = c; + state = 2; + } + } + + return arg->r_opt; +} + + + +static int +find_long_option( ARGPARSE_ARGS *arg, + ARGPARSE_OPTS *opts, const char *keyword ) +{ + int i; + size_t n; + + (void)arg; + + /* Would be better if we can do a binary search, but it is not + possible to reorder our option table because we would mess + up our help strings - What we can do is: Build a nice option + lookup table wehn this function is first invoked */ + if( !*keyword ) + return -1; + for(i=0; opts[i].short_opt; i++ ) + if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) + return i; +#if 0 + { + ALIAS_DEF a; + /* see whether it is an alias */ + for( a = args->internal.aliases; a; a = a->next ) { + if( !strcmp( a->name, keyword) ) { + /* todo: must parse the alias here */ + args->internal.cur_alias = a; + return -3; /* alias available */ + } + } + } +#endif + /* not found, see whether it is an abbreviation */ + /* aliases may not be abbreviated */ + n = strlen( keyword ); + for(i=0; opts[i].short_opt; i++ ) { + if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) { + int j; + for(j=i+1; opts[j].short_opt; j++ ) { + if( opts[j].long_opt + && !strncmp( opts[j].long_opt, keyword, n ) ) + return -2; /* abbreviation is ambiguous */ + } + return i; + } + } + return -1; /* Not found. */ +} + +int +arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) +{ + int idx; + int argc; + char **argv; + char *s, *s2; + int i; + + initialize( arg, NULL, NULL ); + argc = *arg->argc; + argv = *arg->argv; + idx = arg->internal.idx; + + if (!idx && argc && !(arg->flags & ARGPARSE_FLAG_ARG0)) + { + /* Skip the first argument. */ + argc--; argv++; idx++; + } + + next_one: + if (!argc) + { + /* No more args. */ + arg->r_opt = 0; + goto leave; /* Ready. */ + } + + s = *argv; + arg->internal.last = s; + + if (arg->internal.stopped && (arg->flags & ARGPARSE_FLAG_ALL)) + { + arg->r_opt = ARGPARSE_IS_ARG; /* Not an option but an argument. */ + arg->r_type = 2; + arg->r.ret_str = s; + argc--; argv++; idx++; /* set to next one */ + } + else if( arg->internal.stopped ) + { + arg->r_opt = 0; + goto leave; /* Ready. */ + } + else if ( *s == '-' && s[1] == '-' ) + { + /* Long option. */ + char *argpos; + + arg->internal.inarg = 0; + if (!s[2] && !(arg->flags & ARGPARSE_FLAG_NOSTOP)) + { + /* Stop option processing. */ + arg->internal.stopped = 1; + arg->flags |= ARGPARSE_FLAG_STOP_SEEN; + argc--; argv++; idx++; + goto next_one; + } + + argpos = strchr( s+2, '=' ); + if ( argpos ) + *argpos = 0; + i = find_long_option ( arg, opts, s+2 ); + if ( argpos ) + *argpos = '='; + + if ( i < 0 && !strcmp ( "help", s+2) ) + show_help (opts, arg->flags); + else if ( i < 0 && !strcmp ( "version", s+2) ) + { + if (!(arg->flags & ARGPARSE_FLAG_NOVERSION)) + { + show_version (); + exit(0); + } + } + else if ( i < 0 && !strcmp( "warranty", s+2)) + { + writestrings (0, strusage (16), "\n", NULL); + exit (0); + } + else if ( i < 0 && !strcmp( "dump-options", s+2) ) + { + for (i=0; opts[i].short_opt; i++ ) + { + if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE)) + writestrings (0, "--", opts[i].long_opt, "\n", NULL); + } + writestrings (0, "--dump-options\n--help\n--version\n--warranty\n", + NULL); + exit (0); + } + + if ( i == -2 ) + arg->r_opt = ARGPARSE_AMBIGUOUS_OPTION; + else if ( i == -1 ) + { + arg->r_opt = ARGPARSE_INVALID_OPTION; + arg->r.ret_str = s+2; + } + else + arg->r_opt = opts[i].short_opt; + if ( i < 0 ) + ; + else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) ) + { + if ( argpos ) + { + s2 = argpos+1; + if ( !*s2 ) + s2 = NULL; + } + else + s2 = argv[1]; + if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) ) + { + arg->r_type = ARGPARSE_TYPE_NONE; /* Argument is optional. */ + } + else if ( !s2 ) + { + arg->r_opt = ARGPARSE_MISSING_ARG; + } + else if ( !argpos && *s2 == '-' + && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) ) + { + /* The argument is optional and the next seems to be an + option. We do not check this possible option but + assume no argument */ + arg->r_type = ARGPARSE_TYPE_NONE; + } + else + { + set_opt_arg (arg, opts[i].flags, s2); + if ( !argpos ) + { + argc--; argv++; idx++; /* Skip one. */ + } + } + } + else + { + /* Does not take an argument. */ + if ( argpos ) + arg->r_type = ARGPARSE_UNEXPECTED_ARG; + else + arg->r_type = 0; + } + argc--; argv++; idx++; /* Set to next one. */ + } + else if ( (*s == '-' && s[1]) || arg->internal.inarg ) + { + /* Short option. */ + int dash_kludge = 0; + + i = 0; + if ( !arg->internal.inarg ) + { + arg->internal.inarg++; + if ( (arg->flags & ARGPARSE_FLAG_ONEDASH) ) + { + for (i=0; opts[i].short_opt; i++ ) + if ( opts[i].long_opt && !strcmp (opts[i].long_opt, s+1)) + { + dash_kludge = 1; + break; + } + } + } + s += arg->internal.inarg; + + if (!dash_kludge ) + { + for (i=0; opts[i].short_opt; i++ ) + if ( opts[i].short_opt == *s ) + break; + } + + if ( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) ) + show_help (opts, arg->flags); + + arg->r_opt = opts[i].short_opt; + if (!opts[i].short_opt ) + { + arg->r_opt = (opts[i].flags & ARGPARSE_OPT_COMMAND)? + ARGPARSE_INVALID_COMMAND:ARGPARSE_INVALID_OPTION; + arg->internal.inarg++; /* Point to the next arg. */ + arg->r.ret_str = s; + } + else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) ) + { + if ( s[1] && !dash_kludge ) + { + s2 = s+1; + set_opt_arg (arg, opts[i].flags, s2); + } + else + { + s2 = argv[1]; + if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) ) + { + arg->r_type = ARGPARSE_TYPE_NONE; + } + else if ( !s2 ) + { + arg->r_opt = ARGPARSE_MISSING_ARG; + } + else if ( *s2 == '-' && s2[1] + && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) ) + { + /* The argument is optional and the next seems to + be an option. We do not check this possible + option but assume no argument. */ + arg->r_type = ARGPARSE_TYPE_NONE; + } + else + { + set_opt_arg (arg, opts[i].flags, s2); + argc--; argv++; idx++; /* Skip one. */ + } + } + s = "x"; /* This is so that !s[1] yields false. */ + } + else + { + /* Does not take an argument. */ + arg->r_type = ARGPARSE_TYPE_NONE; + arg->internal.inarg++; /* Point to the next arg. */ + } + if ( !s[1] || dash_kludge ) + { + /* No more concatenated short options. */ + arg->internal.inarg = 0; + argc--; argv++; idx++; + } + } + else if ( arg->flags & ARGPARSE_FLAG_MIXED ) + { + arg->r_opt = ARGPARSE_IS_ARG; + arg->r_type = 2; + arg->r.ret_str = s; + argc--; argv++; idx++; /* Set to next one. */ + } + else + { + arg->internal.stopped = 1; /* Stop option processing. */ + goto next_one; + } + + leave: + *arg->argc = argc; + *arg->argv = argv; + arg->internal.idx = idx; + return arg->r_opt; +} + + +/* Returns: -1 on error, 0 for an integer type and 1 for a non integer + type argument. */ +static int +set_opt_arg (ARGPARSE_ARGS *arg, unsigned flags, char *s) +{ + int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10; + long l; + + switch ( (arg->r_type = (flags & ARGPARSE_TYPE_MASK)) ) + { + case ARGPARSE_TYPE_LONG: + case ARGPARSE_TYPE_INT: + errno = 0; + l = strtol (s, NULL, base); + if ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + if (arg->r_type == ARGPARSE_TYPE_LONG) + arg->r.ret_long = l; + else if ( (l < 0 && l < INT_MIN) || l > INT_MAX ) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + else + arg->r.ret_int = (int)l; + return 0; + + case ARGPARSE_TYPE_ULONG: + while (isascii (*s) && isspace(*s)) + s++; + if (*s == '-') + { + arg->r.ret_ulong = 0; + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + errno = 0; + arg->r.ret_ulong = strtoul (s, NULL, base); + if (arg->r.ret_ulong == ULONG_MAX && errno == ERANGE) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + return 0; + + case ARGPARSE_TYPE_STRING: + default: + arg->r.ret_str = s; + return 1; + } +} + + +static size_t +long_opt_strlen( ARGPARSE_OPTS *o ) +{ + size_t n = strlen (o->long_opt); + + if ( o->description && *o->description == '|' ) + { + const char *s; +#ifdef JNLIB_NEED_UTF8CONV + int is_utf8 = is_native_utf8 (); +#endif + + s=o->description+1; + if ( *s != '=' ) + n++; + /* For a (mostly) correct length calculation we exclude + continuation bytes (10xxxxxx) if we are on a native utf8 + terminal. */ + for (; *s && *s != '|'; s++ ) +#ifdef JNLIB_NEED_UTF8CONV + if ( is_utf8 && (*s&0xc0) != 0x80 ) +#endif + n++; + } + return n; +} + + +/**************** + * Print formatted help. The description string has some special + * meanings: + * - A description string which is "@" suppresses help output for + * this option + * - a description,ine which starts with a '@' and is followed by + * any other characters is printed as is; this may be used for examples + * ans such. + * - A description which starts with a '|' outputs the string between this + * bar and the next one as arguments of the long option. + */ +static void +show_help (ARGPARSE_OPTS *opts, unsigned int flags) +{ + const char *s; + char tmp[2]; + + show_version (); + writestrings (0, "\n", NULL); + s = strusage (42); + if (s && *s == '1') + { + s = strusage (40); + writestrings (1, s, NULL); + if (*s && s[strlen(s)] != '\n') + writestrings (1, "\n", NULL); + } + s = strusage(41); + writestrings (0, s, "\n", NULL); + if ( opts[0].description ) + { + /* Auto format the option description. */ + int i,j, indent; + + /* Get max. length of long options. */ + for (i=indent=0; opts[i].short_opt; i++ ) + { + if ( opts[i].long_opt ) + if ( !opts[i].description || *opts[i].description != '@' ) + if ( (j=long_opt_strlen(opts+i)) > indent && j < 35 ) + indent = j; + } + + /* Example: " -v, --verbose Viele Sachen ausgeben" */ + indent += 10; + if ( *opts[0].description != '@' ) + writestrings (0, "Options:", "\n", NULL); + for (i=0; opts[i].short_opt; i++ ) + { + s = map_static_macro_string (_( opts[i].description )); + if ( s && *s== '@' && !s[1] ) /* Hide this line. */ + continue; + if ( s && *s == '@' ) /* Unindented comment only line. */ + { + for (s++; *s; s++ ) + { + if ( *s == '\n' ) + { + if( s[1] ) + writestrings (0, "\n", NULL); + } + else + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } + } + writestrings (0, "\n", NULL); + continue; + } + + j = 3; + if ( opts[i].short_opt < 256 ) + { + tmp[0] = opts[i].short_opt; + tmp[1] = 0; + writestrings (0, " -", tmp, NULL ); + if ( !opts[i].long_opt ) + { + if (s && *s == '|' ) + { + writestrings (0, " ", NULL); j++; + for (s++ ; *s && *s != '|'; s++, j++ ) + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } + if ( *s ) + s++; + } + } + } + else + writestrings (0, " ", NULL); + if ( opts[i].long_opt ) + { + tmp[0] = opts[i].short_opt < 256?',':' '; + tmp[1] = 0; + j += writestrings (0, tmp, " --", opts[i].long_opt, NULL); + if (s && *s == '|' ) + { + if ( *++s != '=' ) + { + writestrings (0, " ", NULL); + j++; + } + for ( ; *s && *s != '|'; s++, j++ ) + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } + if ( *s ) + s++; + } + writestrings (0, " ", NULL); + j += 3; + } + for (;j < indent; j++ ) + writestrings (0, " ", NULL); + if ( s ) + { + if ( *s && j > indent ) + { + writestrings (0, "\n", NULL); + for (j=0;j < indent; j++ ) + writestrings (0, " ", NULL); + } + for (; *s; s++ ) + { + if ( *s == '\n' ) + { + if ( s[1] ) + { + writestrings (0, "\n", NULL); + for (j=0; j < indent; j++ ) + writestrings (0, " ", NULL); + } + } + else + { + tmp[0] = *s; + tmp[1] = 0; + writestrings (0, tmp, NULL); + } + } + } + writestrings (0, "\n", NULL); + } + if ( (flags & ARGPARSE_FLAG_ONEDASH) ) + writestrings (0, "\n(A single dash may be used " + "instead of the double ones)\n", NULL); + } + if ( (s=strusage(19)) ) + { + writestrings (0, "\n", NULL); + writestrings (0, s, NULL); + } + flushstrings (0); + exit(0); +} + +static void +show_version () +{ + const char *s; + int i; + + /* Version line. */ + writestrings (0, strusage (11), NULL); + if ((s=strusage (12))) + writestrings (0, " (", s, ")", NULL); + writestrings (0, " ", strusage (13), "\n", NULL); + /* Additional version lines. */ + for (i=20; i < 30; i++) + if ((s=strusage (i))) + writestrings (0, s, "\n", NULL); + /* Copyright string. */ + if ((s=strusage (14))) + writestrings (0, s, "\n", NULL); + /* Licence string. */ + if( (s=strusage (10)) ) + writestrings (0, s, "\n", NULL); + /* Copying conditions. */ + if ( (s=strusage(15)) ) + writestrings (0, s, NULL); + /* Thanks. */ + if ((s=strusage(18))) + writestrings (0, s, NULL); + /* Additional program info. */ + for (i=30; i < 40; i++ ) + if ( (s=strusage (i)) ) + writestrings (0, s, NULL); + flushstrings (0); +} + + +void +usage (int level) +{ + const char *p; + + if (!level) + { + writestrings (1, strusage(11), " ", strusage(13), "; ", + strusage (14), "\n", NULL); + flushstrings (1); + } + else if (level == 1) + { + p = strusage (40); + writestrings (1, p, NULL); + if (*p && p[strlen(p)] != '\n') + writestrings (1, "\n", NULL); + exit (2); + } + else if (level == 2) + { + p = strusage (42); + if (p && *p == '1') + { + p = strusage (40); + writestrings (1, p, NULL); + if (*p && p[strlen(p)] != '\n') + writestrings (1, "\n", NULL); + } + writestrings (0, strusage(41), "\n", NULL); + exit (0); + } +} + +/* Level + * 0: Print copyright string to stderr + * 1: Print a short usage hint to stderr and terminate + * 2: Print a long usage hint to stdout and terminate + * 10: Return license info string + * 11: Return the name of the program + * 12: Return optional name of package which includes this program. + * 13: version string + * 14: copyright string + * 15: Short copying conditions (with LFs) + * 16: Long copying conditions (with LFs) + * 17: Optional printable OS name + * 18: Optional thanks list (with LFs) + * 19: Bug report info + *20..29: Additional lib version strings. + *30..39: Additional program info (with LFs) + * 40: short usage note (with LF) + * 41: long usage note (with LF) + * 42: Flag string: + * First char is '1': + * The short usage notes needs to be printed + * before the long usage note. + */ +const char * +strusage( int level ) +{ + const char *p = strusage_handler? strusage_handler(level) : NULL; + + if ( p ) + return map_static_macro_string (p); + + switch ( level ) + { + + case 10: +#if ARGPARSE_GPL_VERSION == 3 + p = ("License GPLv3+: GNU GPL version 3 or later " + ""); +#else + p = ("License GPLv2+: GNU GPL version 2 or later " + ""); +#endif + break; + case 11: p = "foo"; break; + case 13: p = "0.0"; break; + case 14: p = ARGPARSE_CRIGHT_STR; break; + case 15: p = +"This is free software: you are free to change and redistribute it.\n" +"There is NO WARRANTY, to the extent permitted by law.\n"; + break; + case 16: p = +"This is free software; you can redistribute it and/or modify\n" +"it under the terms of the GNU General Public License as published by\n" +"the Free Software Foundation; either version " +ARGPARSE_STR2(ARGPARSE_GPL_VERSION) +" of the License, or\n" +"(at your option) any later version.\n\n" +"It is distributed in the hope that it will be useful,\n" +"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +"GNU General Public License for more details.\n\n" +"You should have received a copy of the GNU General Public License\n" +"along with this software. If not, see .\n"; + break; + case 40: /* short and long usage */ + case 41: p = ""; break; + } + + return p; +} + + +/* Set the usage handler. This function is basically a constructor. */ +void +set_strusage ( const char *(*f)( int ) ) +{ + strusage_handler = f; +} + + +#ifdef TEST +static struct { + int verbose; + int debug; + char *outfile; + char *crf; + int myopt; + int echo; + int a_long_one; +} opt; + +int +main(int argc, char **argv) +{ + ARGPARSE_OPTS opts[] = { + ARGPARSE_x('v', "verbose", NONE, 0, "Laut sein"), + ARGPARSE_s_n('e', "echo" , ("Zeile ausgeben, damit wir sehen, " + "was wir eingegeben haben")), + ARGPARSE_s_n('d', "debug", "Debug\nfalls mal etwas\nschief geht"), + ARGPARSE_s_s('o', "output", 0 ), + ARGPARSE_o_s('c', "cross-ref", "cross-reference erzeugen\n" ), + /* Note that on a non-utf8 terminal the ? might garble the output. */ + ARGPARSE_s_n('s', "street","|Stra?e|set the name of the street to Stra?e"), + ARGPARSE_o_i('m', "my-option", 0), + ARGPARSE_s_n(500, "a-long-option", 0 ), + ARGPARSE_end() + }; + ARGPARSE_ARGS pargs = { &argc, &argv, (ARGPARSE_FLAG_ALL + | ARGPARSE_FLAG_MIXED + | ARGPARSE_FLAG_ONEDASH) }; + int i; + + while (arg_parse (&pargs, opts)) + { + switch (pargs.r_opt) + { + case ARGPARSE_IS_ARG : + printf ("arg='%s'\n", pargs.r.ret_str); + break; + case 'v': opt.verbose++; break; + case 'e': opt.echo++; break; + case 'd': opt.debug++; break; + case 'o': opt.outfile = pargs.r.ret_str; break; + case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; + case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; + case 500: opt.a_long_one++; break; + default : pargs.err = ARGPARSE_PRINT_WARNING; break; + } + } + for (i=0; i < argc; i++ ) + printf ("%3d -> (%s)\n", i, argv[i] ); + puts ("Options:"); + if (opt.verbose) + printf (" verbose=%d\n", opt.verbose ); + if (opt.debug) + printf (" debug=%d\n", opt.debug ); + if (opt.outfile) + printf (" outfile='%s'\n", opt.outfile ); + if (opt.crf) + printf (" crffile='%s'\n", opt.crf ); + if (opt.myopt) + printf (" myopt=%d\n", opt.myopt ); + if (opt.a_long_one) + printf (" a-long-one=%d\n", opt.a_long_one ); + if (opt.echo) + printf (" echo=%d\n", opt.echo ); + + return 0; +} +#endif /*TEST*/ + +/**** bottom of file ****/ diff --git a/pinentry/argparse.h b/pinentry/argparse.h new file mode 100644 index 0000000..b4dc253 --- /dev/null +++ b/pinentry/argparse.h @@ -0,0 +1,203 @@ +/* argparse.h - Argument parser for option handling. + * Copyright (C) 1998,1999,2000,2001,2006 Free Software Foundation, Inc. + * + * This file is part of JNLIB, which is a subsystem of GnuPG. + * + * JNLIB is free software; you can redistribute it and/or modify it + * under the terms of either + * + * - the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * or + * + * - the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * or both in parallel, as here. + * + * JNLIB 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 copies of the GNU General Public License + * and the GNU Lesser General Public License along with this program; + * if not, see . + */ + +#ifndef LIBJNLIB_ARGPARSE_H +#define LIBJNLIB_ARGPARSE_H + +#include + +typedef struct +{ + int *argc; /* Pointer to ARGC (value subject to change). */ + char ***argv; /* Pointer to ARGV (value subject to change). */ + unsigned int flags; /* Global flags. May be set prior to calling the + parser. The parser may change the value. */ + int err; /* Print error description for last option. + Either 0, ARGPARSE_PRINT_WARNING or + ARGPARSE_PRINT_ERROR. */ + + int r_opt; /* Returns option code. */ + int r_type; /* Returns type of option value. */ + union { + int ret_int; + long ret_long; + unsigned long ret_ulong; + char *ret_str; + } r; /* Return values */ + + struct { + int idx; + int inarg; + int stopped; + const char *last; + void *aliases; + const void *cur_alias; + void *iio_list; + } internal; /* Private - do not change. */ +} ARGPARSE_ARGS; + +typedef struct +{ + int short_opt; + const char *long_opt; + unsigned int flags; + const char *description; /* Optional option description. */ +} ARGPARSE_OPTS; + + +/* Global flags (ARGPARSE_ARGS). */ +#define ARGPARSE_FLAG_KEEP 1 /* Do not remove options form argv. */ +#define ARGPARSE_FLAG_ALL 2 /* Do not stop at last option but return + remaining args with R_OPT set to -1. */ +#define ARGPARSE_FLAG_MIXED 4 /* Assume options and args are mixed. */ +#define ARGPARSE_FLAG_NOSTOP 8 /* Do not stop processing at "--". */ +#define ARGPARSE_FLAG_ARG0 16 /* Do not skip the first arg. */ +#define ARGPARSE_FLAG_ONEDASH 32 /* Allow long options with one dash. */ +#define ARGPARSE_FLAG_NOVERSION 64 /* No output for "--version". */ + +#define ARGPARSE_FLAG_STOP_SEEN 256 /* Set to true if a "--" has been seen. */ + +/* Flags for each option (ARGPARSE_OPTS). The type code may be + ORed with the OPT flags. */ +#define ARGPARSE_TYPE_NONE 0 /* Does not take an argument. */ +#define ARGPARSE_TYPE_INT 1 /* Takes an int argument. */ +#define ARGPARSE_TYPE_STRING 2 /* Takes a string argument. */ +#define ARGPARSE_TYPE_LONG 3 /* Takes a long argument. */ +#define ARGPARSE_TYPE_ULONG 4 /* Takes an unsigned long argument. */ +#define ARGPARSE_OPT_OPTIONAL (1<<3) /* Argument is optional. */ +#define ARGPARSE_OPT_PREFIX (1<<4) /* Allow 0x etc. prefixed values. */ +#define ARGPARSE_OPT_IGNORE (1<<6) /* Ignore command or option. */ +#define ARGPARSE_OPT_COMMAND (1<<7) /* The argument is a command. */ + +#define ARGPARSE_TYPE_MASK 7 /* Mask for the type values (internal). */ + +/* A set of macros to make option definitions easier to read. */ +#define ARGPARSE_x(s,l,t,f,d) \ + { (s), (l), ARGPARSE_TYPE_ ## t | (f), (d) } + +#define ARGPARSE_s(s,l,t,d) \ + { (s), (l), ARGPARSE_TYPE_ ## t, (d) } +#define ARGPARSE_s_n(s,l,d) \ + { (s), (l), ARGPARSE_TYPE_NONE, (d) } +#define ARGPARSE_s_i(s,l,d) \ + { (s), (l), ARGPARSE_TYPE_INT, (d) } +#define ARGPARSE_s_s(s,l,d) \ + { (s), (l), ARGPARSE_TYPE_STRING, (d) } +#define ARGPARSE_s_l(s,l,d) \ + { (s), (l), ARGPARSE_TYPE_LONG, (d) } +#define ARGPARSE_s_u(s,l,d) \ + { (s), (l), ARGPARSE_TYPE_ULONG, (d) } + +#define ARGPARSE_o(s,l,t,d) \ + { (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_OPTIONAL), (d) } +#define ARGPARSE_o_n(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_OPTIONAL), (d) } +#define ARGPARSE_o_i(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_OPTIONAL), (d) } +#define ARGPARSE_o_s(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_OPTIONAL), (d) } +#define ARGPARSE_o_l(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_OPTIONAL), (d) } +#define ARGPARSE_o_u(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_OPTIONAL), (d) } + +#define ARGPARSE_p(s,l,t,d) \ + { (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_p_n(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_p_i(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_p_s(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_p_l(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_p_u(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_PREFIX), (d) } + +#define ARGPARSE_op(s,l,t,d) \ + { (s), (l), (ARGPARSE_TYPE_ ## t \ + | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_op_n(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_NONE \ + | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_op_i(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_INT \ + | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_op_s(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_STRING \ + | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_op_l(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_LONG \ + | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) } +#define ARGPARSE_op_u(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_ULONG \ + | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) } + +#define ARGPARSE_c(s,l,d) \ + { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_COMMAND), (d) } + +#define ARGPARSE_ignore(s,l) \ + { (s), (l), (ARGPARSE_OPT_IGNORE), "@" } + +#define ARGPARSE_group(s,d) \ + { (s), NULL, 0, (d) } + +#define ARGPARSE_end() { 0, NULL, 0, NULL } + + +/* Other constants. */ +#define ARGPARSE_PRINT_WARNING 1 +#define ARGPARSE_PRINT_ERROR 2 + + +/* Error values. */ +#define ARGPARSE_IS_ARG (-1) +#define ARGPARSE_INVALID_OPTION (-2) +#define ARGPARSE_MISSING_ARG (-3) +#define ARGPARSE_KEYWORD_TOO_LONG (-4) +#define ARGPARSE_READ_ERROR (-5) +#define ARGPARSE_UNEXPECTED_ARG (-6) +#define ARGPARSE_INVALID_COMMAND (-7) +#define ARGPARSE_AMBIGUOUS_OPTION (-8) +#define ARGPARSE_AMBIGUOUS_COMMAND (-9) +#define ARGPARSE_INVALID_ALIAS (-10) +#define ARGPARSE_OUT_OF_CORE (-11) +#define ARGPARSE_INVALID_ARG (-12) + + +int arg_parse (ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); +int optfile_parse (FILE *fp, const char *filename, unsigned *lineno, + ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); +void usage (int level); +const char *strusage (int level); +void set_strusage (const char *(*f)( int )); +void argparse_register_outfnc (int (*fnc)(int, const char *)); + +#endif /*LIBJNLIB_ARGPARSE_H*/ diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index 2d73464..22506b6 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -1,5 +1,5 @@ /* pinentry.c - The PIN entry support library - Copyright (C) 2002, 2003, 2007, 2008, 2010 g10 Code GmbH + Copyright (C) 2002, 2003, 2007, 2008, 2010, 2015 g10 Code GmbH This file is part of PINENTRY. @@ -46,6 +46,7 @@ #include "assuan.h" #include "memory.h" #include "secmem-util.h" +#include "argparse.h" #include "pinentry.h" #ifdef HAVE_W32CE_SYSTEM @@ -408,26 +409,46 @@ pinentry_have_display (int argc, char **argv) -static void -usage (void) +/* Print usage information and and provide strings for help. */ +static const char * +my_strusage( int level ) { - fprintf (stdout, "Usage: %s [OPTION]...\n" -"Ask securely for a secret and print it to stdout.\n" -"\n" -" --display DISPLAY Set the X display\n" -" --ttyname PATH Set the tty terminal node name\n" -" --ttytype NAME Set the tty terminal type\n" -" --lc-ctype Set the tty LC_CTYPE value\n" -" --lc-messages Set the tty LC_MESSAGES value\n" -" --timeout SECS Timeout waiting for input after this many seconds\n" -#ifdef ENABLE_ENHANCED -" -e, --enhanced Ask for timeout and insurance, too\n" -#endif -" -g, --no-global-grab Grab keyboard only while window is focused\n" -" --parent-wid Parent window ID (for positioning)\n" -" -d, --debug Turn on debugging output\n" -" -h, --help Display this help and exit\n" -" --version Output version information and exit\n", this_pgmname); + const char *p; + + switch (level) + { + case 11: p = this_pgmname; break; + case 12: p = "pinentry"; break; + case 13: p = PACKAGE_VERSION; break; + case 14: p = "Copyright (C) 2015 g10 Code GmbH"; break; + case 19: p = "Please report bugs to <" PACKAGE_BUGREPORT ">.\n"; break; + case 1: + case 40: + { + static char *str; + + if (!str) + { + size_t n = 50 + strlen (this_pgmname); + str = malloc (n); + if (str) + snprintf (str, n, "Usage: %s [options] (-h for help)", + this_pgmname); + } + p = str; + } + break; + case 41: + p = "Ask securely for a secret and print it to stdout."; + break; + + case 42: + p = "1"; /* Flag print 40 as part of 41. */ + break; + + default: p = NULL; break; + } + return p; } @@ -481,40 +502,37 @@ parse_color (char *arg, pinentry_color_t *color_p, int *bright_p) return new_arg; } -/* Parse the command line options. Returns 1 if user should print - version and exit. Can exit the program if only help output is - requested. */ -int +/* Parse the command line options. May exit the program if only help + or version output is requested. */ +void pinentry_parse_opts (int argc, char *argv[]) { - int opt; - int opt_help = 0; - int opt_version = 0; - struct option opts[] = - {{ "debug", no_argument, 0, 'd' }, - { "display", required_argument, 0, 'D' }, - { "ttyname", required_argument, 0, 'T' }, - { "ttytype", required_argument, 0, 'N' }, - { "lc-ctype", required_argument, 0, 'C' }, - { "lc-messages", required_argument, 0, 'M' }, + static ARGPARSE_OPTS opts[] = { + ARGPARSE_s_n('d', "debug", "Turn on debugging output"), + ARGPARSE_s_s('D', "display", "|DISPLAY|Set the X display"), + ARGPARSE_s_s('T', "ttyname", "|FILE|Set the tty terminal node name"), + ARGPARSE_s_s('N', "ttytype", "|NAME|Set the tty terminal type"), + ARGPARSE_s_s('C', "lc-ctype", "|STRING|Set the tty LC_CTYPE value"), + ARGPARSE_s_s('M', "lc-messages", "|STRING|Set the tty LC_MESSAGES value"), #ifdef ENABLE_ENHANCED - { "enhanced", no_argument, 0, 'e' }, + ARGPARSE_s_n('e', "enhanced", "Ask for timeout and insurance, too"), #endif - { "no-global-grab", no_argument, 0, 'g' }, - { "parent-wid", required_argument, 0, 'W' }, - { "colors", required_argument, 0, 'c' }, - { "help", no_argument, 0, 'h' }, - { "version", no_argument, &opt_version, 1 }, - { "timeout", required_argument, 0, 'o' }, - { NULL, 0, NULL, 0 }}; - - while ((opt = getopt_long (argc, argv, "degh", opts, NULL)) != -1) + ARGPARSE_s_i('o', "timeout", + "|SECS|Timeout waiting for input after this many seconds"), + ARGPARSE_s_n('g', "no-global-grab", + "Grab keyboard only while window is focused"), + ARGPARSE_s_u('W', "parent-wid", "Parent window ID (for positioning)"), + ARGPARSE_s_s('c', "colors", "|STRING|Set custom colors for ncurses"), + ARGPARSE_end() + }; + ARGPARSE_ARGS pargs = { &argc, &argv, 0 }; + + set_strusage (my_strusage); + + while (arg_parse (&pargs, opts)) { - switch (opt) + switch (pargs.r_opt) { - case 0: - case '?': - break; case 'd': pinentry.debug = 1; break; @@ -526,14 +544,11 @@ pinentry_parse_opts (int argc, char *argv[]) case 'g': pinentry.grab = 0; break; - case 'h': - opt_help = 1; - break; case 'D': /* Note, this is currently not used because the GUI engine has already been initialized when parsing these options. */ - pinentry.display = strdup (optarg); + pinentry.display = strdup (pargs.r.ret_str); if (!pinentry.display) { #ifndef HAVE_W32CE_SYSTEM @@ -543,7 +558,7 @@ pinentry_parse_opts (int argc, char *argv[]) } break; case 'T': - pinentry.ttyname = strdup (optarg); + pinentry.ttyname = strdup (pargs.r.ret_str); if (!pinentry.ttyname) { #ifndef HAVE_W32CE_SYSTEM @@ -553,7 +568,7 @@ pinentry_parse_opts (int argc, char *argv[]) } break; case 'N': - pinentry.ttytype = strdup (optarg); + pinentry.ttytype = strdup (pargs.r.ret_str); if (!pinentry.ttytype) { #ifndef HAVE_W32CE_SYSTEM @@ -563,7 +578,7 @@ pinentry_parse_opts (int argc, char *argv[]) } break; case 'C': - pinentry.lc_ctype = strdup (optarg); + pinentry.lc_ctype = strdup (pargs.r.ret_str); if (!pinentry.lc_ctype) { #ifndef HAVE_W32CE_SYSTEM @@ -573,7 +588,7 @@ pinentry_parse_opts (int argc, char *argv[]) } break; case 'M': - pinentry.lc_messages = strdup (optarg); + pinentry.lc_messages = strdup (pargs.r.ret_str); if (!pinentry.lc_messages) { #ifndef HAVE_W32CE_SYSTEM @@ -583,34 +598,30 @@ pinentry_parse_opts (int argc, char *argv[]) } break; case 'W': - pinentry.parent_wid = atoi (optarg); - /* FIXME: Add some error handling. Use strtol. */ + pinentry.parent_wid = pargs.r.ret_ulong; break; case 'c': - optarg = parse_color (optarg, &pinentry.color_fg, - &pinentry.color_fg_bright); - optarg = parse_color (optarg, &pinentry.color_bg, NULL); - optarg = parse_color (optarg, &pinentry.color_so, - &pinentry.color_so_bright); + { + char *tmpstr = pargs.r.ret_str; + + tmpstr = parse_color (tmpstr, &pinentry.color_fg, + &pinentry.color_fg_bright); + tmpstr = parse_color (tmpstr, &pinentry.color_bg, NULL); + tmpstr = parse_color (tmpstr, &pinentry.color_so, + &pinentry.color_so_bright); + } break; case 'o': - pinentry.timeout = atoi(optarg); + pinentry.timeout = pargs.r.ret_int; break; + default: - fprintf (stderr, "%s: oops: option not handled\n", this_pgmname); + pargs.err = ARGPARSE_PRINT_WARNING; break; } } - if (opt_version) - return 1; - if (opt_help) - { - usage (); - exit (EXIT_SUCCESS); - } - return 0; } diff --git a/pinentry/pinentry.h b/pinentry/pinentry.h index b6c863e..6787130 100644 --- a/pinentry/pinentry.h +++ b/pinentry/pinentry.h @@ -197,10 +197,9 @@ void pinentry_init (const char *pgmname); "--display". */ int pinentry_have_display (int argc, char **argv); -/* Parse the command line options. Returns 1 if user should print - version and exit. Can exit the program if only help output is - requested. */ -int pinentry_parse_opts (int argc, char *argv[]); +/* Parse the command line options. May exit the program if only help + or version output is requested. */ +void pinentry_parse_opts (int argc, char *argv[]); /* The caller must define this variable to process assuan commands. */ diff --git a/qt/main.cpp b/qt/main.cpp index 1f21c03..c0ca6de 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -3,17 +3,17 @@ Copyright (C) 2003 g10 Code GmbH Written by Steffen Hansen . Modified by Marcus Brinkmann . - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -87,7 +87,7 @@ public: QWidget::destroy(); create( wid, false, false ); } - + ~ForeignWidget() { destroy( false, false ); @@ -167,16 +167,16 @@ qt_cmd_handler (pinentry_t pe) (QString::fromUtf8 (pe->cancel ? pe->cancel : pe->default_cancel? pe->default_cancel: "&Cancel")); bool ret; - + ret = QMessageBox::information (parent, "", desc, ok, can ); - + return !ret; } } pinentry_cmd_handler_t pinentry_cmd_handler = qt_cmd_handler; -int +int main (int argc, char *argv[]) { pinentry_init ("pinentry-qt"); @@ -205,7 +205,7 @@ main (int argc, char *argv[]) fprintf (stderr, "pinentry-qt: can't fixup argument list: %s\n", strerror (errno)); exit (EXIT_FAILURE); - + } for (done=0,p=*new_argv,i=0; i < argc; i++) if (!done && !strcmp (argv[i], "--display")) @@ -224,14 +224,9 @@ main (int argc, char *argv[]) i = argc; new QApplication (i, new_argv); } - - /* Consumes all arguments. */ - if (pinentry_parse_opts (argc, argv)) - { - printf ("pinentry-qt (pinentry) " VERSION "\n"); - exit (EXIT_SUCCESS); - } + + pinentry_parse_opts (argc, argv); if (pinentry_loop ()) return 1; diff --git a/qt4/main.cpp b/qt4/main.cpp index b2a69f2..37b6e7b 100644 --- a/qt4/main.cpp +++ b/qt4/main.cpp @@ -123,7 +123,7 @@ static QString from_utf8( const char * s ) { else return QString::fromLocal8Bit( s ); } - + return result; } @@ -149,7 +149,7 @@ qt_cmd_handler (pinentry_t pe) const QString title = pe->title ? from_utf8( pe->title ) : /* else */ QLatin1String( "pinentry-qt4" ) ; - + if (want_pass) { @@ -311,15 +311,7 @@ main (int argc, char *argv[]) } - /* Consumes all arguments. */ - if (pinentry_parse_opts (argc, argv)) - { - printf ("pinentry-qt4 (pinentry) " /* VERSION */ "\n"); - return EXIT_SUCCESS; - } - else - { - return pinentry_loop () ? EXIT_FAILURE : EXIT_SUCCESS ; - } + pinentry_parse_opts (argc, argv); + return pinentry_loop () ? EXIT_FAILURE : EXIT_SUCCESS ; } diff --git a/tty/pinentry-tty.c b/tty/pinentry-tty.c index 2c40d42..8f680fd 100644 --- a/tty/pinentry-tty.c +++ b/tty/pinentry-tty.c @@ -189,11 +189,7 @@ main (int argc, char *argv[]) pinentry_init ("pinentry-tty"); /* Consumes all arguments. */ - if (pinentry_parse_opts(argc, argv)) - { - printf ("pinentry-tty (pinentry) " VERSION "\n"); - exit(EXIT_SUCCESS); - } + pinentry_parse_opts(argc, argv); if (pinentry_loop ()) return 1; diff --git a/w32/main.c b/w32/main.c index 85bf2b1..fee37c1 100644 --- a/w32/main.c +++ b/w32/main.c @@ -628,9 +628,7 @@ main (int argc, char **argv) pinentry_init (PGMNAME); - /* Consumes all arguments. */ - if (pinentry_parse_opts (argc, argv)) - exit (EXIT_SUCCESS); + pinentry_parse_opts (argc, argv); /* debugfp = fopen ("pinentry.log", "w"); */ /* if (!debugfp) */ commit 8fa3ca90bfbaa84314443fab9865742b78eb85a9 Author: Werner Koch Date: Tue Mar 17 09:56:18 2015 +0100 Use CH type instead of wchar_t for curses. * pinentry/pinentry-curses.c (collect_line): Change second arg to CH. * pinentry/pinentry.c (pinentry_utf8_to_local): Make args const. Signed-off-by: Werner Koch diff --git a/pinentry/pinentry-curses.c b/pinentry/pinentry-curses.c index 4fc8bc4..aad925d 100644 --- a/pinentry/pinentry-curses.c +++ b/pinentry/pinentry-curses.c @@ -1,18 +1,18 @@ /* pinentry-curses.c - A secure curses dialog for PIN entry, library version Copyright (C) 2002 g10 Code GmbH - + This file is part of PINENTRY. - + PINENTRY is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + PINENTRY is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -126,7 +126,7 @@ typedef char CH; there is a forced line break. A full line is returned and will be continued in the next line. */ static void -collect_line (int maxwidth, wchar_t **start_p, int *len_p) +collect_line (int maxwidth, CH **start_p, int *len_p) { int last_space = 0; int len = *len_p; @@ -244,7 +244,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) } \ } \ while (0) - + COPY_OUT (description); COPY_OUT (error); COPY_OUT (prompt); @@ -306,7 +306,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) while (start[len - 1]); y++; } - + if (pinentry->pin) { if (error) @@ -333,7 +333,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog) y += 2; /* Pin entry field. */ } y += 2; /* OK/Cancel and bottom frame. */ - + if (y > size_y) { err = 1; @@ -763,7 +763,7 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) else clear (); } - + keypad (stdscr, TRUE); /* Enable keyboard mapping. */ nonl (); /* Tell curses not to do NL->CR/NL on output. */ cbreak (); /* Take input chars one at a time, no wait for \n. */ @@ -873,7 +873,7 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) if (diag.notok) dialog_switch_pos (&diag, DIALOG_POS_NOTOK); else - dialog_switch_pos (&diag, DIALOG_POS_CANCEL); + dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_CANCEL); @@ -888,7 +888,7 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type) break; } break; - + case '\005': done = -2; break; diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index 0030754..2d73464 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -104,7 +104,7 @@ struct pinentry pinentry = #if defined FALLBACK_CURSES || defined PINENTRY_CURSES || defined PINENTRY_GTK char * -pinentry_utf8_to_local (char *lc_ctype, char *text) +pinentry_utf8_to_local (const char *lc_ctype, const char *text) { iconv_t cd; const char *input = text; diff --git a/pinentry/pinentry.h b/pinentry/pinentry.h index d419550..b6c863e 100644 --- a/pinentry/pinentry.h +++ b/pinentry/pinentry.h @@ -173,7 +173,7 @@ int pinentry_loop2 (int infd, int outfd); /* Convert the UTF-8 encoded string TEXT to the encoding given in LC_CTYPE. Return NULL on error. */ -char *pinentry_utf8_to_local (char *lc_ctype, char *text); +char *pinentry_utf8_to_local (const char *lc_ctype, const char *text); /* Convert TEXT which is encoded according to LC_CTYPE to UTF-8. With SECURE set to true, use secure memory for the returned buffer. ----------------------------------------------------------------------- Summary of changes: curses/pinentry-curses.c | 17 +- gtk+-2/pinentry-gtk-2.c | 7 +- gtk/pinentry-gtk.c | 53 +- pinentry/Makefile.am | 2 +- pinentry/argparse.c | 1607 ++++++++++++++++++++++++++++++++++++++++++++ pinentry/argparse.h | 203 ++++++ pinentry/pinentry-curses.c | 22 +- pinentry/pinentry.c | 159 +++-- pinentry/pinentry.h | 9 +- qt/main.cpp | 25 +- qt4/main.cpp | 16 +- tty/pinentry-tty.c | 6 +- w32/main.c | 4 +- 13 files changed, 1958 insertions(+), 172 deletions(-) create mode 100644 pinentry/argparse.c create mode 100644 pinentry/argparse.h hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 17 12:03:50 2015 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 17 Mar 2015 12:03:50 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-41-g6cbbb0b 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 6cbbb0bec98e1acefc4c7163cc41a507469db920 (commit) from 9078b75a73600fc6b7b5502ceee8de032bb9c446 (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 6cbbb0bec98e1acefc4c7163cc41a507469db920 Author: Andre Heinecke Date: Tue Mar 17 10:48:09 2015 +0100 gpgtar: Fix extracting files with !(size % 512) * tools/gpgtar-extract.c (extract_regular): Handle size multiples of RECORDSIZE. -- If a hdr->size was a multiple of 512 the last record would not have been written and the files corrupted accordingly. GnuPG-bug-id: 1926 Signed-off-by: Andre Heinecke Changed to use only if-else. Signed-off-by: Werner Koch diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 1ea3597..6e506d9 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -66,7 +66,11 @@ extract_regular (estream_t stream, const char *dirname, if (err) goto leave; n++; - nbytes = (n < hdr->nrecords)? RECORDSIZE : (hdr->size % RECORDSIZE); + if (n < hdr->nrecords || (hdr->size && !(hdr->size % RECORDSIZE))) + nbytes = RECORDSIZE; + else + nbytes = (hdr->size % RECORDSIZE); + nwritten = es_fwrite (record, 1, nbytes, outfp); if (nwritten != nbytes) { ----------------------------------------------------------------------- Summary of changes: tools/gpgtar-extract.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 17 12:05:01 2015 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 17 Mar 2015 12:05:01 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.27-5-g0ed2cfc 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 0ed2cfcf054e286b238d4ddbbb3e929482849a47 (commit) from 25e2b27b0027af9c1ce0cae0cd549c09ed349811 (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 0ed2cfcf054e286b238d4ddbbb3e929482849a47 Author: Andre Heinecke Date: Tue Mar 17 10:48:09 2015 +0100 gpgtar: Fix extracting files with !(size % 512) * tools/gpgtar-extract.c (extract_regular): Handle size multiples of RECORDSIZE. -- If a hdr->size was a multiple of 512 the last record would not have been written and the files corrupted accordingly. GnuPG-bug-id: 1926 Signed-off-by: Andre Heinecke Changed to use only if-else. Signed-off-by: Werner Koch (cherry picked from commit 6cbbb0bec98e1acefc4c7163cc41a507469db920) diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 736c7fc..b0d31e0 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -73,7 +73,11 @@ extract_regular (estream_t stream, const char *dirname, if (err) goto leave; n++; - nbytes = (n < hdr->nrecords)? RECORDSIZE : (hdr->size % RECORDSIZE); + if (n < hdr->nrecords || (hdr->size && !(hdr->size % RECORDSIZE))) + nbytes = RECORDSIZE; + else + nbytes = (hdr->size % RECORDSIZE); + nwritten = es_fwrite (record, 1, nbytes, outfp); if (nwritten != nbytes) { ----------------------------------------------------------------------- Summary of changes: tools/gpgtar-extract.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 19 09:11:04 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 19 Mar 2015 09:11:04 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.18-7-gdc95f1e 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 dc95f1ea1ab902b9f49de651084f514535e4a3fc (commit) from b5cb32f979a80904ea58fc7531e43e2be2270573 (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 dc95f1ea1ab902b9f49de651084f514535e4a3fc Author: Werner Koch Date: Thu Mar 19 09:08:45 2015 +0100 Add GPG_ERR_LDAP_* error codes. * src/err-codes.h.in: Add error codes. * doc/ldap2gpgerr.c: New. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index eb50b02..c834a16 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,11 @@ Noteworthy changes in version 1.19 (unreleased) [C/A/R] ----------------------------------------------- + * New set of error codes for use with LDAP. + * Interface changes relative to the 1.18 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPG_ERR_LDAP_* NEW. Noteworthy changes in version 1.18 (2015-01-26) [C14/A14/R0] diff --git a/doc/errorref.txt b/doc/errorref.txt index 7e6da8d..0393f16 100644 --- a/doc/errorref.txt +++ b/doc/errorref.txt @@ -755,3 +755,33 @@ GPG_ERR_INV_LOCK_OBJ Invalid lock object GPGRT: - The provided lock object is not valid. This indicates an internal problem in libgpg-error or more likely a programming error. + + + + +GPG_ERR_LDAP_GENERAL LDAP General error + + Catch all error for LDAP. Use if if can't map an erro rocde to an + gpg-error code. + +GPG_ERR_LDAP_ATTR_GENERAL LDAP General attribute error +GPG_ERR_LDAP_NAME_GENERAL LDAP General name error +GPG_ERR_LDAP_SECURITY_GENERAL LDAP General security error +GPG_ERR_LDAP_SERVICE_GENERAL LDAP General service error +GPG_ERR_LDAP_UPDATE_GENERAL LDAP General update error +GPG_ERR_LDAP_E_GENERAL LDAP Experimental error code +GPG_ERR_LDAP_X_GENERAL LDAP Private error code +GPG_ERR_LDAP_OTHER_GENERAL LDAP Other general error + + All above may be used to map ranges of LDAP errors to one specific + code. OpenLDAP uses LDAP_xxx_RANGE(n) macros for tha mapping. + "Other general error" may be used similar to "General error" for + mapping of ranges. Here are macros from OpenLDAP for reference + + #define LDAP_ATTR_ERROR(n) LDAP_RANGE((n),0x10,0x15) /* 16-21 */ + #define LDAP_NAME_ERROR(n) LDAP_RANGE((n),0x20,0x24) /* 32-34,36 */ + #define LDAP_SECURITY_ERROR(n) LDAP_RANGE((n),0x2F,0x32) /* 47-50 */ + #define LDAP_SERVICE_ERROR(n) LDAP_RANGE((n),0x33,0x36) /* 51-54 */ + #define LDAP_UPDATE_ERROR(n) LDAP_RANGE((n),0x40,0x47) /* 64-69,71 */ + #define LDAP_E_ERROR(n) LDAP_RANGE((n),0x1000,0x3FFF) + #define LDAP_X_ERROR(n) LDAP_RANGE((n),0x4000,0xFFFF) diff --git a/doc/ldap2gpgerr.c b/doc/ldap2gpgerr.c new file mode 100644 index 0000000..515bf40 --- /dev/null +++ b/doc/ldap2gpgerr.c @@ -0,0 +1,184 @@ +/* ldap2gpgerr.c - Mapping of LDAP error codes to gpg-error codes. + * Written in 2015 by Werner Koch + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +/* + * These functions are not part of libgpg-error so not to introduce a + * dependency on a specific LDAP implementation. Feel free to copy + * and distribute them with your code. + */ + +#ifdef _WIN32 +# include +# include +#else +# include +#endif +#include + + +/* Windows uses a few other names. Re-map them. */ +#ifdef _WIN32 +# define LDAP_ADMINLIMIT_EXCEEDED LDAP_ADMIN_LIMIT_EXCEEDED +# define LDAP_UNAVAILABLE_CRITICAL_EXTENSION LDAP_UNAVAILABLE_CRIT_EXTENSION +# define LDAP_TYPE_OR_VALUE_EXISTS LDAP_ATTRIBUTE_OR_VALUE_EXISTS +# define LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_RIGHTS +# define LDAP_VLV_ERROR LDAP_VIRTUAL_LIST_VIEW_ERROR +#endif + + +/* Map LDAP error CODE to an gpg_err_code_t. */ +gpg_err_code_t +map_ldap_to_gpg_error (int code) +{ + gpg_err_code_t ec; + + switch (code) + { +#ifdef LDAP_X_CONNECTING + case LDAP_X_CONNECTING: ec = GPG_ERR_LDAP_X_CONNECTING; break; +#endif + + case LDAP_REFERRAL_LIMIT_EXCEEDED: ec = GPG_ERR_LDAP_REFERRAL_LIMIT; break; + case LDAP_CLIENT_LOOP: ec = GPG_ERR_LDAP_CLIENT_LOOP; break; + case LDAP_NO_RESULTS_RETURNED: ec = GPG_ERR_LDAP_NO_RESULTS; break; + case LDAP_CONTROL_NOT_FOUND: ec = GPG_ERR_LDAP_CONTROL_NOT_FOUND; break; + case LDAP_NOT_SUPPORTED: ec = GPG_ERR_LDAP_NOT_SUPPORTED; break; + case LDAP_CONNECT_ERROR: ec = GPG_ERR_LDAP_CONNECT; break; + case LDAP_NO_MEMORY: ec = GPG_ERR_LDAP_NO_MEMORY; break; + case LDAP_PARAM_ERROR: ec = GPG_ERR_LDAP_PARAM; break; + case LDAP_USER_CANCELLED: ec = GPG_ERR_LDAP_USER_CANCELLED; break; + case LDAP_FILTER_ERROR: ec = GPG_ERR_LDAP_FILTER; break; + case LDAP_AUTH_UNKNOWN: ec = GPG_ERR_LDAP_AUTH_UNKNOWN; break; + case LDAP_TIMEOUT: ec = GPG_ERR_LDAP_TIMEOUT; break; + case LDAP_DECODING_ERROR: ec = GPG_ERR_LDAP_DECODING; break; + case LDAP_ENCODING_ERROR: ec = GPG_ERR_LDAP_ENCODING; break; + case LDAP_LOCAL_ERROR: ec = GPG_ERR_LDAP_LOCAL; break; + case LDAP_SERVER_DOWN: ec = GPG_ERR_LDAP_SERVER_DOWN; break; + + case LDAP_SUCCESS: ec = GPG_ERR_LDAP_SUCCESS; break; + + case LDAP_OPERATIONS_ERROR: ec = GPG_ERR_LDAP_OPERATIONS; break; + case LDAP_PROTOCOL_ERROR: ec = GPG_ERR_LDAP_PROTOCOL; break; + case LDAP_TIMELIMIT_EXCEEDED: ec = GPG_ERR_LDAP_TIMELIMIT; break; + case LDAP_SIZELIMIT_EXCEEDED: ec = GPG_ERR_LDAP_SIZELIMIT; break; + case LDAP_COMPARE_FALSE: ec = GPG_ERR_LDAP_COMPARE_FALSE; break; + case LDAP_COMPARE_TRUE: ec = GPG_ERR_LDAP_COMPARE_TRUE; break; + case LDAP_AUTH_METHOD_NOT_SUPPORTED: ec=GPG_ERR_LDAP_UNSUPPORTED_AUTH;break; + case LDAP_STRONG_AUTH_REQUIRED: ec = GPG_ERR_LDAP_STRONG_AUTH_RQRD; break; + case LDAP_PARTIAL_RESULTS: ec = GPG_ERR_LDAP_PARTIAL_RESULTS; break; + case LDAP_REFERRAL: ec = GPG_ERR_LDAP_REFERRAL; break; + +#ifdef LDAP_ADMINLIMIT_EXCEEDED + case LDAP_ADMINLIMIT_EXCEEDED: ec = GPG_ERR_LDAP_ADMINLIMIT; break; +#endif + +#ifdef LDAP_UNAVAILABLE_CRITICAL_EXTENSION + case LDAP_UNAVAILABLE_CRITICAL_EXTENSION: + ec = GPG_ERR_LDAP_UNAVAIL_CRIT_EXTN; break; +#endif + + case LDAP_CONFIDENTIALITY_REQUIRED: ec = GPG_ERR_LDAP_CONFIDENT_RQRD; break; + case LDAP_SASL_BIND_IN_PROGRESS: ec = GPG_ERR_LDAP_SASL_BIND_INPROG; break; + case LDAP_NO_SUCH_ATTRIBUTE: ec = GPG_ERR_LDAP_NO_SUCH_ATTRIBUTE; break; + case LDAP_UNDEFINED_TYPE: ec = GPG_ERR_LDAP_UNDEFINED_TYPE; break; + case LDAP_INAPPROPRIATE_MATCHING: ec = GPG_ERR_LDAP_BAD_MATCHING; break; + case LDAP_CONSTRAINT_VIOLATION: ec = GPG_ERR_LDAP_CONST_VIOLATION; break; + +#ifdef LDAP_TYPE_OR_VALUE_EXISTS + case LDAP_TYPE_OR_VALUE_EXISTS: ec = GPG_ERR_LDAP_TYPE_VALUE_EXISTS; break; +#endif + + case LDAP_INVALID_SYNTAX: ec = GPG_ERR_LDAP_INV_SYNTAX; break; + case LDAP_NO_SUCH_OBJECT: ec = GPG_ERR_LDAP_NO_SUCH_OBJ; break; + case LDAP_ALIAS_PROBLEM: ec = GPG_ERR_LDAP_ALIAS_PROBLEM; break; + case LDAP_INVALID_DN_SYNTAX: ec = GPG_ERR_LDAP_INV_DN_SYNTAX; break; + case LDAP_IS_LEAF: ec = GPG_ERR_LDAP_IS_LEAF; break; + case LDAP_ALIAS_DEREF_PROBLEM: ec = GPG_ERR_LDAP_ALIAS_DEREF; break; + +#ifdef LDAP_X_PROXY_AUTHZ_FAILURE + case LDAP_X_PROXY_AUTHZ_FAILURE: ec = GPG_ERR_LDAP_X_PROXY_AUTH_FAIL; break; +#endif + + case LDAP_INAPPROPRIATE_AUTH: ec = GPG_ERR_LDAP_BAD_AUTH; break; + case LDAP_INVALID_CREDENTIALS: ec = GPG_ERR_LDAP_INV_CREDENTIALS; break; + +#ifdef LDAP_INSUFFICIENT_ACCESS + case LDAP_INSUFFICIENT_ACCESS: ec = GPG_ERR_LDAP_INSUFFICIENT_ACC; break; +#endif + + case LDAP_BUSY: ec = GPG_ERR_LDAP_BUSY; break; + case LDAP_UNAVAILABLE: ec = GPG_ERR_LDAP_UNAVAILABLE; break; + case LDAP_UNWILLING_TO_PERFORM: ec = GPG_ERR_LDAP_UNWILL_TO_PERFORM; break; + case LDAP_LOOP_DETECT: ec = GPG_ERR_LDAP_LOOP_DETECT; break; + case LDAP_NAMING_VIOLATION: ec = GPG_ERR_LDAP_NAMING_VIOLATION; break; + case LDAP_OBJECT_CLASS_VIOLATION: ec = GPG_ERR_LDAP_OBJ_CLS_VIOLATION; break; + case LDAP_NOT_ALLOWED_ON_NONLEAF: ec=GPG_ERR_LDAP_NOT_ALLOW_NONLEAF;break; + case LDAP_NOT_ALLOWED_ON_RDN: ec = GPG_ERR_LDAP_NOT_ALLOW_ON_RDN; break; + case LDAP_ALREADY_EXISTS: ec = GPG_ERR_LDAP_ALREADY_EXISTS; break; + case LDAP_NO_OBJECT_CLASS_MODS: ec = GPG_ERR_LDAP_NO_OBJ_CLASS_MODS; break; + case LDAP_RESULTS_TOO_LARGE: ec = GPG_ERR_LDAP_RESULTS_TOO_LARGE; break; + case LDAP_AFFECTS_MULTIPLE_DSAS: ec = GPG_ERR_LDAP_AFFECTS_MULT_DSAS; break; + +#ifdef LDAP_VLV_ERROR + case LDAP_VLV_ERROR: ec = GPG_ERR_LDAP_VLV; break; +#endif + + case LDAP_OTHER: ec = GPG_ERR_LDAP_OTHER; break; + +#ifdef LDAP_CUP_RESOURCES_EXHAUSTED + case LDAP_CUP_RESOURCES_EXHAUSTED: ec=GPG_ERR_LDAP_CUP_RESOURCE_LIMIT;break; + case LDAP_CUP_SECURITY_VIOLATION: ec=GPG_ERR_LDAP_CUP_SEC_VIOLATION; break; + case LDAP_CUP_INVALID_DATA: ec = GPG_ERR_LDAP_CUP_INV_DATA; break; + case LDAP_CUP_UNSUPPORTED_SCHEME: ec = GPG_ERR_LDAP_CUP_UNSUP_SCHEME; break; + case LDAP_CUP_RELOAD_REQUIRED: ec = GPG_ERR_LDAP_CUP_RELOAD; break; +#endif + +#ifdef LDAP_CANCELLED + case LDAP_CANCELLED: ec = GPG_ERR_LDAP_CANCELLED; break; +#endif + +#ifdef LDAP_NO_SUCH_OPERATION + case LDAP_NO_SUCH_OPERATION: ec = GPG_ERR_LDAP_NO_SUCH_OPERATION; break; +#endif + +#ifdef LDAP_TOO_LATE + case LDAP_TOO_LATE: ec = GPG_ERR_LDAP_TOO_LATE; break; +#endif + +#ifdef LDAP_CANNOT_CANCEL + case LDAP_CANNOT_CANCEL: ec = GPG_ERR_LDAP_CANNOT_CANCEL; break; +#endif + +#ifdef LDAP_ASSERTION_FAILED + case LDAP_ASSERTION_FAILED: ec = GPG_ERR_LDAP_ASSERTION_FAILED; break; +#endif + +#ifdef LDAP_PROXIED_AUTHORIZATION_DENIED + case LDAP_PROXIED_AUTHORIZATION_DENIED: + ec = GPG_ERR_LDAP_PROX_AUTH_DENIED; break; +#endif + + default: +#if defined(LDAP_E_ERROR) && defined(LDAP_X_ERROR) + if (LDAP_E_ERROR (code)) + ec = GPG_ERR_LDAP_E_GENERAL; + else if (LDAP_X_ERROR (code)) + ec = GPG_ERR_LDAP_X_GENERAL; + else +#endif + ec = GPG_ERR_LDAP_GENERAL; + break; + } + + return ec; +} diff --git a/src/err-codes.h.in b/src/err-codes.h.in index 9e1924d..6a2fe6c 100644 --- a/src/err-codes.h.in +++ b/src/err-codes.h.in @@ -314,9 +314,110 @@ # 282 to 299 are reserved for future assuan codes. -# 300 to 1023 are free to be used. +# 300 to 720 are free to be used. -# For free use by non-GnuPG components. +# +# Mapping of LDAP error codes +# +# The numbers reflect the OpenLDAP code with an offset of 768. +# Some error names are shortened +# +721 GPG_ERR_LDAP_GENERAL LDAP General error +722 GPG_ERR_LDAP_ATTR_GENERAL LDAP General attribute error +723 GPG_ERR_LDAP_NAME_GENERAL LDAP General name error +724 GPG_ERR_LDAP_SECURITY_GENERAL LDAP General security error +725 GPG_ERR_LDAP_SERVICE_GENERAL LDAP General service error +726 GPG_ERR_LDAP_UPDATE_GENERAL LDAP General update error +727 GPG_ERR_LDAP_E_GENERAL LDAP Experimental error code +728 GPG_ERR_LDAP_X_GENERAL LDAP Private error code +729 GPG_ERR_LDAP_OTHER_GENERAL LDAP Other general error +# 730 to 749 not used +750 GPG_ERR_LDAP_X_CONNECTING Connecting failed (X) +751 GPG_ERR_LDAP_REFERRAL_LIMIT Referral limit exceeded +752 GPG_ERR_LDAP_CLIENT_LOOP Client loop +# 753 is an obsolete error code +754 GPG_ERR_LDAP_NO_RESULTS No results returned +755 GPG_ERR_LDAP_CONTROL_NOT_FOUND Control not found +756 GPG_ERR_LDAP_NOT_SUPPORTED Not supported +757 GPG_ERR_LDAP_CONNECT Connect error +758 GPG_ERR_LDAP_NO_MEMORY Out of memory +759 GPG_ERR_LDAP_PARAM Bad parameter to an LDAP routine +760 GPG_ERR_LDAP_USER_CANCELLED User cancelled operation +761 GPG_ERR_LDAP_FILTER Bad search filter +762 GPG_ERR_LDAP_AUTH_UNKNOWN Unknown authentication method +763 GPG_ERR_LDAP_TIMEOUT Timeout +764 GPG_ERR_LDAP_DECODING Decoding error +765 GPG_ERR_LDAP_ENCODING Encoding error +766 GPG_ERR_LDAP_LOCAL LDAP Local error +767 GPG_ERR_LDAP_SERVER_DOWN Cannot contact LDAP server +768 GPG_ERR_LDAP_SUCCESS Success +769 GPG_ERR_LDAP_OPERATIONS Operations error +770 GPG_ERR_LDAP_PROTOCOL Protocol error +771 GPG_ERR_LDAP_TIMELIMIT Time limit exceeded +772 GPG_ERR_LDAP_SIZELIMIT Size limit exceeded +773 GPG_ERR_LDAP_COMPARE_FALSE Compare false +774 GPG_ERR_LDAP_COMPARE_TRUE Compare true +775 GPG_ERR_LDAP_UNSUPPORTED_AUTH Authentication method not supported +776 GPG_ERR_LDAP_STRONG_AUTH_RQRD Strong(er) authentication required +777 GPG_ERR_LDAP_PARTIAL_RESULTS Partial results and referral received +778 GPG_ERR_LDAP_REFERRAL Referral +779 GPG_ERR_LDAP_ADMINLIMIT Administrative limit exceeded +780 GPG_ERR_LDAP_UNAVAIL_CRIT_EXTN Critical extension is unavailable +781 GPG_ERR_LDAP_CONFIDENT_RQRD Confidentiality required +782 GPG_ERR_LDAP_SASL_BIND_INPROG SASL bind in progress +# 783 not used +784 GPG_ERR_LDAP_NO_SUCH_ATTRIBUTE No such attribute +785 GPG_ERR_LDAP_UNDEFINED_TYPE Undefined attribute type +786 GPG_ERR_LDAP_BAD_MATCHING Inappropriate matching +787 GPG_ERR_LDAP_CONST_VIOLATION Constraint violation +788 GPG_ERR_LDAP_TYPE_VALUE_EXISTS Type or value exists +789 GPG_ERR_LDAP_INV_SYNTAX Invalid syntax +# 790 to 799 not used +800 GPG_ERR_LDAP_NO_SUCH_OBJ No such object +801 GPG_ERR_LDAP_ALIAS_PROBLEM Alias problem +802 GPG_ERR_LDAP_INV_DN_SYNTAX Invalid DN syntax +803 GPG_ERR_LDAP_IS_LEAF Entry is a leaf +804 GPG_ERR_LDAP_ALIAS_DEREF Alias dereferencing problem +# 805 to 814 not used +815 GPG_ERR_LDAP_X_PROXY_AUTH_FAIL Proxy authorization failure (X) +816 GPG_ERR_LDAP_BAD_AUTH Inappropriate authentication +817 GPG_ERR_LDAP_INV_CREDENTIALS Invalid credentials +818 GPG_ERR_LDAP_INSUFFICIENT_ACC Insufficient access +819 GPG_ERR_LDAP_BUSY Server is busy +820 GPG_ERR_LDAP_UNAVAILABLE Server is unavailable +821 GPG_ERR_LDAP_UNWILL_TO_PERFORM Server is unwilling to perform +822 GPG_ERR_LDAP_LOOP_DETECT Loop detected +# 823 to 831 not used +832 GPG_ERR_LDAP_NAMING_VIOLATION Naming violation +833 GPG_ERR_LDAP_OBJ_CLS_VIOLATION Object class violation +834 GPG_ERR_LDAP_NOT_ALLOW_NONLEAF Operation not allowed on non-leaf +835 GPG_ERR_LDAP_NOT_ALLOW_ON_RDN Operation not allowed on RDN +836 GPG_ERR_LDAP_ALREADY_EXISTS Already exists +837 GPG_ERR_LDAP_NO_OBJ_CLASS_MODS Cannot modify object class +838 GPG_ERR_LDAP_RESULTS_TOO_LARGE Results too large +839 GPG_ERR_LDAP_AFFECTS_MULT_DSAS Operation affects multiple DSAs +# 840 to 843 not used +844 GPG_ERR_LDAP_VLV Virtual list view error +# 845 to 847 not used +848 GPG_ERR_LDAP_OTHER Other LDAP error +# 849 to 880 not used +881 GPG_ERR_LDAP_CUP_RESOURCE_LIMIT LCUP Resources exhausted +882 GPG_ERR_LDAP_CUP_SEC_VIOLATION LCUP Security violation +883 GPG_ERR_LDAP_CUP_INV_DATA LCUP Invalid data +884 GPG_ERR_LDAP_CUP_UNSUP_SCHEME LCUP Unsupported scheme +885 GPG_ERR_LDAP_CUP_RELOAD LCUP Reload required +886 GPG_ERR_LDAP_CANCELLED LDAP Cancelled +887 GPG_ERR_LDAP_NO_SUCH_OPERATION No operation to cancel +888 GPG_ERR_LDAP_TOO_LATE Too late to cancel +889 GPG_ERR_LDAP_CANNOT_CANCEL Cannot cancel +890 GPG_ERR_LDAP_ASSERTION_FAILED Assertion failed +891 GPG_ERR_LDAP_PROX_AUTH_DENIED Proxied authorization denied + +# 892 to 950 are reserved for future LDAP codes. + +# 951 to 1023 are free to be used. + +# For free use by non-GnuPG components: 1024 GPG_ERR_USER_1 User defined error code 1 1025 GPG_ERR_USER_2 User defined error code 2 1026 GPG_ERR_USER_3 User defined error code 3 ----------------------------------------------------------------------- Summary of changes: NEWS | 3 + doc/errorref.txt | 30 +++++++++ doc/ldap2gpgerr.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/err-codes.h.in | 105 +++++++++++++++++++++++++++++- 4 files changed, 320 insertions(+), 2 deletions(-) create mode 100644 doc/ldap2gpgerr.c hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 19 09:27:45 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 19 Mar 2015 09:27:45 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.18-8-g528ee70 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 528ee704f8f9d881ba370dcbfa9194d6704f9a2f (commit) from dc95f1ea1ab902b9f49de651084f514535e4a3fc (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 528ee704f8f9d881ba370dcbfa9194d6704f9a2f Author: Werner Koch Date: Thu Mar 19 09:26:23 2015 +0100 Add option --defines to gpg-error. * src/gpg-error.c (main): Add option --help and --defines. Signed-off-by: Werner Koch diff --git a/src/gpg-error.c b/src/gpg-error.c index 034a61b..672efe7 100644 --- a/src/gpg-error.c +++ b/src/gpg-error.c @@ -394,13 +394,27 @@ main (int argc, char *argv[]) fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout); exit (0); } + else if (argc == 2 && !strcmp (argv[1], "--help")) + { + fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout); + fputs ("Options:\n" + " --version Print version\n" + " --help Print this help\n" + " --list Print all error codes\n" + " --defines Print all error codes as #define lines\n", stdout); + exit (0); + } else if (argc == 2 && !strcmp (argv[1], "--list")) { listmode = 1; } + else if (argc == 2 && !strcmp (argv[1], "--defines")) + { + listmode = 2; + } - if (listmode) + if (listmode == 1) { for (i=0; i < GPG_ERR_SOURCE_DIM; i++) { @@ -423,27 +437,71 @@ main (int argc, char *argv[]) err, gpg_err_code (err), error_sym, gpg_strerror (err)); } - - i = argc; /* Don't run the usual stuff. */ } - while (i < argc) + else if (listmode == 2) { - if (get_err_from_number (argv[i], &err) - || get_err_from_symbol (argv[i], &err) - || get_err_from_str (argv[i], &err)) - { + int n, nmax; + + for (i=0, nmax=0; i < GPG_ERR_SOURCE_DIM; i++) + { + err = gpg_err_make (i, 1); source_sym = gpg_strsource_sym (err); + if (source_sym) + { + n = strlen (source_sym); + if (n > nmax) + nmax = n; + } + } + for (i=0; i < GPG_ERR_SOURCE_DIM; i++) + { + err = gpg_err_make (i, 1); + source_sym = gpg_strsource_sym (err); + if (source_sym) + printf ("#define %-*s %3u\n", nmax,source_sym,gpg_err_source (err)); + } + + + for (i=0, nmax = 0; i < GPG_ERR_CODE_DIM; i++) + { + err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i); + error_sym = gpg_strerror_sym (err); + if (error_sym) + { + n = strlen (error_sym); + if (n > nmax) + nmax = n; + } + } + for (i=0; i < GPG_ERR_CODE_DIM; i++) + { + err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i); error_sym = gpg_strerror_sym (err); + if (error_sym) + printf ("#define %-*s %5u\n", nmax, error_sym, gpg_err_code (err)); + } + } + else /* Standard mode. */ + { + while (i < argc) + { + if (get_err_from_number (argv[i], &err) + || get_err_from_symbol (argv[i], &err) + || get_err_from_str (argv[i], &err)) + { + source_sym = gpg_strsource_sym (err); + error_sym = gpg_strerror_sym (err); - printf ("%u = (%u, %u) = (%s, %s) = (%s, %s)\n", - err, gpg_err_source (err), gpg_err_code (err), - source_sym ? source_sym : "-", error_sym ? error_sym : "-", - gpg_strsource (err), gpg_strerror (err)); - } - else - fprintf (stderr, _("%s: warning: could not recognize %s\n"), - argv[0], argv[i]); - i++; + printf ("%u = (%u, %u) = (%s, %s) = (%s, %s)\n", + err, gpg_err_source (err), gpg_err_code (err), + source_sym ? source_sym : "-", error_sym ? error_sym:"-", + gpg_strsource (err), gpg_strerror (err)); + } + else + fprintf (stderr, _("%s: warning: could not recognize %s\n"), + argv[0], argv[i]); + i++; + } } exit (0); ----------------------------------------------------------------------- Summary of changes: src/gpg-error.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 17 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 19 09:35:42 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 19 Mar 2015 09:35:42 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-42-g28bb3ab 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 28bb3ab686c1c994f67a92b6846b3726c58a0bc3 (commit) from 6cbbb0bec98e1acefc4c7163cc41a507469db920 (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 28bb3ab686c1c994f67a92b6846b3726c58a0bc3 Author: Werner Koch Date: Thu Mar 19 09:34:08 2015 +0100 Define replacement error codes from libgpg-error 1.19. * common/util.h: Add GPG_ERR_LDAP codes for libgpg-error < 1.19. diff --git a/common/util.h b/common/util.h index 0a54718..4761a28 100644 --- a/common/util.h +++ b/common/util.h @@ -42,7 +42,89 @@ # define GPG_ERR_OBJ_TERM_STATE 225 # define GPG_ERR_FORBIDDEN 251 #endif - +#if GPG_ERROR_VERSION_NUMBER < 0x011300 /* 1.19 */ +# define GPG_ERR_LDAP_GENERAL 721 +# define GPG_ERR_LDAP_ATTR_GENERAL 722 +# define GPG_ERR_LDAP_NAME_GENERAL 723 +# define GPG_ERR_LDAP_SECURITY_GENERAL 724 +# define GPG_ERR_LDAP_SERVICE_GENERAL 725 +# define GPG_ERR_LDAP_UPDATE_GENERAL 726 +# define GPG_ERR_LDAP_E_GENERAL 727 +# define GPG_ERR_LDAP_X_GENERAL 728 +# define GPG_ERR_LDAP_OTHER_GENERAL 729 +# define GPG_ERR_LDAP_X_CONNECTING 750 +# define GPG_ERR_LDAP_REFERRAL_LIMIT 751 +# define GPG_ERR_LDAP_CLIENT_LOOP 752 +# define GPG_ERR_LDAP_NO_RESULTS 754 +# define GPG_ERR_LDAP_CONTROL_NOT_FOUND 755 +# define GPG_ERR_LDAP_NOT_SUPPORTED 756 +# define GPG_ERR_LDAP_CONNECT 757 +# define GPG_ERR_LDAP_NO_MEMORY 758 +# define GPG_ERR_LDAP_PARAM 759 +# define GPG_ERR_LDAP_USER_CANCELLED 760 +# define GPG_ERR_LDAP_FILTER 761 +# define GPG_ERR_LDAP_AUTH_UNKNOWN 762 +# define GPG_ERR_LDAP_TIMEOUT 763 +# define GPG_ERR_LDAP_DECODING 764 +# define GPG_ERR_LDAP_ENCODING 765 +# define GPG_ERR_LDAP_LOCAL 766 +# define GPG_ERR_LDAP_SERVER_DOWN 767 +# define GPG_ERR_LDAP_SUCCESS 768 +# define GPG_ERR_LDAP_OPERATIONS 769 +# define GPG_ERR_LDAP_PROTOCOL 770 +# define GPG_ERR_LDAP_TIMELIMIT 771 +# define GPG_ERR_LDAP_SIZELIMIT 772 +# define GPG_ERR_LDAP_COMPARE_FALSE 773 +# define GPG_ERR_LDAP_COMPARE_TRUE 774 +# define GPG_ERR_LDAP_UNSUPPORTED_AUTH 775 +# define GPG_ERR_LDAP_STRONG_AUTH_RQRD 776 +# define GPG_ERR_LDAP_PARTIAL_RESULTS 777 +# define GPG_ERR_LDAP_REFERRAL 778 +# define GPG_ERR_LDAP_ADMINLIMIT 779 +# define GPG_ERR_LDAP_UNAVAIL_CRIT_EXTN 780 +# define GPG_ERR_LDAP_CONFIDENT_RQRD 781 +# define GPG_ERR_LDAP_SASL_BIND_INPROG 782 +# define GPG_ERR_LDAP_NO_SUCH_ATTRIBUTE 784 +# define GPG_ERR_LDAP_UNDEFINED_TYPE 785 +# define GPG_ERR_LDAP_BAD_MATCHING 786 +# define GPG_ERR_LDAP_CONST_VIOLATION 787 +# define GPG_ERR_LDAP_TYPE_VALUE_EXISTS 788 +# define GPG_ERR_LDAP_INV_SYNTAX 789 +# define GPG_ERR_LDAP_NO_SUCH_OBJ 800 +# define GPG_ERR_LDAP_ALIAS_PROBLEM 801 +# define GPG_ERR_LDAP_INV_DN_SYNTAX 802 +# define GPG_ERR_LDAP_IS_LEAF 803 +# define GPG_ERR_LDAP_ALIAS_DEREF 804 +# define GPG_ERR_LDAP_X_PROXY_AUTH_FAIL 815 +# define GPG_ERR_LDAP_BAD_AUTH 816 +# define GPG_ERR_LDAP_INV_CREDENTIALS 817 +# define GPG_ERR_LDAP_INSUFFICIENT_ACC 818 +# define GPG_ERR_LDAP_BUSY 819 +# define GPG_ERR_LDAP_UNAVAILABLE 820 +# define GPG_ERR_LDAP_UNWILL_TO_PERFORM 821 +# define GPG_ERR_LDAP_LOOP_DETECT 822 +# define GPG_ERR_LDAP_NAMING_VIOLATION 832 +# define GPG_ERR_LDAP_OBJ_CLS_VIOLATION 833 +# define GPG_ERR_LDAP_NOT_ALLOW_NONLEAF 834 +# define GPG_ERR_LDAP_NOT_ALLOW_ON_RDN 835 +# define GPG_ERR_LDAP_ALREADY_EXISTS 836 +# define GPG_ERR_LDAP_NO_OBJ_CLASS_MODS 837 +# define GPG_ERR_LDAP_RESULTS_TOO_LARGE 838 +# define GPG_ERR_LDAP_AFFECTS_MULT_DSAS 839 +# define GPG_ERR_LDAP_VLV 844 +# define GPG_ERR_LDAP_OTHER 848 +# define GPG_ERR_LDAP_CUP_RESOURCE_LIMIT 881 +# define GPG_ERR_LDAP_CUP_SEC_VIOLATION 882 +# define GPG_ERR_LDAP_CUP_INV_DATA 883 +# define GPG_ERR_LDAP_CUP_UNSUP_SCHEME 884 +# define GPG_ERR_LDAP_CUP_RELOAD 885 +# define GPG_ERR_LDAP_CANCELLED 886 +# define GPG_ERR_LDAP_NO_SUCH_OPERATION 887 +# define GPG_ERR_LDAP_TOO_LATE 888 +# define GPG_ERR_LDAP_CANNOT_CANCEL 889 +# define GPG_ERR_LDAP_ASSERTION_FAILED 890 +# define GPG_ERR_LDAP_PROX_AUTH_DENIED 891 +#endif /*GPG_ERROR_VERSION_NUMBER < 0x011300*/ /* Hash function used with libksba. */ #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write) ----------------------------------------------------------------------- Summary of changes: common/util.h | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 19 10:45:59 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 19 Mar 2015 10:45:59 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-178-gf583228 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 f5832285b0e420d77be1b8da10a1e1d86583b414 (commit) from db8ae3616987fa288173446398a107e31e2e28aa (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 f5832285b0e420d77be1b8da10a1e1d86583b414 Author: Werner Koch Date: Thu Mar 19 10:43:55 2015 +0100 Fix two pedantic warnings. * src/gcrypt.h.in (gcry_mpi_flag, gcry_mac_algos): Remove trailing comma. -- Reported-by: Opal Raava Signed-off-by: Werner Koch diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 10099e1..cac2b49 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -511,7 +511,7 @@ enum gcry_mpi_flag GCRYMPI_FLAG_USER1 = 0x0100,/* User flag 1. */ GCRYMPI_FLAG_USER2 = 0x0200,/* User flag 2. */ GCRYMPI_FLAG_USER3 = 0x0400,/* User flag 3. */ - GCRYMPI_FLAG_USER4 = 0x0800,/* User flag 4. */ + GCRYMPI_FLAG_USER4 = 0x0800 /* User flag 4. */ }; @@ -1372,7 +1372,7 @@ enum gcry_mac_algos /* Flags used with the open function. */ enum gcry_mac_flags { - GCRY_MAC_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */ + GCRY_MAC_FLAG_SECURE = 1 /* Allocate all buffers in "secure" memory. */ }; /* Create a MAC handle for algorithm ALGO. FLAGS may be given as an bitwise OR ----------------------------------------------------------------------- Summary of changes: src/gcrypt.h.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 19 15:39:10 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 19 Mar 2015 15:39:10 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-43-gdc10d46 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 dc10d466bff53821f23d2cb4814c259d40c5d9c5 (commit) from 28bb3ab686c1c994f67a92b6846b3726c58a0bc3 (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 dc10d466bff53821f23d2cb4814c259d40c5d9c5 Author: Werner Koch Date: Thu Mar 19 15:37:05 2015 +0100 hkps: Fix host name verification when using pools. * common/http.c (send_request): Set the requested for SNI. * dirmngr/ks-engine-hkp.c (map_host): Return the poolname and not the selecting a host. -- GnuPG-bug-id: 1792 Thanks to davidw for figuring out the problem. Signed-off-by: Werner Koch diff --git a/common/http.c b/common/http.c index 50c0692..12e3fcb 100644 --- a/common/http.c +++ b/common/http.c @@ -1443,7 +1443,8 @@ send_request (http_t hd, const char *httphost, const char *auth, } # if HTTP_USE_NTBTLS - err = ntbtls_set_hostname (hd->session->tls_session, server); + err = ntbtls_set_hostname (hd->session->tls_session, + hd->session->servername); if (err) { log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err)); @@ -1452,7 +1453,8 @@ send_request (http_t hd, const char *httphost, const char *auth, # elif HTTP_USE_GNUTLS rc = gnutls_server_name_set (hd->session->tls_session, GNUTLS_NAME_DNS, - server, strlen (server)); + hd->session->servername + strlen (hd->session->servername)); if (rc < 0) log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc)); # endif /*HTTP_USE_GNUTLS*/ diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index ea607cb..0568094 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -521,6 +521,14 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, hi = hosttable[idx]; if (hi->pool) { + /* Deal with the pool name before selecting a host. */ + if (r_poolname && hi->cname) + { + *r_poolname = xtrystrdup (hi->cname); + if (!*r_poolname) + return gpg_error_from_syserror (); + } + /* If the currently selected host is now marked dead, force a re-selection . */ if (force_reselect) @@ -536,6 +544,11 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, if (hi->poolidx == -1) { log_error ("no alive host found in pool '%s'\n", name); + if (r_poolname) + { + xfree (*r_poolname); + *r_poolname = NULL; + } return gpg_error (GPG_ERR_NO_KEYSERVER); } } @@ -548,6 +561,11 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, if (hi->dead) { log_error ("host '%s' marked as dead\n", hi->name); + if (r_poolname) + { + xfree (*r_poolname); + *r_poolname = NULL; + } return gpg_error (GPG_ERR_NO_KEYSERVER); } @@ -564,13 +582,6 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, *r_httpflags |= HTTP_FLAG_IGNORE_IPv6; } - if (r_poolname && hi->pool && hi->cname) - { - *r_poolname = xtrystrdup (hi->cname); - if (!*r_poolname) - return gpg_error_from_syserror (); - } - *r_host = xtrystrdup (hi->name); if (!*r_host) { ----------------------------------------------------------------------- Summary of changes: common/http.c | 6 ++++-- dirmngr/ks-engine-hkp.c | 25 ++++++++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 19 18:06:02 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 19 Mar 2015 18:06:02 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-44-gcf83ff0 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 cf83ff01fce3ddcbde6d97dffa0db6f277588e25 (commit) from dc10d466bff53821f23d2cb4814c259d40c5d9c5 (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 cf83ff01fce3ddcbde6d97dffa0db6f277588e25 Author: Werner Koch Date: Thu Mar 19 18:01:58 2015 +0100 agent: Compute correct MPI length header for protected ECC keys. * agent/cvt-openpgp.c (apply_protection): Strip leading zeroes from opaque MPIs to comply with the OpenPGP spec. -- This patch is the protected private key counterpart to commit ab17f7b. Thanks to andy_s for describing the problem. GnuPG-bug-id: 1853 Signed-off-by: Werner Koch diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index cadc871..b00f032 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -1107,14 +1107,33 @@ apply_protection (gcry_mpi_t *array, int npkey, int nskey, { if (gcry_mpi_get_flag (array[i], GCRYMPI_FLAG_OPAQUE)) { - const void *s; + const unsigned char *s; unsigned int n; s = gcry_mpi_get_opaque (array[i], &n); + if (!s) + { + s = ""; + n = 0; + } + /* Strip leading zero bits. */ + for (; n >= 8 && !*s; s++, n -= 8) + ; + if (n >= 8 && !(*s & 0x80)) + if (--n >= 7 && !(*s & 0x40)) + if (--n >= 6 && !(*s & 0x20)) + if (--n >= 5 && !(*s & 0x10)) + if (--n >= 4 && !(*s & 0x08)) + if (--n >= 3 && !(*s & 0x04)) + if (--n >= 2 && !(*s & 0x02)) + if (--n >= 1 && !(*s & 0x01)) + --n; + nbits[j] = n; n = (n+7)/8; narr[j] = n; - bufarr[j] = gcry_is_secure (s)? xtrymalloc_secure (n):xtrymalloc (n); + bufarr[j] = (gcry_is_secure (s)? xtrymalloc_secure (n?n:1) + /* */ : xtrymalloc (n?n:1)); if (!bufarr[j]) { err = gpg_error_from_syserror (); ----------------------------------------------------------------------- Summary of changes: agent/cvt-openpgp.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 19 20:41:09 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 19 Mar 2015 20:41:09 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-45-ge7ddaad 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 e7ddaad0fd2c8774a1d3367adfaa68014eaf65de (commit) from cf83ff01fce3ddcbde6d97dffa0db6f277588e25 (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 e7ddaad0fd2c8774a1d3367adfaa68014eaf65de Author: Werner Koch Date: Thu Mar 19 20:38:25 2015 +0100 gpg: Emit status line NEWSIG before signature verification starts. * g10/mainproc.c (check_sig_and_print): Emit STATUS_NEWSIG. -- gpgsm does this for a long time but somehow it never made it into gpg. Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index 4b82497..61ad7d8 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -338,9 +338,9 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: ** General status codes *** NEWSIG - May be issued right before a signature verification starts. This - is useful to define a context for parsing ERROR status messages. - No arguments are currently defined. + Is issued right before a signature verification starts. This is + useful to define a context for parsing ERROR status messages. No + arguments are currently defined. *** GOODSIG The signature with the keyid is good. For each signature only one diff --git a/g10/mainproc.c b/g10/mainproc.c index 0ae9168..0f6ba2b 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1670,6 +1670,8 @@ check_sig_and_print (CTX c, kbnode_t node) } } + write_status_text (STATUS_NEWSIG, NULL); + astr = openpgp_pk_algo_name ( sig->pubkey_algo ); if (keystrlen () > 8) { ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 6 +++--- g10/mainproc.c | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 20 09:44:31 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Fri, 20 Mar 2015 09:44:31 +0100 Subject: [git] GnuPG - branch, neal/dirmngr-ldap, updated. gnupg-2.1.2-53-g02e25c5 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, neal/dirmngr-ldap has been updated discards a7cd3b8037848e313d8819556a733808781b3610 (commit) discards f6cd33c14c7d749d6cad76909cd50d6596bfe93f (commit) discards 57c3938bcf4d3e95102e5a792cc67eea94331c95 (commit) discards 99a91dae4909edf1dbad79696ae15733f38d8f16 (commit) via 02e25c50b8215332dc4e36c7980e01359b1a33d4 (commit) via 3ce432417b67858bfbc14faa0031b253ee74a9fa (commit) via f871d582089d4b33e7ec572553a412a17a69dc3d (commit) via d10a6597b10e25d30ee68468ca3433bde3015b3e (commit) This update added new revisions after undoing existing revisions. That is to say, the old revision is not a strict subset of the new revision. This situation occurs when you --force push a change and generate a repository containing something like this: * -- * -- B -- O -- O -- O (a7cd3b8037848e313d8819556a733808781b3610) \ N -- N -- N (02e25c50b8215332dc4e36c7980e01359b1a33d4) When this happens we assume that you've already had alert emails for all of the O revisions, and so we here report only the revisions in the N branch from the common base, B. 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 02e25c50b8215332dc4e36c7980e01359b1a33d4 Author: Neal H. Walfield Date: Thu Mar 19 11:15:53 2015 +0100 Improve documentation for ks_hkp_get. * dirmngr/ks-engine-hkp.c (ks_hkp_get): Improvement documentation. -- diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 4562e88..a46defb 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1242,7 +1242,8 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, /* Get the key described key the KEYSPEC string from the keyserver identified by URI. On success R_FP has an open stream to read the - data. */ + data. The data will be provided in a format GnuPG can import + (either a binary OpenPGP message or an armored one). */ gpg_error_t ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp) { commit 3ce432417b67858bfbc14faa0031b253ee74a9fa Author: Neal H. Walfield Date: Thu Mar 19 11:14:52 2015 +0100 Improve spelling and grammar of some comments. -- diff --git a/common/userids.c b/common/userids.c index 61e88cc..e1304be 100644 --- a/common/userids.c +++ b/common/userids.c @@ -38,7 +38,7 @@ /* Parse the user-id NAME and build a search description for it. - * Returns 0 on succdess or an error code. DESC may be NULL to merely + * Returns 0 on success or an error code. DESC may be NULL to merely * check the validity of a user-id. * * Some used rules: diff --git a/configure.ac b/configure.ac index 34fffb2..d02137a 100644 --- a/configure.ac +++ b/configure.ac @@ -1799,7 +1799,7 @@ if test x"$use_regex" != xyes ; then echo " Warning: No regular expression support available. OpenPGP trust signatures won't work. - gpg-check-pattern will not be build. + gpg-check-pattern will not be built. " fi if test "x${gpg_config_script_warn}" != x; then diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 7fc9826..8c5feef 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -78,7 +78,7 @@ typedef struct cert_item_s *cert_item_t; the first byte of the fingerprint. */ static cert_item_t cert_cache[256]; -/* This is the global cache_lock variable. In general looking is not +/* This is the global cache_lock variable. In general locking is not needed but it would take extra efforts to make sure that no indirect use of npth functions is done, so we simply lock it always. Note: We can't use static initialization, as that is not @@ -153,7 +153,7 @@ compare_serialno (ksba_sexp_t serial1, ksba_sexp_t serial2 ) -/* Return a malloced canonical S-Expression with the serialnumber +/* Return a malloced canonical S-Expression with the serial number converted from the hex string HEXSN. Return NULL on memory error. */ ksba_sexp_t diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 36a476a..94d6692 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -251,7 +251,7 @@ static const char *redir_socket_name; POSIX systems). */ static assuan_sock_nonce_t socket_nonce; -/* Only if this flag has been set we will remove the socket file. */ +/* Only if this flag has been set will we remove the socket file. */ static int cleanup_socket; /* Keep track of the current log file so that we can avoid updating @@ -1881,8 +1881,8 @@ handle_tick (void) } -/* Check the nonce on a new connection. This is a NOP unless we we - are using our Unix domain socket emulation under Windows. */ +/* Check the nonce on a new connection. This is a NOP unless we are + using our Unix domain socket emulation under Windows. */ static int check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce) { diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 79313ec..4562e88 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1385,7 +1385,7 @@ put_post_cb (void *opaque, http_t http) } -/* Send the key in {DATA,DATALEN} to the keyserver identified by URI. */ +/* Send the key in {DATA,DATALEN} to the keyserver identified by URI. */ gpg_error_t ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen) { diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c index f2aaf59..5588468 100644 --- a/dirmngr/ldap-wrapper.c +++ b/dirmngr/ldap-wrapper.c @@ -630,7 +630,7 @@ reader_callback (void *cb_value, char *buffer, size_t count, size_t *nread) return 0; } -/* Fork and exec the LDAP wrapper and returns a new libksba reader +/* Fork and exec the LDAP wrapper and return a new libksba reader object at READER. ARGV is a NULL terminated list of arguments for the wrapper. The function returns 0 on success or an error code. diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c index c596198..e4c6aa2 100644 --- a/dirmngr/ldap.c +++ b/dirmngr/ldap.c @@ -131,7 +131,7 @@ run_ldap_wrapper (ctrl_t ctrl, *reader = NULL; argc = 0; - if (pass) /* Note, that the password most be the first item. */ + if (pass) /* Note, that the password must be the first item. */ { argv[argc++] = "--pass"; argv[argc++] = pass; diff --git a/dirmngr/ldapserver.c b/dirmngr/ldapserver.c index 5808c5b..16e13e2 100644 --- a/dirmngr/ldapserver.c +++ b/dirmngr/ldapserver.c @@ -47,7 +47,7 @@ ldapserver_list_free (ldap_server_t servers) /* Parse a single LDAP server configuration line. Returns the server - or NULL in case of errors. The configuration lineis assumed to be + or NULL in case of errors. The configuration line is assumed to be colon seprated with these fields: 1. field: Hostname diff --git a/dirmngr/misc.c b/dirmngr/misc.c index 93f051c..244919e 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -125,7 +125,7 @@ serial_to_buffer (const ksba_sexp_t serial, size_t *length) } -/* Do an in-place percent unescaping of STRING. Returns STRING. Noet +/* Do an in-place percent unescaping of STRING. Returns STRING. Note that this function does not do a '+'-to-space unescaping.*/ char * unpercent_string (char *string) diff --git a/dirmngr/server.c b/dirmngr/server.c index b5d1653..deae85c 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1635,7 +1635,7 @@ cmd_ks_get (assuan_context_t ctx, char *line) /* No options for now. */ line = skip_options (line); - /* Break the line down into an strlist. Each pattern is by + /* Break the line into a strlist. Each pattern is by definition percent-plus escaped. However we only support keyids and fingerprints and thus the client has no need to apply the escaping. */ @@ -1752,7 +1752,7 @@ cmd_ks_put (assuan_context_t ctx, char *line) } /* Ask for the key meta data. Not actually needed for HKP servers - but we do it anyway test the client implementaion. */ + but we do it anyway to test the client implementaion. */ err = assuan_inquire (ctx, "KEYBLOCK_INFO", &info, &infolen, MAX_KEYBLOCK_LENGTH); if (err) @@ -1944,8 +1944,8 @@ reset_notify (assuan_context_t ctx, char *line) } -/* Startup the server and run the main command loop. With FD = -1 - used stdin/stdout. */ +/* Startup the server and run the main command loop. With FD = -1, + use stdin/stdout. */ void start_command_handler (assuan_fd_t fd) { diff --git a/doc/DETAILS b/doc/DETAILS index 4b82497..749e0bf 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -32,7 +32,7 @@ fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4: #+end_example The double =--with-fingerprint= prints the fingerprint for the subkeys -too. Old versions of gpg used a slighrly different format and required +too. Old versions of gpg used a slightly different format and required the use of the option =--fixed-list-mode= to conform to the format described here. diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 8ad2a13..9118aa0 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -152,7 +152,7 @@ print_fd_and_time (int fd) /* Print LINE for the client identified by C. Calling this function - witgh LINE set to NULL, will flush the internal buffer. */ + with LINE set to NULL, will flush the internal buffer. */ static void print_line (client_t c, const char *line) { commit f871d582089d4b33e7ec572553a412a17a69dc3d Author: Neal H. Walfield Date: Thu Mar 19 11:12:43 2015 +0100 Improve documenation for http_parse_uri. * common/http.c (http_parse_uri): Improve documentation. -- diff --git a/common/http.c b/common/http.c index 5b45a9c..55e37a2 100644 --- a/common/http.c +++ b/common/http.c @@ -1018,9 +1018,10 @@ parse_uri (parsed_uri_t *ret_uri, const char *uri, /* * Parse an URI and put the result into the newly allocated RET_URI. - * On success the caller must use release_parsed_uri() to releases the - * resources. If NO_SCHEME_CHECK is set, the function tries to parse - * the URL in the same way it would do for an HTTP style URI. + * On success the caller must use http_release_parsed_uri() to + * releases the resources. If NO_SCHEME_CHECK is set, the function + * tries to parse the URL in the same way it would do for an HTTP + * style URI. */ gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri, commit d10a6597b10e25d30ee68468ca3433bde3015b3e Author: Neal H. Walfield Date: Thu Mar 19 11:02:46 2015 +0100 Add support to talking to LDAP key servers. * dirmngr/ks-action.c: Include "ldap-parse-uri.h". (ks_action_help): If the provided URI is an LDAP URI, then use ldap_parse_uri to parse. Call ks_ldap_help. (ks_action_search): If passed an LDAP URI, then call ks_ldap_search. (ks_action_get): Likewise. (ks_action_put): Likewise. Also, change data from a 'const void *' to a 'void *' and add info and infolen parameters. Add note that function may modify DATA. * dirmngr/ks-action.h (ks_action_put): Update declaration accordingly. * dirmngr/server.c: Include "ldap-parse-uri.h". (cmd_keyserver): If ITEM->URI is an LDAP URI, parse it using ldap_parse_uri. (hlp_ks_put): Improve documentation. (cmd_ks_put): Also pass info and infolen to ks_action_put. Improve documentation. * dirmngr/ks-engine.h (ks_ldap_help): New declaration. (ks_ldap_search): Likewise. (ks_ldap_get): Likewise. (ks_ldap_put): Likewise. * dirmngr/ks-engine-ldap.c: New file. * dirmngr/Makefile.am (dirmngr_SOURCES): Add ks-engine-ldap.c, ldap-parse-uri.c and ldap-parse-uri.h. (dirmngr_LDADD) [USE_LDAP]: Add $(ldaplibs). -- diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index c0918a7..97f27f5 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -62,7 +62,9 @@ dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ cdb.h cdblib.c misc.c dirmngr-err.h \ ocsp.c ocsp.h validate.c validate.h \ ks-action.c ks-action.h ks-engine.h \ - ks-engine-hkp.c ks-engine-http.c ks-engine-finger.c ks-engine-kdns.c + ks-engine-hkp.c ks-engine-http.c ks-engine-finger.c ks-engine-kdns.c \ + ks-engine-ldap.c \ + ldap-parse-uri.c ldap-parse-uri.h if USE_LDAP dirmngr_SOURCES += ldapserver.h ldapserver.c ldap.c w32-ldap-help.h \ @@ -77,6 +79,9 @@ dirmngr_LDADD = $(libcommontlsnpth) $(libcommonpth) \ $(DNSLIBS) $(LIBASSUAN_LIBS) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(NPTH_LIBS) \ $(NTBTLS_LIBS) $(LIBGNUTLS_LIBS) $(LIBINTL) $(LIBICONV) +if USE_LDAP +dirmngr_LDADD += $(ldaplibs) +endif if !USE_LDAPWRAPPER dirmngr_LDADD += $(ldaplibs) endif diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index 8e2f520..1797828 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -1,6 +1,7 @@ /* ks-action.c - OpenPGP keyserver actions * Copyright (C) 2011 Free Software Foundation, Inc. * Copyright (C) 2011, 2014 Werner Koch + * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -29,7 +30,7 @@ #include "misc.h" #include "ks-engine.h" #include "ks-action.h" - +#include "ldap-parse-uri.h" /* Called by the engine's help functions to print the actual help. */ gpg_error_t @@ -72,7 +73,15 @@ ks_action_help (ctrl_t ctrl, const char *url) } else { - err = http_parse_uri (&parsed_uri, url, 1); + int is_ldap = (strcmp (parsed_uri->scheme, "ldap") == 0 + || strcmp (parsed_uri->scheme, "ldaps") == 0 + || strcmp (parsed_uri->scheme, "ldapi") == 0); + + if (is_ldap) + err = ldap_parse_uri (&parsed_uri, url); + else + err = http_parse_uri (&parsed_uri, url, 1); + if (err) return err; } @@ -85,6 +94,8 @@ ks_action_help (ctrl_t ctrl, const char *url) err = ks_finger_help (ctrl, parsed_uri); if (!err) err = ks_kdns_help (ctrl, parsed_uri); + if (!err) + err = ks_ldap_help (ctrl, parsed_uri); if (!parsed_uri) ks_print_help (ctrl, @@ -142,10 +153,18 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp) stop at the first error. */ for (uri = ctrl->keyservers; !err && uri; uri = uri->next) { - if (uri->parsed_uri->is_http) + int is_http = uri->parsed_uri->is_http; + int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 + || strcmp (uri->parsed_uri->scheme, "ldaps") == 0 + || strcmp (uri->parsed_uri->scheme, "ldapi") == 0); + if (is_http || is_ldap) { any_server = 1; - err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d, &infp); + if (is_http) + err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d, &infp); + else if (is_ldap) + err = ks_ldap_search (ctrl, uri->parsed_uri, patterns->d, &infp); + if (!err) { err = copy_stream (infp, outfp); @@ -185,12 +204,20 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp) Need to think about a better strategy. */ for (uri = ctrl->keyservers; !err && uri; uri = uri->next) { - if (uri->parsed_uri->is_http) + int is_http = uri->parsed_uri->is_http; + int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 + || strcmp (uri->parsed_uri->scheme, "ldaps") == 0 + || strcmp (uri->parsed_uri->scheme, "ldapi") == 0); + if (is_http || is_ldap) { any_server = 1; for (sl = patterns; !err && sl; sl = sl->next) { - err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp); + if (is_http) + err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp); + else + err = ks_ldap_get (ctrl, uri->parsed_uri, sl->d, &infp); + if (err) { /* It is possible that a server does not carry a @@ -282,9 +309,14 @@ ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp) /* Send an OpenPGP key to all keyservers. The key in {DATA,DATALEN} - is expected in OpenPGP binary transport format. */ + is expected to be in OpenPGP binary transport format. The metadata + in {INFO,INFOLEN} is in colon-separated format (concretely, it is + the output of 'for x in keys sigs; do gpg --list-$x --with-colons + KEYID; done'. This function may modify DATA and INFO. If this is + a problem, then the caller should create a copy. */ gpg_error_t -ks_action_put (ctrl_t ctrl, const void *data, size_t datalen) +ks_action_put (ctrl_t ctrl, void *data, size_t datalen, + void *info, size_t infolen) { gpg_error_t err = 0; gpg_error_t first_err = 0; @@ -293,10 +325,20 @@ ks_action_put (ctrl_t ctrl, const void *data, size_t datalen) for (uri = ctrl->keyservers; !err && uri; uri = uri->next) { - if (uri->parsed_uri->is_http) + int is_http = uri->parsed_uri->is_http; + int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 + || strcmp (uri->parsed_uri->scheme, "ldaps") == 0 + || strcmp (uri->parsed_uri->scheme, "ldapi") == 0); + + if (is_http || is_ldap) { any_server = 1; - err = ks_hkp_put (ctrl, uri->parsed_uri, data, datalen); + if (is_http) + err = ks_hkp_put (ctrl, uri->parsed_uri, data, datalen); + else + err = ks_ldap_put (ctrl, uri->parsed_uri, data, datalen, + info, infolen); + if (err) { first_err = err; diff --git a/dirmngr/ks-action.h b/dirmngr/ks-action.h index 5c8a5cd..2def3dc 100644 --- a/dirmngr/ks-action.h +++ b/dirmngr/ks-action.h @@ -1,5 +1,6 @@ /* ks-action.h - OpenPGP keyserver actions definitions * Copyright (C) 2011 Free Software Foundation, Inc. + * 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -25,7 +26,8 @@ gpg_error_t ks_action_resolve (ctrl_t ctrl); gpg_error_t ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp); gpg_error_t ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp); gpg_error_t ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp); -gpg_error_t ks_action_put (ctrl_t ctrl, const void *data, size_t datalen); +gpg_error_t ks_action_put (ctrl_t ctrl, void *data, size_t datalen, + void *info, size_t infolen); #endif /*DIRMNGR_KS_ACTION_H*/ diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c new file mode 100644 index 0000000..77e0ec2 --- /dev/null +++ b/dirmngr/ks-engine-ldap.c @@ -0,0 +1,2000 @@ +/* ks-engine-ldap.c - talk to a LDAP keyserver + * Copyright (C) 2001, 2002, 2004, 2005, 2006 + * 2007 Free Software Foundation, Inc. + * Copyright (C) 2015 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 +#ifdef HAVE_GETOPT_H +# include +#endif +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# ifdef NEED_LBER_H +# include +# endif +/* For OpenLDAP, to enable the API that we're using. */ +# define LDAP_DEPRECATED 1 +# include +#endif + +#include "dirmngr.h" +#include "misc.h" +#include "userids.h" +#include "ks-engine.h" +#include "ldap-parse-uri.h" + +#ifdef __riscos__ +# include "util.h" +#endif + +#ifndef HAVE_TIMEGM +time_t timegm(struct tm *tm); +#endif + +/* Convert an LDAP error to a GPG error. */ +static int +ldap_err_to_gpg_err (int code) +{ + gpg_err_code_t ec; + + switch (code) + { +#ifdef LDAP_X_CONNECTING + case LDAP_X_CONNECTING: ec = GPG_ERR_LDAP_X_CONNECTING; break; +#endif + + case LDAP_REFERRAL_LIMIT_EXCEEDED: ec = GPG_ERR_LDAP_REFERRAL_LIMIT; break; + case LDAP_CLIENT_LOOP: ec = GPG_ERR_LDAP_CLIENT_LOOP; break; + case LDAP_NO_RESULTS_RETURNED: ec = GPG_ERR_LDAP_NO_RESULTS; break; + case LDAP_CONTROL_NOT_FOUND: ec = GPG_ERR_LDAP_CONTROL_NOT_FOUND; break; + case LDAP_NOT_SUPPORTED: ec = GPG_ERR_LDAP_NOT_SUPPORTED; break; + case LDAP_CONNECT_ERROR: ec = GPG_ERR_LDAP_CONNECT; break; + case LDAP_NO_MEMORY: ec = GPG_ERR_LDAP_NO_MEMORY; break; + case LDAP_PARAM_ERROR: ec = GPG_ERR_LDAP_PARAM; break; + case LDAP_USER_CANCELLED: ec = GPG_ERR_LDAP_USER_CANCELLED; break; + case LDAP_FILTER_ERROR: ec = GPG_ERR_LDAP_FILTER; break; + case LDAP_AUTH_UNKNOWN: ec = GPG_ERR_LDAP_AUTH_UNKNOWN; break; + case LDAP_TIMEOUT: ec = GPG_ERR_LDAP_TIMEOUT; break; + case LDAP_DECODING_ERROR: ec = GPG_ERR_LDAP_DECODING; break; + case LDAP_ENCODING_ERROR: ec = GPG_ERR_LDAP_ENCODING; break; + case LDAP_LOCAL_ERROR: ec = GPG_ERR_LDAP_LOCAL; break; + case LDAP_SERVER_DOWN: ec = GPG_ERR_LDAP_SERVER_DOWN; break; + + case LDAP_SUCCESS: ec = GPG_ERR_LDAP_SUCCESS; break; + + case LDAP_OPERATIONS_ERROR: ec = GPG_ERR_LDAP_OPERATIONS; break; + case LDAP_PROTOCOL_ERROR: ec = GPG_ERR_LDAP_PROTOCOL; break; + case LDAP_TIMELIMIT_EXCEEDED: ec = GPG_ERR_LDAP_TIMELIMIT; break; + case LDAP_SIZELIMIT_EXCEEDED: ec = GPG_ERR_LDAP_SIZELIMIT; break; + case LDAP_COMPARE_FALSE: ec = GPG_ERR_LDAP_COMPARE_FALSE; break; + case LDAP_COMPARE_TRUE: ec = GPG_ERR_LDAP_COMPARE_TRUE; break; + case LDAP_AUTH_METHOD_NOT_SUPPORTED: ec=GPG_ERR_LDAP_UNSUPPORTED_AUTH;break; + case LDAP_STRONG_AUTH_REQUIRED: ec = GPG_ERR_LDAP_STRONG_AUTH_RQRD; break; + case LDAP_PARTIAL_RESULTS: ec = GPG_ERR_LDAP_PARTIAL_RESULTS; break; + case LDAP_REFERRAL: ec = GPG_ERR_LDAP_REFERRAL; break; + +#ifdef LDAP_ADMINLIMIT_EXCEEDED + case LDAP_ADMINLIMIT_EXCEEDED: ec = GPG_ERR_LDAP_ADMINLIMIT; break; +#endif + +#ifdef LDAP_UNAVAILABLE_CRITICAL_EXTENSION + case LDAP_UNAVAILABLE_CRITICAL_EXTENSION: + ec = GPG_ERR_LDAP_UNAVAIL_CRIT_EXTN; break; +#endif + + case LDAP_CONFIDENTIALITY_REQUIRED: ec = GPG_ERR_LDAP_CONFIDENT_RQRD; break; + case LDAP_SASL_BIND_IN_PROGRESS: ec = GPG_ERR_LDAP_SASL_BIND_INPROG; break; + case LDAP_NO_SUCH_ATTRIBUTE: ec = GPG_ERR_LDAP_NO_SUCH_ATTRIBUTE; break; + case LDAP_UNDEFINED_TYPE: ec = GPG_ERR_LDAP_UNDEFINED_TYPE; break; + case LDAP_INAPPROPRIATE_MATCHING: ec = GPG_ERR_LDAP_BAD_MATCHING; break; + case LDAP_CONSTRAINT_VIOLATION: ec = GPG_ERR_LDAP_CONST_VIOLATION; break; + +#ifdef LDAP_TYPE_OR_VALUE_EXISTS + case LDAP_TYPE_OR_VALUE_EXISTS: ec = GPG_ERR_LDAP_TYPE_VALUE_EXISTS; break; +#endif + + case LDAP_INVALID_SYNTAX: ec = GPG_ERR_LDAP_INV_SYNTAX; break; + case LDAP_NO_SUCH_OBJECT: ec = GPG_ERR_LDAP_NO_SUCH_OBJ; break; + case LDAP_ALIAS_PROBLEM: ec = GPG_ERR_LDAP_ALIAS_PROBLEM; break; + case LDAP_INVALID_DN_SYNTAX: ec = GPG_ERR_LDAP_INV_DN_SYNTAX; break; + case LDAP_IS_LEAF: ec = GPG_ERR_LDAP_IS_LEAF; break; + case LDAP_ALIAS_DEREF_PROBLEM: ec = GPG_ERR_LDAP_ALIAS_DEREF; break; + +#ifdef LDAP_X_PROXY_AUTHZ_FAILURE + case LDAP_X_PROXY_AUTHZ_FAILURE: ec = GPG_ERR_LDAP_X_PROXY_AUTH_FAIL; break; +#endif + + case LDAP_INAPPROPRIATE_AUTH: ec = GPG_ERR_LDAP_BAD_AUTH; break; + case LDAP_INVALID_CREDENTIALS: ec = GPG_ERR_LDAP_INV_CREDENTIALS; break; + +#ifdef LDAP_INSUFFICIENT_ACCESS + case LDAP_INSUFFICIENT_ACCESS: ec = GPG_ERR_LDAP_INSUFFICIENT_ACC; break; +#endif + + case LDAP_BUSY: ec = GPG_ERR_LDAP_BUSY; break; + case LDAP_UNAVAILABLE: ec = GPG_ERR_LDAP_UNAVAILABLE; break; + case LDAP_UNWILLING_TO_PERFORM: ec = GPG_ERR_LDAP_UNWILL_TO_PERFORM; break; + case LDAP_LOOP_DETECT: ec = GPG_ERR_LDAP_LOOP_DETECT; break; + case LDAP_NAMING_VIOLATION: ec = GPG_ERR_LDAP_NAMING_VIOLATION; break; + case LDAP_OBJECT_CLASS_VIOLATION: ec = GPG_ERR_LDAP_OBJ_CLS_VIOLATION; break; + case LDAP_NOT_ALLOWED_ON_NONLEAF: ec=GPG_ERR_LDAP_NOT_ALLOW_NONLEAF;break; + case LDAP_NOT_ALLOWED_ON_RDN: ec = GPG_ERR_LDAP_NOT_ALLOW_ON_RDN; break; + case LDAP_ALREADY_EXISTS: ec = GPG_ERR_LDAP_ALREADY_EXISTS; break; + case LDAP_NO_OBJECT_CLASS_MODS: ec = GPG_ERR_LDAP_NO_OBJ_CLASS_MODS; break; + case LDAP_RESULTS_TOO_LARGE: ec = GPG_ERR_LDAP_RESULTS_TOO_LARGE; break; + case LDAP_AFFECTS_MULTIPLE_DSAS: ec = GPG_ERR_LDAP_AFFECTS_MULT_DSAS; break; + +#ifdef LDAP_VLV_ERROR + case LDAP_VLV_ERROR: ec = GPG_ERR_LDAP_VLV; break; +#endif + + case LDAP_OTHER: ec = GPG_ERR_LDAP_OTHER; break; + +#ifdef LDAP_CUP_RESOURCES_EXHAUSTED + case LDAP_CUP_RESOURCES_EXHAUSTED: ec=GPG_ERR_LDAP_CUP_RESOURCE_LIMIT;break; + case LDAP_CUP_SECURITY_VIOLATION: ec=GPG_ERR_LDAP_CUP_SEC_VIOLATION; break; + case LDAP_CUP_INVALID_DATA: ec = GPG_ERR_LDAP_CUP_INV_DATA; break; + case LDAP_CUP_UNSUPPORTED_SCHEME: ec = GPG_ERR_LDAP_CUP_UNSUP_SCHEME; break; + case LDAP_CUP_RELOAD_REQUIRED: ec = GPG_ERR_LDAP_CUP_RELOAD; break; +#endif + +#ifdef LDAP_CANCELLED + case LDAP_CANCELLED: ec = GPG_ERR_LDAP_CANCELLED; break; +#endif + +#ifdef LDAP_NO_SUCH_OPERATION + case LDAP_NO_SUCH_OPERATION: ec = GPG_ERR_LDAP_NO_SUCH_OPERATION; break; +#endif + +#ifdef LDAP_TOO_LATE + case LDAP_TOO_LATE: ec = GPG_ERR_LDAP_TOO_LATE; break; +#endif + +#ifdef LDAP_CANNOT_CANCEL + case LDAP_CANNOT_CANCEL: ec = GPG_ERR_LDAP_CANNOT_CANCEL; break; +#endif + +#ifdef LDAP_ASSERTION_FAILED + case LDAP_ASSERTION_FAILED: ec = GPG_ERR_LDAP_ASSERTION_FAILED; break; +#endif + +#ifdef LDAP_PROXIED_AUTHORIZATION_DENIED + case LDAP_PROXIED_AUTHORIZATION_DENIED: + ec = GPG_ERR_LDAP_PROX_AUTH_DENIED; break; +#endif + + default: +#if defined(LDAP_E_ERROR) && defined(LDAP_X_ERROR) + if (LDAP_E_ERROR (code)) + ec = GPG_ERR_LDAP_E_GENERAL; + else if (LDAP_X_ERROR (code)) + ec = GPG_ERR_LDAP_X_GENERAL; + else +#endif + ec = GPG_ERR_LDAP_GENERAL; + break; + } + + return ec; +} + +/* Retrieve an LDAP error and return it's GPG equivalent. */ +static int +ldap_to_gpg_err (LDAP *ld) +{ +#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) + int err; + + if (ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &err) == 0) + return ldap_err_to_gpg_err (err); + else + return GPG_ERR_GENERAL; +#elif defined(HAVE_LDAP_LD_ERRNO) + return ldap_err_to_gpg_err (ld->ld_errno); +#else + /* We should never get here since the LDAP library should always + have either ldap_get_option or ld_errno, but just in case... */ + return GPG_ERR_GENERAL; +#endif +} + +static time_t +ldap2epochtime (const char *timestr) +{ + struct tm pgptime; + time_t answer; + + memset (&pgptime, 0, sizeof(pgptime)); + + /* YYYYMMDDHHmmssZ */ + + sscanf (timestr, "%4d%2d%2d%2d%2d%2d", + &pgptime.tm_year, + &pgptime.tm_mon, + &pgptime.tm_mday, + &pgptime.tm_hour, + &pgptime.tm_min, + &pgptime.tm_sec); + + pgptime.tm_year -= 1900; + pgptime.tm_isdst = -1; + pgptime.tm_mon--; + + /* mktime() takes the timezone into account, so we use timegm() */ + + answer = timegm (&pgptime); + + return answer; +} + +/* Caller must free the result. */ +static char * +tm2ldaptime (struct tm *tm) +{ + struct tm tmp = *tm; + char buf[16]; + + /* YYYYMMDDHHmmssZ */ + + tmp.tm_year += 1900; + tmp.tm_mon ++; + + sprintf (buf, "%04d%02d%02d%02d%02d%02dZ", + tmp.tm_year, + tmp.tm_mon, + tmp.tm_mday, + tmp.tm_hour, + tmp.tm_min, + tmp.tm_sec); + + return xstrdup (buf); +} + +#if 0 +/* Caller must free */ +static char * +epoch2ldaptime (time_t stamp) +{ + struct tm tm; + if (gmtime_r (&stamp, &tm)) + return tm2ldaptime (&tm); + else + return xstrdup ("INVALID TIME"); +} +#endif + +/* Print a help output for the schemata supported by this module. */ +gpg_error_t +ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri) +{ + const char const data[] = + "Handler for LDAP URLs:\n" + " ldap://host:port/[BASEDN]???[bindname=BINDNAME,password=PASSWORD]\n" + "\n" + "Note: basedn, bindname and password need to be percent escaped. In\n" + "particular, spaces need to be replaced with %20 and commas with %2c.\n" + "bindname will typically be of the form:\n" + "\n" + " uid=user%2cou=PGP%20Users%2cdc=EXAMPLE%2cdc=ORG\n" + "\n" + "The ldaps:// and ldapi:// schemes are also supported. If ldaps is used\n" + "then the server's certificate will be checked. If it is not valid, any\n" + "operation will be aborted.\n" + "\n" + "Supported methods: search, get, put\n"; + gpg_error_t err; + + if (strcmp (uri->scheme, "ldap") == 0 + || strcmp (uri->scheme, "ldaps") == 0 + || strcmp (uri->scheme, "ldapi") == 0) + err = ks_print_help (ctrl, data); + else + err = 0; + + return err; +} + +/* Convert a keyspec to a filter. Return an error if the keyspec is + bad or is not supported. The filter is escaped and returned in + *filter. It is the caller's responsibility to free *filter. + *filter is only set if this function returns success (i.e., 0). */ +static gpg_error_t +keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) +{ + /* Remove search type indicator and adjust PATTERN accordingly. + Note: don't include a preceding 0x when searching by keyid. */ + + /* XXX: Should we include disabled / revoke options? */ + KEYDB_SEARCH_DESC desc; + char *f = NULL; + + gpg_error_t err = classify_user_id (keyspec, &desc, 1); + if (err) + return err; + + switch (desc.mode) + { + case KEYDB_SEARCH_MODE_EXACT: + f = xasprintf ("(pgpUserID=%s)", + ldap_escape_filter (desc.u.name)); + break; + + case KEYDB_SEARCH_MODE_SUBSTR: + if (! only_exact) + f = xasprintf ("(pgpUserID=*%s*)", + ldap_escape_filter (desc.u.name)); + break; + + case KEYDB_SEARCH_MODE_MAIL: + if (! only_exact) + f = xasprintf ("(pgpUserID=*<%s>*)", + ldap_escape_filter (desc.u.name)); + break; + + case KEYDB_SEARCH_MODE_MAILSUB: + if (! only_exact) + f = xasprintf ("(pgpUserID=*<*%s*>*)", + ldap_escape_filter (desc.u.name)); + break; + + case KEYDB_SEARCH_MODE_MAILEND: + if (! only_exact) + f = xasprintf ("(pgpUserID=*<*%s>*)", + ldap_escape_filter (desc.u.name)); + break; + + case KEYDB_SEARCH_MODE_SHORT_KID: + f = xasprintf ("(pgpKeyID=%08lX)", (ulong) desc.u.kid[1]); + break; + case KEYDB_SEARCH_MODE_LONG_KID: + f = xasprintf ("(pgpCertID=%08lX%08lX)", + (ulong) desc.u.kid[0], (ulong) desc.u.kid[1]); + break; + + case KEYDB_SEARCH_MODE_FPR16: + case KEYDB_SEARCH_MODE_FPR20: + case KEYDB_SEARCH_MODE_FPR: + case KEYDB_SEARCH_MODE_ISSUER: + case KEYDB_SEARCH_MODE_ISSUER_SN: + case KEYDB_SEARCH_MODE_SN: + case KEYDB_SEARCH_MODE_SUBJECT: + case KEYDB_SEARCH_MODE_KEYGRIP: + case KEYDB_SEARCH_MODE_WORDS: + case KEYDB_SEARCH_MODE_FIRST: + case KEYDB_SEARCH_MODE_NEXT: + default: + break; + } + + if (! f) + { + log_error ("Unsupported search mode.\n"); + return gpg_error (GPG_ERR_NOT_SUPPORTED); + } + + *filter = f; + + return 0; +} + +/* Connect to an LDAP server and interrogate it. + + - uri describes the server to connect to and various options + including whether to use TLS and the username and password (see + ldap_parse_uri for a description of the various fields). + + This function returns: + + - The ldap connection handle in *LDAP_CONNP. + + - The base DN for the PGP key space by querying the + pgpBaseKeySpaceDN attribute (This is normally + 'ou=PGP Keys,dc=EXAMPLE,dc=ORG'). + + - The attribute to lookup to find the pgp key. This is either + 'pgpKey' or 'pgpKeyV2'. + + - Whether this is a real ldap server. (It's unclear what this + exactly means.) + + The values are returned in the passed variables. If you pass NULL, + then the value won't be returned. It is the caller's + responsibility to release *LDAP_CONNP with ldap_unbind and xfree + *BASEDNP and *PGPKEYATTRP. + + If this function successfully interrogated the server, it returns + 0. If there was an LDAP error, it returns the LDAP error code. If + an error occured, *basednp, etc., are undefined (and don't need to + be freed.) + + If no LDAP error occured, you still need to check that *basednp is + valid. If it is NULL, then the server does not appear to be an + OpenPGP Keyserver. In this case, you also do not need to free + *pgpkeyattrp. */ +static int +ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, + char **basednp, char **pgpkeyattrp, int *real_ldapp) +{ + int err = 0; + + LDAP *ldap_conn = NULL; + + char *user = uri->auth; + struct uri_tuple_s *password_param = uri_query_lookup (uri, "password"); + char *password = password_param ? password_param->value : NULL; + + char *basedn = NULL; + /* Whether to look for the pgpKey or pgpKeyv2 attribute. */ + char *pgpkeyattr = "pgpKey"; + int real_ldap = 0; + + log_debug ("ldap_connect(%s:%d/%s????%s%s%s%s%s)\n", + uri->host, uri->port, + uri->path ?: "", + uri->auth ? "bindname=" : "", uri->auth ?: "", + uri->auth && password ? "," : "", + password ? "password=" : "", password ?: ""); + + /* If the uri specifies a secure connection and we don't support + TLS, then fail; don't silently revert to an insecure + connection. */ + if (uri->use_tls) + { +#ifndef HAVE_LDAP_START_TLS_S + log_error ("Can't use LDAP to connect to the server: no TLS support."); + err = GPG_ERR_LDAP_NOT_SUPPORTED; + goto out; +#endif + } + + ldap_conn = ldap_init (uri->host, uri->port); + if (! ldap_conn) + { + log_error ("Failed to open connection to LDAP server (%s://%s:%d)\n", + uri->scheme, uri->host, uri->port); + err = gpg_err_code_from_errno (errno); + goto out; + } + +#ifdef HAVE_LDAP_SET_OPTION + { + int ver = LDAP_VERSION3; + + err = ldap_set_option (ldap_conn, LDAP_OPT_PROTOCOL_VERSION, &ver); + if (err != LDAP_SUCCESS) + { + log_error ("gpgkeys: unable to go to LDAP 3: %s\n", + ldap_err2string (err)); + goto out; + } + } +#endif + + /* XXX: It would be nice to have an option to provide the server's + certificate. */ +#if 0 +#if defined(LDAP_OPT_X_TLS_CACERTFILE) && defined(HAVE_LDAP_SET_OPTION) + err = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, ca_cert_file); + if (err) + { + log_error ("unable to set ca-cert-file to '%s': %s\n", + ca_cert_file, ldap_err2string (err)); + goto out; + } +#endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */ +#endif + +#ifndef HAVE_LDAP_START_TLS_S + if (uri->use_tls) + { + /* XXX: We need an option to determine whether to abort if the + certificate is bad or not. Right now we conservatively + default to checking the certificate and aborting. */ + int check_cert = LDAP_OPT_X_TLS_HARD; // LDAP_OPT_X_TLS_NEVER + + err = ldap_set_option (ldap_conn, + LDAP_OPT_X_TLS_REQUIRE_CERT, &check_cert); + if (err) + { + log_error ("Failed to set TLS option on LDAP connection.\n"); + goto out; + } + + err = ldap_start_tls_s (ldap_conn, NULL, NULL); + if (err) + { + log_error ("Failed to connect to LDAP server with TLS.\n"); + goto out; + } + } +#endif + + /* By default we don't bind as there is usually no need to. */ + if (uri->auth) + { + log_debug ("LDAP bind to %s, password %s\n", + user, password ? ">not shown<" : ">none<"); + + err = ldap_simple_bind_s (ldap_conn, user, password); + if (err != LDAP_SUCCESS) + { + log_error ("Internal LDAP bind error: %s\n", + ldap_err2string (err)); + goto out; + } + } + + if (uri->path && *uri->path) + /* User specified base DN. */ + { + basedn = xstrdup (uri->path); + + /* If the user specifies a base DN, then we know the server is a + real LDAP server. */ + real_ldap = 1; + } + else + { + LDAPMessage *res = NULL; + /* Look for namingContexts. */ + char *attr[] = { "namingContexts", NULL }; + + err = ldap_search_s (ldap_conn, "", LDAP_SCOPE_BASE, + "(objectClass=*)", attr, 0, &res); + if (err == LDAP_SUCCESS) + { + char **context = ldap_get_values (ldap_conn, res, "namingContexts"); + if (context) + /* We found some, so try each namingContext as the search + base and look for pgpBaseKeySpaceDN. Because we found + this, we know we're talking to a regular-ish LDAP + server and not an LDAP keyserver. */ + { + int i; + char *attr2[] = + { "pgpBaseKeySpaceDN", "pgpVersion", "pgpSoftware", NULL }; + + real_ldap = 1; + + for (i = 0; context[i] && ! basedn; i++) + { + char **vals; + LDAPMessage *si_res; + + char *object = xasprintf ("cn=pgpServerInfo,%s", context[i]); + err = ldap_search_s (ldap_conn, object, LDAP_SCOPE_BASE, + "(objectClass=*)", attr2, 0, &si_res); + free (object); + + if (err == LDAP_SUCCESS) + { + vals = ldap_get_values (ldap_conn, si_res, + "pgpBaseKeySpaceDN"); + if (vals) + { + basedn = strdup (vals[0]); + ldap_value_free (vals); + } + + vals = ldap_get_values (ldap_conn, si_res, + "pgpSoftware"); + if (vals) + { + log_debug ("Server: \t%s\n", vals[0]); + ldap_value_free (vals); + } + + vals = ldap_get_values (ldap_conn, si_res, + "pgpVersion"); + if (vals) + { + log_debug ("Version:\t%s\n", vals[0]); + ldap_value_free (vals); + } + } + + /* From man ldap_search_s: "res parameter of + ldap_search_ext_s() and ldap_search_s() should be + freed with ldap_msgfree() regardless of return + value of these functions. */ + ldap_msgfree (si_res); + } + + ldap_value_free (context); + } + } + else + { + /* We don't have an answer yet, which means the server might + be an LDAP keyserver. */ + char **vals; + LDAPMessage *si_res = NULL; + + char *attr2[] = { "pgpBaseKeySpaceDN", "version", "software", NULL }; + + err = ldap_search_s (ldap_conn, "cn=pgpServerInfo", LDAP_SCOPE_BASE, + "(objectClass=*)", attr2, 0, &si_res); + if (err == LDAP_SUCCESS) + { + /* For the LDAP keyserver, this is always + "OU=ACTIVE,O=PGP KEYSPACE,C=US", but it might not be + in the future. */ + + vals = ldap_get_values (ldap_conn, si_res, "baseKeySpaceDN"); + if (vals) + { + basedn = strdup (vals[0]); + ldap_value_free (vals); + } + + vals = ldap_get_values (ldap_conn, si_res, "software"); + if (vals) + { + log_debug ("ldap: Server: \t%s\n", vals[0]); + ldap_value_free (vals); + } + + vals = ldap_get_values (ldap_conn, si_res, "version"); + if (vals) + { + log_debug ("ldap: Version:\t%s\n", vals[0]); + + /* If the version is high enough, use the new + pgpKeyV2 attribute. This design is iffy at best, + but it matches how PGP does it. I figure the NAI + folks assumed that there would never be an LDAP + keyserver vendor with a different numbering + scheme. */ + if (atoi (vals[0]) > 1) + pgpkeyattr = "pgpKeyV2"; + + ldap_value_free (vals); + } + } + + ldap_msgfree (si_res); + } + + /* From man ldap_search_s: "res parameter of ldap_search_ext_s() + and ldap_search_s() should be freed with ldap_msgfree() + regardless of return value of these functions. */ + ldap_msgfree (res); + } + + out: + if (! err) + { + log_debug ("ldap_conn: %p\n", ldap_conn); + log_debug ("real_ldap: %d\n", real_ldap); + log_debug ("basedn: %s\n", basedn); + log_debug ("pgpkeyattr: %s\n", pgpkeyattr); + } + + if (! err && real_ldapp) + *real_ldapp = real_ldap; + + if (err) + xfree (basedn); + else + { + if (pgpkeyattrp) + { + if (basedn) + *pgpkeyattrp = xstrdup (pgpkeyattr); + else + *pgpkeyattrp = NULL; + } + + if (basednp) + *basednp = basedn; + else + xfree (basedn); + } + + if (err) + { + if (ldap_conn) + ldap_unbind (ldap_conn); + } + else + *ldap_connp = ldap_conn; + + return err; +} + +/* Extract keys from an LDAP reply and write them out to the output + stream OUTPUT in a format GnuPG can import (either the OpenPGP + binary format or armored format). */ +static void +extract_keys (estream_t output, + LDAP *ldap_conn, const char *certid, LDAPMessage *message) +{ + char **vals; + + es_fprintf (output, "INFO %s BEGIN\n", certid); + es_fprintf (output, "pub:%s:", certid); + + /* Note: ldap_get_values returns a NULL terminates array of + strings. */ + vals = ldap_get_values (ldap_conn, message, "pgpkeytype"); + if (vals && vals[0]) + { + if (strcmp (vals[0], "RSA") == 0) + es_fprintf (output, "1"); + else if (strcmp (vals[0],"DSS/DH") == 0) + es_fprintf (output, "17"); + ldap_value_free (vals); + } + + es_fprintf (output, ":"); + + vals = ldap_get_values (ldap_conn, message, "pgpkeysize"); + if (vals && vals[0]) + { + int v = atoi (vals[0]); + if (v > 0) + es_fprintf (output, "%d", v); + ldap_value_free (vals); + } + + es_fprintf (output, ":"); + + vals = ldap_get_values (ldap_conn, message, "pgpkeycreatetime"); + if (vals && vals[0]) + { + if (strlen (vals[0]) == 15) + es_fprintf (output, "%u", (unsigned int) ldap2epochtime (vals[0])); + ldap_value_free (vals); + } + + es_fprintf (output, ":"); + + vals = ldap_get_values (ldap_conn, message, "pgpkeyexpiretime"); + if (vals && vals[0]) + { + if (strlen (vals[0]) == 15) + es_fprintf (output, "%u", (unsigned int) ldap2epochtime (vals[0])); + ldap_value_free (vals); + } + + es_fprintf (output, ":"); + + vals = ldap_get_values (ldap_conn, message, "pgprevoked"); + if (vals && vals[0]) + { + if (atoi (vals[0]) == 1) + es_fprintf (output, "r"); + ldap_value_free (vals); + } + + es_fprintf (output, "\n"); + + vals = ldap_get_values (ldap_conn, message, "pgpuserid"); + if (vals && vals[0]) + { + int i; + for (i = 0; vals[i]; i++) + es_fprintf (output, "uid:%s\n", vals[i]); + ldap_value_free (vals); + } + + es_fprintf (output, "INFO %s END\n", certid); +} + +/* Get the key described key the KEYSPEC string from the keyserver + identified by URI. On success R_FP has an open stream to read the + data. */ +gpg_error_t +ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, + estream_t *r_fp) +{ + gpg_error_t err = 0; + int ldap_err; + + char *filter = NULL; + + LDAP *ldap_conn = NULL; + + char *basedn = NULL; + char *pgpkeyattr = NULL; + + estream_t fp = NULL; + + LDAPMessage *message = NULL; + + (void) ctrl; + + /* Before connecting to the server, make sure we have a sane + keyspec. If not, there is no need to establish a network + connection. */ + err = keyspec_to_ldap_filter (keyspec, &filter, 1); + if (err) + return (err); + + /* Make sure we are talking to an OpenPGP LDAP server. */ + ldap_err = ldap_connect (uri, &ldap_conn, &basedn, &pgpkeyattr, NULL); + if (ldap_err || !basedn) + { + if (ldap_err) + err = ldap_err_to_gpg_err (ldap_err); + else + err = GPG_ERR_GENERAL; + goto out; + } + + { + /* The ordering is significant. Specifically, "pgpcertid" needs + to be the second item in the list, since everything after it + may be discarded we aren't in verbose mode. */ + char *attrs[] = + { + pgpkeyattr, + "pgpcertid", "pgpuserid", "pgpkeyid", "pgprevoked", "pgpdisabled", + "pgpkeycreatetime", "modifytimestamp", "pgpkeysize", "pgpkeytype", + NULL + }; + /* 1 if we want just attribute types; 0 if we want both attribute + types and values. */ + int attrsonly = 0; + + int count; + + ldap_err = ldap_search_s (ldap_conn, basedn, LDAP_SCOPE_SUBTREE, + filter, attrs, attrsonly, &message); + if (ldap_err) + { + err = ldap_err_to_gpg_err (ldap_err); + + log_error ("gpgkeys: LDAP search error: %s\n", + ldap_err2string (ldap_err)); + log_error ("KEY 0x%s BEGIN\n", keyspec); + log_error ("KEY 0x%s FAILED %d\n", keyspec, err); + goto out; + } + + count = ldap_count_entries (ldap_conn, message); + if (count < 1) + { + log_error ("gpgkeys: key %s not found on keyserver\n", keyspec); + + if (count == -1) + err = ldap_to_gpg_err (ldap_conn); + else + err = gpg_error (GPG_ERR_NO_DATA); + + goto out; + } + + { + /* There may be more than one unique result for a given keyID, + so we should fetch them all (test this by fetching short key + id 0xDEADBEEF). */ + + /* The set of entries that we've seen. */ + strlist_t seen = NULL; + LDAPMessage *each; + + for (each = ldap_first_entry (ldap_conn, message); + each; + each = ldap_next_entry (ldap_conn, each)) + { + char **vals; + char **certid; + + /* Use the long keyid to remove duplicates. The LDAP + server returns the same keyid more than once if there + are multiple user IDs on the key. Note that this does + NOT mean that a keyid that exists multiple times on the + keyserver will not be fetched. It means that each KEY, + no matter how many user IDs share its keyid, will be + fetched only once. If a keyid that belongs to more + than one key is fetched, the server quite properly + responds with all matching keys. -ds */ + + certid = ldap_get_values (ldap_conn, each, "pgpcertid"); + if (certid && certid[0]) + { + if (! strlist_find (seen, certid[0])) + { + /* It's not a duplicate, add it */ + + add_to_strlist (&seen, certid[0]); + + if (! fp) + fp = es_fopenmem(0, "rw"); + + extract_keys (fp, ldap_conn, certid[0], each); + + log_debug ("KEY 0x%s BEGIN\n", certid[0]); + + vals = ldap_get_values (ldap_conn, each, pgpkeyattr); + if (! vals) + { + err = ldap_to_gpg_err (ldap_conn); + log_error("gpgkeys: unable to retrieve key %s " + "from keyserver\n", certid[0]); + goto out; + } + else + { + /* We should strip the new lines. */ + es_fprintf (fp, "KEY 0x%s BEGIN\n", certid[0]); + es_fputs (vals[0], fp); + es_fprintf (fp, "\nKEY 0x%s END\n", certid[0]); + + ldap_value_free (vals); + } + } + } + + ldap_value_free (certid); + } + + free_strlist (seen); + + if (! fp) + err = gpg_error (GPG_ERR_NO_DATA); + } + } + + out: + if (message) + ldap_msgfree (message); + + if (err) + { + if (fp) + es_fclose (fp); + } + else + { + if (fp) + es_fseek (fp, 0, SEEK_SET); + + *r_fp = fp; + } + + xfree (pgpkeyattr); + xfree (basedn); + + if (ldap_conn) + ldap_unbind (ldap_conn); + + xfree (filter); + + return err; +} + +/* Search the keyserver identified by URI for keys matching PATTERN. + On success R_FP has an open stream to read the data. */ +gpg_error_t +ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, + estream_t *r_fp) +{ + gpg_error_t err; + int ldap_err; + + char *filter = NULL; + + LDAP *ldap_conn = NULL; + + char *basedn = NULL; + + estream_t fp = NULL; + + (void) ctrl; + + /* Before connecting to the server, make sure we have a sane + keyspec. If not, there is no need to establish a network + connection. */ + err = keyspec_to_ldap_filter (pattern, &filter, 0); + if (err) + { + log_error ("Bad search pattern: '%s'\n", pattern); + return (err); + } + + /* Make sure we are talking to an OpenPGP LDAP server. */ + ldap_err = ldap_connect (uri, &ldap_conn, &basedn, NULL, NULL); + if (ldap_err || !basedn) + { + if (ldap_err) + err = ldap_err_to_gpg_err (ldap_err); + else + err = GPG_ERR_GENERAL; + goto out; + } + + /* Even if we have no results, we want to return a stream. */ + fp = es_fopenmem(0, "rw"); + + { + char **vals; + LDAPMessage *res, *each; + int count = 0; + strlist_t dupelist = NULL; + + /* The maximum size of the search, including the optional stuff + and the trailing \0 */ + char *attrs[] = + { + "pgpcertid", "pgpuserid", "pgprevoked", "pgpdisabled", + "pgpkeycreatetime", "pgpkeyexpiretime", "modifytimestamp", + "pgpkeysize", "pgpkeytype", NULL + }; + + log_debug ("SEARCH '%s' => '%s' BEGIN\n", pattern, filter); + + ldap_err = ldap_search_s (ldap_conn, basedn, + LDAP_SCOPE_SUBTREE, filter, attrs, 0, &res); + + xfree (filter); + filter = NULL; + + if (err != LDAP_SUCCESS && err != LDAP_SIZELIMIT_EXCEEDED) + { + err = ldap_err_to_gpg_err (ldap_err); + + log_error ("SEARCH %s FAILED %d\n", pattern, err); + log_error ("gpgkeys: LDAP search error: %s\n", + ldap_err2string (err)); + goto out; + } + + /* The LDAP server doesn't return a real count of unique keys, so we + can't use ldap_count_entries here. */ + for (each = ldap_first_entry (ldap_conn, res); + each; + each = ldap_next_entry (ldap_conn, each)) + { + char **certid = ldap_get_values (ldap_conn, each, "pgpcertid"); + if (certid && certid[0] && ! strlist_find (dupelist, certid[0])) + { + add_to_strlist (&dupelist, certid[0]); + count++; + } + } + + if (err == LDAP_SIZELIMIT_EXCEEDED) + { + if (count == 1) + log_error ("gpgkeys: search results exceeded server limit." + " First 1 result shown.\n"); + else + log_error ("gpgkeys: search results exceeded server limit." + " First %d results shown.\n", count); + } + + free_strlist (dupelist); + dupelist = NULL; + + if (count < 1) + es_fputs ("info:1:0\n", fp); + else + { + es_fprintf (fp, "info:1:%d\n", count); + + for (each = ldap_first_entry (ldap_conn, res); + each; + each = ldap_next_entry (ldap_conn, each)) + { + char **certid; + LDAPMessage *uids; + + certid = ldap_get_values (ldap_conn, each, "pgpcertid"); + if (! certid || ! certid[0]) + continue; + + /* Have we seen this certid before? */ + if (! strlist_find (dupelist, certid[0])) + { + add_to_strlist (&dupelist, certid[0]); + + es_fprintf (fp, "pub:%s:",certid[0]); + + vals = ldap_get_values (ldap_conn, each, "pgpkeytype"); + if (vals) + { + /* The LDAP server doesn't exactly handle this + well. */ + if (strcasecmp (vals[0], "RSA") == 0) + es_fputs ("1", fp); + else if (strcasecmp (vals[0], "DSS/DH") == 0) + es_fputs ("17", fp); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "pgpkeysize"); + if (vals) + { + /* Not sure why, but some keys are listed with a + key size of 0. Treat that like an + unknown. */ + if (atoi (vals[0]) > 0) + es_fprintf (fp, "%d", atoi (vals[0])); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + /* YYYYMMDDHHmmssZ */ + + vals = ldap_get_values (ldap_conn, each, "pgpkeycreatetime"); + if(vals && strlen (vals[0]) == 15) + { + es_fprintf (fp, "%u", + (unsigned int) ldap2epochtime(vals[0])); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "pgpkeyexpiretime"); + if (vals && strlen (vals[0]) == 15) + { + es_fprintf (fp, "%u", + (unsigned int) ldap2epochtime (vals[0])); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "pgprevoked"); + if (vals) + { + if (atoi (vals[0]) == 1) + es_fprintf (fp, "r"); + ldap_value_free (vals); + } + + vals = ldap_get_values (ldap_conn, each, "pgpdisabled"); + if (vals) + { + if (atoi (vals[0]) ==1) + es_fprintf (fp, "d"); + ldap_value_free (vals); + } + +#if 0 + /* This is not yet specified in the keyserver + protocol, but may be someday. */ + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "modifytimestamp"); + if(vals && strlen (vals[0]) == 15) + { + es_fprintf (fp, "%u", + (unsigned int) ldap2epochtime (vals[0])); + ldap_value_free (vals); + } +#endif + + es_fprintf (fp, "\n"); + + /* Now print all the uids that have this certid */ + for (uids = ldap_first_entry (ldap_conn, res); + uids; + uids = ldap_next_entry (ldap_conn, uids)) + { + vals = ldap_get_values (ldap_conn, uids, "pgpcertid"); + if (! vals) + continue; + + if (strcasecmp (certid[0], vals[0]) == 0) + { + char **uidvals; + + es_fprintf (fp, "uid:"); + + uidvals = ldap_get_values (ldap_conn, + uids, "pgpuserid"); + if (uidvals) + { + /* Need to escape any colons */ + char *quoted = percent_escape (uidvals[0], NULL); + es_fputs (quoted, fp); + xfree (quoted); + ldap_value_free (uidvals); + } + + es_fprintf (fp, "\n"); + } + + ldap_value_free(vals); + } + } + + ldap_value_free (certid); + } + } + + ldap_msgfree (res); + free_strlist (dupelist); + } + + log_debug ("SEARCH %s END\n", pattern); + + out: + if (err) + { + if (fp) + es_fclose (fp); + } + else + { + /* Return the read stream. */ + if (fp) + es_fseek (fp, 0, SEEK_SET); + + *r_fp = fp; + } + + xfree (basedn); + + if (ldap_conn) + ldap_unbind (ldap_conn); + + xfree (filter); + + return err; +} + +/* A modlist describes a set of changes to an LDAP entry. (An entry + consists of 1 or more attributes. Attributes are + pairs. Note: an attribute may be multi-valued in which case + multiple values are associated with a single name.) + + A modlist is a NULL terminated array of struct LDAPMod's. + + Thus, if we have: + + LDAPMod **modlist; + + Then: + + modlist[i] + + Is the ith modification. + + Each LDAPMod describes a change to a single attribute. Further, + there is one modification for each attribute that we want to + change. The attribute's new value is stored in LDAPMod.mod_values. + If the attribute is multi-valued, we still only use a single + LDAPMod structure: mod_values is a NULL-terminated array of + strings. To delete an attribute from an entry, we set mod_values + to NULL. + + Thus, if: + + modlist[i]->mod_values == NULL + + then we remove the attribute. + + (Using LDAP_MOD_DELETE doesn't work here as we don't know if the + attribute in question exists or not.) + + Note: this function does NOT copy or free ATTR. It does copy + VALUE. */ +static void +modlist_add (LDAPMod ***modlistp, char *attr, const char *value) +{ + LDAPMod **modlist = *modlistp; + + LDAPMod **m; + int nummods = 0; + + /* Search modlist for the attribute we're playing with. If modlist + is NULL, then the list is empty. Recall: modlist is a NULL + terminated array. */ + for (m = modlist; m && *m; m++, nummods ++) + { + if (strcasecmp ((*m)->mod_type, attr) != 0) + continue; + + /* The attribute is already on the list. */ + char **ptr; + int numvalues = 0; + + /* We have this attribute already, so when the REPLACE happens, + the server attributes will be replaced anyway. */ + if (! value) + return; + + /* Attributes can be multi-valued. See if the value is already + present. mod_values is a NULL terminated array of pointers. + Note: mod_values can be NULL. */ + for (ptr = (*m)->mod_values; ptr && *ptr; ptr++) + { + if (strcmp (*ptr, value) == 0) + /* Duplicate value, we're done. */ + return; + numvalues ++; + } + + /* Append the value. */ + ptr = xrealloc ((*m)->mod_values, sizeof (char *) * (numvalues + 2)); + + (*m)->mod_values = ptr; + ptr[numvalues] = xstrdup (value); + + ptr[numvalues + 1] = NULL; + + return; + } + + /* We didn't find the attr, so make one and add it to the end */ + + /* Like attribute values, the list of attributes is NULL terminated + array of pointers. */ + modlist = xrealloc (modlist, sizeof (LDAPMod *) * (nummods + 2)); + + *modlistp = modlist; + modlist[nummods] = xmalloc (sizeof (LDAPMod)); + + modlist[nummods]->mod_op = LDAP_MOD_REPLACE; + modlist[nummods]->mod_type = attr; + if (value) + { + modlist[nummods]->mod_values = xmalloc (sizeof(char *) * 2); + + /* XXX: Is this the right thing? Can a UTF8-encoded user ID + have embedded nulls? */ + modlist[nummods]->mod_values[0] = xstrdup (value); + modlist[nummods]->mod_values[1] = NULL; + } + else + modlist[nummods]->mod_values = NULL; + + modlist[nummods + 1] = NULL; + + return; +} + +/* Look up the value of an attribute in the specified modlist. If the + attribute is not on the mod list, returns NULL. The result is a + NULL-terminated array of strings. Don't change it. */ +static char ** +modlist_lookup (LDAPMod **modlist, const char *attr) +{ + LDAPMod **m; + for (m = modlist; m && *m; m++) + { + if (strcasecmp ((*m)->mod_type, attr) != 0) + continue; + + return (*m)->mod_values; + } + + return NULL; +} + +/* Dump a modlist to a file. This is useful for debugging. */ +static const estream_t modlist_dump (LDAPMod **modlist, estream_t output) + __attribute__ ((used)); + +static const estream_t +modlist_dump (LDAPMod **modlist, estream_t output) +{ + LDAPMod **m; + + int opened = 0; + if (! output) + { + output = es_fopenmem (0, "rw"); + opened = 1; + } + + for (m = modlist; m && *m; m++) + { + es_fprintf (output, " %s:", (*m)->mod_type); + + if (! (*m)->mod_values) + es_fprintf(output, " delete.\n"); + else + { + char **ptr; + int i; + + int multi = 0; + if ((*m)->mod_values[1] && (*m)->mod_values[2]) + /* Have at least 2. */ + multi = 1; + + if (multi) + es_fprintf (output, "\n"); + + for ((ptr = (*m)->mod_values), (i = 1); ptr && *ptr; ptr++, i ++) + { + const int max_len = 60; + size_t value_len = strlen (*ptr); + char buffer[max_len + 4]; + char *temp; + int elided = 0; + if (value_len > max_len) + { + temp = buffer; + memcpy (temp, *ptr, max_len); + temp[max_len] = temp[max_len + 1] = temp[max_len + 2] = '.'; + temp[max_len + 3] = 0; + elided = 1; + } + else + temp = *ptr; + + if (multi) + es_fprintf (output, " %d. ", i); + es_fprintf (output, "`%s'", temp); + if (elided) + es_fprintf (output, " (%zd bytes elided)", + value_len - max_len); + es_fprintf (output, "\n"); + } + } + } + + if (opened) + es_fseek (output, 0, SEEK_SET); + + return output; +} + +/* Free all of the memory allocated by the mod list. This assumes + that the attribute names don't have to be freed, but the attributes + values do. (Which is what modlist_add does.) */ +static void +modlist_free (LDAPMod **modlist) +{ + LDAPMod **ml; + + if (! modlist) + return; + + /* Unwind and free the whole modlist structure */ + + /* The modlist is a NULL terminated array of pointers. */ + for (ml = modlist; *ml; ml++) + { + LDAPMod *mod = *ml; + char **ptr; + + /* The list of values is a NULL termianted array of pointers. + If the list is NULL, there are no values. */ + + if (mod->mod_values) + { + for (ptr = mod->mod_values; *ptr; ptr++) + free (*ptr); + + free (mod->mod_values); + } + + free (mod); + } + free (modlist); +} + +/* Append two onto the end of one. Two is not freed, but its pointers + are now part of one. Make sure you don't free them both! + + As long as you don't add anything to ONE, TWO is still valid. + After that all bets are off. */ +static void +modlists_join (LDAPMod ***one, LDAPMod **two) +{ + int i, one_count = 0, two_count = 0; + LDAPMod **grow; + + if (!*two) + /* two is empty. Nothing to do. */ + return; + + if (!*one) + /* one is empty. Just set it equal to *two. */ + { + *one = *two; + return; + } + + for (grow = *one; *grow; grow++) + one_count ++; + + for (grow = two; *grow; grow++) + two_count ++; + + grow = xrealloc (*one, sizeof(LDAPMod *) * (one_count + two_count + 1)); + + for (i = 0; i < two_count; i++) + grow[one_count + i] = two[i]; + + grow[one_count + i] = NULL; + + *one = grow; +} + +/* Given a string, unescape C escapes. In particular, \xXX. This + modifies the string in place. */ +static void +uncescape (char *str) +{ + int r = 0; + int w = 0; + + char *first = strchr (str, '\\'); + if (! first) + /* No backslashes => no escaping. We're done. */ + return; + + /* Start at the first '\\'. */ + r = w = (uintptr_t) first - (uintptr_t) str; + + while (str[r]) + { + /* XXX: What to do about bad escapes? */ + if (str[r] == '\\' && str[r + 1] == 'x' + && (('0' <= str[r + 2] && str[r + 2] <= '9') + || ('a' <= str[r + 2] && str[r + 2] <= 'f') + || ('A' <= str[r + 2] && str[r + 2] <= 'F')) + && (('0' <= str[r + 3] && str[r + 3] <= '9') + || ('a' <= str[r + 3] && str[r + 3] <= 'f') + || ('A' <= str[r + 3] && str[r + 3] <= 'F'))) + { + int x = hextobyte (&str[r + 2]); + assert (0 <= x && x <= 0xff); + + str[w] = x; + + /* We consumed 4 characters and wrote 1. */ + r += 4; + w ++; + } + else + str[w ++] = str[r ++]; + } + + str[w] = '\0'; +} + +/* Given one line from an info block (`gpg --list-{keys,sigs} + --with-colons KEYID'), pull it apart and fill in the modlist with + the relevant (for the LDAP schema) attributes. */ +static void +extract_attributes (LDAPMod ***modlist, char *line) +{ + int i; + + int field_count; + char **fields; + + char *keyid; + + int is_pub, is_sub, is_uid, is_sig; + + /* Remove trailing whitespace */ + for (i = strlen (line) - 1; i >= 0 && ascii_isspace (line[i]); i--) + line[i] = '\0'; + + fields = strsplit (line, ':', '\0', &field_count); + if (field_count == 1) + /* We only have a single field. There is definately nothing to + do. */ + goto out; + + if (field_count < 7) + goto out; + + is_pub = strcasecmp ("pub", fields[0]) == 0; + is_sub = strcasecmp ("sub", fields[0]) == 0; + is_uid = strcasecmp ("uid", fields[0]) == 0; + is_sig = strcasecmp ("sig", fields[0]) == 0; + + if (!is_pub && !is_sub && !is_uid && !is_sig) + /* Not a relevant line. */ + goto out; + + keyid = fields[4]; + + if (is_uid && strlen (keyid) == 0) + /* The uid record type can have an empty keyid. */ + ; + else if (strlen (keyid) == 16 + && strspn (keyid, "0123456789aAbBcCdDeEfF") == 16) + /* Otherwise, we expect exactly 16 hex characters. */ + ; + else + { + log_error ("malformed keyid!\n"); + goto out; + } + + if (is_pub) + { + int disabled = 0, revoked = 0; + char *flags; + for (flags = fields[1]; *flags; flags ++) + switch (*flags) + { + case 'r': + case 'R': + revoked = 1; + break; + + case 'd': + case 'D': + disabled = 1; + break; + } + + /* Note: we always create the pgpDisabled and pgpRevoked + attributes, regardless of whether the key is disabled/revoked + or not. This is because a very common search is like + "(&(pgpUserID=*isabella*)(pgpDisabled=0))" */ + + if (is_pub) + { + modlist_add (modlist,"pgpDisabled", disabled ? "1" : "0"); + modlist_add (modlist,"pgpRevoked", revoked ? "1" : "0"); + } + } + + if (is_pub || is_sub) + { + char *size = fields[2]; + int val = atoi (size); + size = NULL; + + if (val > 0) + { + /* We zero pad this on the left to make PGP happy. */ + char padded[6]; + if (val < 99999 && val > 0) + { + sprintf (padded, "%05u", val); + size = padded; + } + } + + if (size) + { + if (is_pub || is_sub) + modlist_add (modlist, "pgpKeySize", size); + } + } + + if (is_pub) + { + char *algo = fields[3]; + int val = atoi (algo); + switch (val) + { + case 1: + algo = "RSA"; + break; + + case 17: + algo = "DSS/DH"; + break; + + default: + algo = NULL; + break; + } + + if (algo) + { + if (is_pub) + modlist_add (modlist, "pgpKeyType", algo); + } + } + + if (is_pub || is_sub || is_sig) + { + if (is_pub) + { + modlist_add (modlist, "pgpCertID", keyid); + modlist_add (modlist, "pgpKeyID", &keyid[8]); + } + + if (is_sub) + modlist_add (modlist, "pgpSubKeyID", keyid); + + if (is_sig) + modlist_add (modlist, "pgpSignerID", keyid); + } + + if (is_pub) + { + char *create_time = fields[5]; + + if (strlen (create_time) == 0) + create_time = NULL; + else + { + struct tm tm; + memset (&tm, 0, sizeof (tm)); + + if (! strptime (create_time, "%Y-%m-%d", &tm)) + { + /* Failed to parse string. */ + log_error ("Failed to parse creation time ('%s') as a date ('YYYY-MM-DD')", + create_time); + create_time = NULL; + } + else + create_time = tm2ldaptime (&tm); + } + + if (create_time) + { + modlist_add (modlist, "pgpKeyCreateTime", create_time); + xfree (create_time); + } + } + + if (is_pub) + { + char *expire_time = fields[6]; + + if (strlen (expire_time) == 0) + expire_time = NULL; + else + { + struct tm tm; + memset (&tm, 0, sizeof (tm)); + + if (! strptime (expire_time, "%Y-%m-%d", &tm)) + { + /* Failed to parse string. */ + log_error ("Failed to parse expiration time ('%s') as a date ('YYYY-MM-DD')", + expire_time); + expire_time = NULL; + } + else + expire_time = tm2ldaptime (&tm); + } + + if (expire_time) + { + modlist_add (modlist, "pgpKeyExpireTime", expire_time); + xfree (expire_time); + } + } + + if ((is_uid || is_pub) && field_count >= 10) + { + char *uid = fields[9]; + + uncescape (uid); + + modlist_add (modlist, "pgpUserID", uid); + } + + out: + free (fields); +} + +/* Send the key in {KEY,KEYLEN} with the metadata {INFO,INFOLEN} to + the keyserver identified by URI. See server.c:cmd_ks_put for the + format of the data and metadata. */ +gpg_error_t +ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri, + void *data, size_t datalen, + void *info, size_t infolen) +{ + gpg_error_t err = 0; + int ldap_err; + + LDAP *ldap_conn = NULL; + char *basedn = NULL; + char *pgpkeyattr = NULL; + int real_ldap; + + LDAPMod **modlist = NULL; + LDAPMod **addlist = NULL; + + char *data_armored = NULL; + + /* The last byte of the info block. */ + const char *infoend = info + infolen - 1; + + /* Elide a warning. */ + (void) ctrl; + + /* Make sure we are talking to an OpenPGP LDAP server. */ + ldap_err = ldap_connect (uri, &ldap_conn, &basedn, &pgpkeyattr, &real_ldap); + if (ldap_err || !basedn) + { + if (ldap_err) + err = ldap_err_to_gpg_err (ldap_err); + else + err = GPG_ERR_GENERAL; + goto out; + } + + ldap_err = ldap_simple_bind_s (ldap_conn, + "uid=user,ou=PGP Users,dc=huenfield,dc=org", + "foobar"); + if (ldap_err) + { + err = ldap_err_to_gpg_err (ldap_err); + goto out; + } + + if (! real_ldap) + /* We appear to have a OpenPGP Keyserver, which can unpack the key + on its own (not just a dumb LDAP server). */ + { + LDAPMod mod, *attrs[2]; + char *key[] = { data, NULL }; + char *dn; + + memset (&mod, 0, sizeof (mod)); + mod.mod_op = LDAP_MOD_ADD; + mod.mod_type = pgpkeyattr; + mod.mod_values = key; + attrs[0] = &mod; + attrs[1] = NULL; + + dn = xasprintf ("pgpCertid=virtual,%s", basedn); + ldap_err = ldap_add_s (ldap_conn, dn, attrs); + xfree (dn); + + if (ldap_err != LDAP_SUCCESS) + { + err = ldap_err_to_gpg_err (err); + goto out; + } + + goto out; + } + + modlist = xmalloc (sizeof (LDAPMod *)); + *modlist = NULL; + + /* Start by nulling out all attributes. We try and do a modify + operation first, so this ensures that we don't leave old + attributes lying around. */ + modlist_add (&modlist, "pgpDisabled", NULL); + modlist_add (&modlist, "pgpKeyID", NULL); + modlist_add (&modlist, "pgpKeyType", NULL); + modlist_add (&modlist, "pgpUserID", NULL); + modlist_add (&modlist, "pgpKeyCreateTime", NULL); + modlist_add (&modlist, "pgpSignerID", NULL); + modlist_add (&modlist, "pgpRevoked", NULL); + modlist_add (&modlist, "pgpSubKeyID", NULL); + modlist_add (&modlist, "pgpKeySize", NULL); + modlist_add (&modlist, "pgpKeyExpireTime", NULL); + modlist_add (&modlist, "pgpCertID", NULL); + + /* Assemble the INFO stuff into LDAP attributes */ + + while (infolen > 0) + { + char *temp = NULL; + + char *newline = memchr (info, '\n', infolen); + if (!newline) + /* The last line is not \n terminated! Make a copy so we can + add a NUL terminator. */ + { + temp = alloca (infolen + 1); + memcpy (temp, info, infolen); + info = temp; + newline = info + infolen; + } + + *newline = '\0'; + + extract_attributes (&modlist, info); + + infolen = infolen - ((uintptr_t) newline - (uintptr_t) info + 1); + info = newline + 1; + + /* Sanity check. */ + if (! temp) + assert (info + infolen - 1 == infoend); + else + assert (infolen == -1); + } + + modlist_add (&addlist, "objectClass", "pgpKeyInfo"); + + err = armor_data (&data_armored, data, datalen); + if (err) + goto out; + + modlist_add (&addlist, pgpkeyattr, data_armored); + + /* Now append addlist onto modlist. */ + modlists_join (&modlist, addlist); + +#if 0 + { + estream_t output = es_fopen("/tmp/modlist.txt", "w"); + estream_t input = modlist_dump (modlist, NULL); + copy_stream (input, output); + + es_fclose (input); + es_fclose (output); + } +#endif + + /* Going on the assumption that modify operations are more frequent + than adds, we try a modify first. If it's not there, we just + turn around and send an add command for the same key. Otherwise, + the modify brings the server copy into compliance with our copy. + Note that unlike the LDAP keyserver (and really, any other + keyserver) this does NOT merge signatures, but replaces the whole + key. This should make some people very happy. */ + { + char **certid; + char *dn; + + certid = modlist_lookup (modlist, "pgpCertID"); + if (/* We should have a value. */ + ! certid + /* Exactly one. */ + || !(certid[0] && !certid[1])) + { + log_error ("Bad certid.\n"); + err = GPG_ERR_GENERAL; + goto out; + } + + dn = xasprintf ("pgpCertID=%s,%s", certid[0], basedn); + + err = ldap_modify_s (ldap_conn, dn, modlist); + if (err == LDAP_NO_SUCH_OBJECT) + err = ldap_add_s (ldap_conn, dn, addlist); + + xfree (dn); + + if (err != LDAP_SUCCESS) + { + log_error ("gpgkeys: error adding key to keyserver: %s\n", + ldap_err2string (err)); + err = ldap_err_to_gpg_err (err); + } + } + + out: + if (ldap_conn) + ldap_unbind (ldap_conn); + + xfree (basedn); + xfree (pgpkeyattr); + + modlist_free (modlist); + xfree (addlist); + + xfree (data_armored); + + return err; +} diff --git a/dirmngr/ks-engine.h b/dirmngr/ks-engine.h index dc950cf..5bfe29b 100644 --- a/dirmngr/ks-engine.h +++ b/dirmngr/ks-engine.h @@ -1,5 +1,6 @@ /* ks-engine.h - Keyserver engines definitions * Copyright (C) 2011 Free Software Foundation, Inc. + * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -52,6 +53,15 @@ gpg_error_t ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp); gpg_error_t ks_kdns_help (ctrl_t ctrl, parsed_uri_t uri); gpg_error_t ks_kdns_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp); +/*-- ks-engine-ldap.c --*/ +gpg_error_t ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri); +gpg_error_t ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, + estream_t *r_fp); +gpg_error_t ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, + const char *keyspec, estream_t *r_fp); +gpg_error_t ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri, + void *data, size_t datalen, + void *info, size_t infolen); #endif /*DIRMNGR_KS_ENGINE_H*/ diff --git a/dirmngr/server.c b/dirmngr/server.c index 6094bc9..b5d1653 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -2,6 +2,7 @@ * Copyright (C) 2002 Klar?lvdalens Datakonsult AB * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011 g10 Code GmbH * Copyright (C) 2014 Werner Koch + * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -48,6 +49,7 @@ #endif #include "ks-action.h" #include "ks-engine.h" /* (ks_hkp_print_hosttable) */ +#include "ldap-parse-uri.h" /* To avoid DoS attacks we limit the size of a certificate to something reasonable. */ @@ -1524,7 +1526,10 @@ cmd_keyserver (assuan_context_t ctx, char *line) item->parsed_uri = NULL; strcpy (item->uri, line); - err = http_parse_uri (&item->parsed_uri, line, 1); + if (ldap_uri_p (item->uri)) + err = ldap_parse_uri (&item->parsed_uri, line); + else + err = http_parse_uri (&item->parsed_uri, line, 1); if (err) { xfree (item); @@ -1709,13 +1714,15 @@ static const char hlp_ks_put[] = "\n" " INQUIRE KEYBLOCK\n" "\n" - "The client shall respond with a binary version of the keyblock. For LDAP\n" + "The client shall respond with a binary version of the keyblock (e.g.,\n" + "the output of `gpg --export KEYID'). For LDAP\n" "keyservers Dirmngr may ask for meta information of the provided keyblock\n" "using:\n" "\n" " INQUIRE KEYBLOCK_INFO\n" "\n" - "The client shall respond with a colon delimited info lines"; + "The client shall respond with a colon delimited info lines (the output\n" + "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n"; static gpg_error_t cmd_ks_put (assuan_context_t ctx, char *line) { @@ -1755,7 +1762,7 @@ cmd_ks_put (assuan_context_t ctx, char *line) } /* Send the key. */ - err = ks_action_put (ctrl, value, valuelen); + err = ks_action_put (ctrl, value, valuelen, info, infolen); leave: xfree (info); ----------------------------------------------------------------------- Summary of changes: dirmngr/ks-engine-ldap.c | 200 ++++++++++++++++++++++++++--------------------- 1 file changed, 113 insertions(+), 87 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 20 13:22:47 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 20 Mar 2015 13:22:47 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-46-g5136e39 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 5136e39c6466de90697153ea253c4b540c1f7d1a (commit) from e7ddaad0fd2c8774a1d3367adfaa68014eaf65de (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 5136e39c6466de90697153ea253c4b540c1f7d1a Author: Werner Koch Date: Fri Mar 20 13:20:04 2015 +0100 common: Fix syntax error when building with gnutls * common/http.c (send_request): Add missing comma. -- This fixes commit dc10d46. Signed-off-by: Werner Koch diff --git a/common/http.c b/common/http.c index 12e3fcb..271257d 100644 --- a/common/http.c +++ b/common/http.c @@ -1453,7 +1453,7 @@ send_request (http_t hd, const char *httphost, const char *auth, # elif HTTP_USE_GNUTLS rc = gnutls_server_name_set (hd->session->tls_session, GNUTLS_NAME_DNS, - hd->session->servername + hd->session->servername, strlen (hd->session->servername)); if (rc < 0) log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc)); ----------------------------------------------------------------------- Summary of changes: common/http.c | 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 Fri Mar 20 15:48:01 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 20 Mar 2015 15:48:01 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-49-gbebab54 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 bebab54027d8c63574a2680c60481cfe9b88c240 (commit) via a0eb2e4e8cef9ca6a5dfbae6440fa6cd583d0805 (commit) via 783a4a98378fa1aa222d5cb7427dd37151feb08b (commit) from 5136e39c6466de90697153ea253c4b540c1f7d1a (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 bebab54027d8c63574a2680c60481cfe9b88c240 Author: Werner Koch Date: Fri Mar 20 15:43:32 2015 +0100 gpg: Consider a mailbox only userid in mail search mode. * kbx/keybox-search.c: Include mbox-util.h. (blob_cmp_mail): Improve OpenPGP uid parsing. -- GnuPG-bug-id: 1927 diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index b03874d..1433591 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -30,6 +30,7 @@ #include "keybox-defs.h" #include #include "host2net.h" +#include "mbox-util.h" #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) @@ -435,6 +436,7 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, for (idx=!!x509 ;idx < nuids; idx++) { size_t mypos = pos; + size_t mylen; mypos += idx*uidinfolen; off = get32 (buffer+mypos); @@ -454,20 +456,32 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, else /* OpenPGP. */ { /* We need to forward to the mailbox part. */ + mypos = off; + mylen = len; for ( ; len && buffer[off] != '<'; len--, off++) ; if (len < 2 || buffer[off] != '<') - continue; /* empty name or trailing 0 not stored */ - - off++; /* Point to first char of the mail address. */ - len--; + { + /* Mailbox not explicitly given or too short. Restore + OFF and LEN and check whether the entire string + resembles a mailbox without the angle brackets. */ + off = mypos; + len = mylen; + if (!is_valid_mailbox_mem (buffer+off, len)) + continue; /* Not a mail address. */ + } + else /* Seems to be standard user id with mail address. */ + { + off++; /* Point to first char of the mail address. */ + len--; + /* Search closing '>'. */ + for (mypos=off; len && buffer[mypos] != '>'; len--, mypos++) + ; + if (!len || buffer[mypos] != '>' || off == mypos) + continue; /* Not a proper mail address. */ + len = mypos - off; + } - /* Search closing '>'. */ - for (mypos=off; len && buffer[mypos] != '>'; len--, mypos++) - ; - if (!len || buffer[mypos] != '>' || off == mypos) - continue; /* Not a proper mail address. */ - len = mypos - off; } if (substr) commit a0eb2e4e8cef9ca6a5dfbae6440fa6cd583d0805 Author: Werner Koch Date: Fri Mar 20 15:39:49 2015 +0100 common: Add function is_valid_mailbox_mem. * common/mbox-util.c (mem_count_chr): New. (my_memstr): New. (has_invalid_email_chars): Change args to work on a buffer. (is_valid_mailbox_mem): New. (is_valid_mailbox): Rewrite to use is_valid_mailbox_mem. Signed-off-by: Werner Koch diff --git a/common/mbox-util.c b/common/mbox-util.c index 0885f0e..2029324 100644 --- a/common/mbox-util.c +++ b/common/mbox-util.c @@ -50,6 +50,47 @@ string_count_chr (const char *string, int c) return count; } +static int +mem_count_chr (const void *buffer, int c, size_t length) +{ + const char *s = buffer; + int count; + + for (count=0; length; length--, s++) + if (*s == c) + count++; + return count; +} + + +/* This is a case-sensitive version of our memistr. I wonder why no + standard function memstr exists but I better do not use the name + memstr to avoid future conflicts. */ +static const char * +my_memstr (const void *buffer, size_t buflen, const char *sub) +{ + const unsigned char *buf = buffer; + const unsigned char *t = (const unsigned char *)buf; + const unsigned char *s = (const unsigned char *)sub; + size_t n = buflen; + + for ( ; n ; t++, n-- ) + { + if (*t == *s) + { + for (buf = t++, buflen = n--, s++; n && *t ==*s; t++, s++, n--) + ; + if (!*s) + return (const char*)buf; + t = (const unsigned char *)buf; + s = (const unsigned char *)sub ; + n = buflen; + } + } + return NULL; +} + + static int string_has_ctrl_or_space (const char *string) @@ -74,52 +115,66 @@ has_dotdot_after_at (const char *string) } -/* Check whether the string has characters not valid in an RFC-822 - address. To cope with OpenPGP we ignore non-ascii characters - so that for example umlauts are legal in an email address. An - OpenPGP user ID must be utf-8 encoded but there is no strict - requirement for RFC-822. Thus to avoid IDNA encoding we put the - address verbatim as utf-8 into the user ID under the assumption - that mail programs handle IDNA at a lower level and take OpenPGP - user IDs as utf-8. Note that we can't do an utf-8 encoding - checking here because in keygen.c this function is called with the - native encoding and native to utf-8 encoding is only done later. */ +/* Check whether BUFFER has characters not valid in an RFC-822 + address. LENGTH gives the length of BUFFER. + + To cope with OpenPGP we ignore non-ascii characters so that for + example umlauts are legal in an email address. An OpenPGP user ID + must be utf-8 encoded but there is no strict requirement for + RFC-822. Thus to avoid IDNA encoding we put the address verbatim + as utf-8 into the user ID under the assumption that mail programs + handle IDNA at a lower level and take OpenPGP user IDs as utf-8. + Note that we can't do an utf-8 encoding checking here because in + keygen.c this function is called with the native encoding and + native to utf-8 encoding is only done later. */ int -has_invalid_email_chars (const char *s) +has_invalid_email_chars (const void *buffer, size_t length) { + const unsigned char *s = buffer; int at_seen=0; const char *valid_chars= "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - for ( ; *s; s++ ) + for ( ; length && *s; length--, s++ ) { - if ( (*s & 0x80) ) + if ((*s & 0x80)) continue; /* We only care about ASCII. */ - if ( *s == '@' ) + if (*s == '@') at_seen=1; - else if ( !at_seen && !(strchr (valid_chars, *s) - || strchr ("!#$%&'*+/=?^`{|}~", *s))) + else if (!at_seen && !(strchr (valid_chars, *s) + || strchr ("!#$%&'*+/=?^`{|}~", *s))) return 1; - else if ( at_seen && !strchr( valid_chars, *s ) ) + else if (at_seen && !strchr (valid_chars, *s)) return 1; } return 0; } +/* Same as is_valid_mailbox (see below) but operates on non-nul + terminated buffer. */ +int +is_valid_mailbox_mem (const void *name_arg, size_t namelen) +{ + const char *name = name_arg; + + return !( !name + || !namelen + || has_invalid_email_chars (name, namelen) + || mem_count_chr (name, '@', namelen) != 1 + || *name == '@' + || name[namelen-1] == '@' + || name[namelen-1] == '.' + || my_memstr (name, namelen, "..")); +} + + /* Check whether NAME represents a valid mailbox according to RFC822. Returns true if so. */ int is_valid_mailbox (const char *name) { - return !( !name - || !*name - || has_invalid_email_chars (name) - || string_count_chr (name,'@') != 1 - || *name == '@' - || name[strlen(name)-1] == '@' - || name[strlen(name)-1] == '.' - || strstr (name, "..") ); + return name? is_valid_mailbox_mem (name, strlen (name)) : 0; } diff --git a/common/mbox-util.h b/common/mbox-util.h index b9a3bda..4dd48ec 100644 --- a/common/mbox-util.h +++ b/common/mbox-util.h @@ -29,8 +29,9 @@ #ifndef GNUPG_COMMON_MBOX_UTIL_H #define GNUPG_COMMON_MBOX_UTIL_H -int has_invalid_email_chars (const char *s); +int has_invalid_email_chars (const void *buffer, size_t length); int is_valid_mailbox (const char *name); +int is_valid_mailbox_mem (const void *buffer, size_t length); char *mailbox_from_userid (const char *userid); int is_valid_user_id (const char *uid); commit 783a4a98378fa1aa222d5cb7427dd37151feb08b Author: Werner Koch Date: Fri Mar 20 13:29:20 2015 +0100 gpg: Find keys using mail addresses with garbage after the '>' * kbx/keybox-search.c (blob_cmp_mail): Stop comparing at the '>'. -- This change allows to find mail addresses like Joe Doe bar Joe Doe (comment) using the command gpg -k '' These UIDs are ill-formed according to gpg checks but nevertheless are seen in the wild. Note, that it does only work with the new keybox format. Signed-off-by: Werner Koch diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index d22ef19..b03874d 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -385,8 +385,8 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, /* Compare all email addresses of the subject. With SUBSTR given as - True a substring search is done in the mail address. If X509 - states whether thr search is done on an X.509 blob. */ + True a substring search is done in the mail address. The X509 flag + indicated whether the search is done on an X.509 blob. */ static int blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, int x509) @@ -440,27 +440,44 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, off = get32 (buffer+mypos); len = get32 (buffer+mypos+4); if (off+len > length) - return 0; /* error: better stop here out of bounds */ - if (!x509) + return 0; /* error: better stop here - out of bounds */ + if (x509) { - /* For OpenPGP we need to forward to the mailbox part. */ - for ( ;len && buffer[off] != '<'; len--, off++) + if (len < 2 || buffer[off] != '<') + continue; /* empty name or trailing 0 not stored */ + len--; /* one back */ + if ( len < 3 || buffer[off+len] != '>') + continue; /* not a proper email address */ + off++; + len--; + } + else /* OpenPGP. */ + { + /* We need to forward to the mailbox part. */ + for ( ; len && buffer[off] != '<'; len--, off++) ; + if (len < 2 || buffer[off] != '<') + continue; /* empty name or trailing 0 not stored */ + + off++; /* Point to first char of the mail address. */ + len--; + + /* Search closing '>'. */ + for (mypos=off; len && buffer[mypos] != '>'; len--, mypos++) + ; + if (!len || buffer[mypos] != '>' || off == mypos) + continue; /* Not a proper mail address. */ + len = mypos - off; } - if (len < 2 || buffer[off] != '<') - continue; /* empty name or trailing 0 not stored */ - len--; /* one back */ - if ( len < 3 || buffer[off+len] != '>') - continue; /* not a proper email address */ - len--; + if (substr) { - if (ascii_memcasemem (buffer+off+1, len, name, namelen)) + if (ascii_memcasemem (buffer+off, len, name, namelen)) return idx+1; /* found */ } else { - if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len)) + if (len == namelen && !ascii_memcasecmp (buffer+off, name, len)) return idx+1; /* found */ } } ----------------------------------------------------------------------- Summary of changes: common/mbox-util.c | 105 +++++++++++++++++++++++++++++++++++++++------------- common/mbox-util.h | 3 +- kbx/keybox-search.c | 59 ++++++++++++++++++++++------- 3 files changed, 127 insertions(+), 40 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Mar 21 12:06:57 2015 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sat, 21 Mar 2015 12:06:57 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-181-ga06fbc0 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 a06fbc0d1e98eb1218eff55ad2f37d471e4f33b2 (commit) via 92fa5f16d69707e302c0f85b2e5e80af8dc037f1 (commit) via aa234561d00c3fb15fe501df4bf58f3db7c7c06b (commit) from f5832285b0e420d77be1b8da10a1e1d86583b414 (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 a06fbc0d1e98eb1218eff55ad2f37d471e4f33b2 Author: Jussi Kivilinna Date: Sat Mar 21 13:01:38 2015 +0200 wipememory: use one-byte aligned type for unaligned memory accesses * src/g10lib.h (fast_wipememory2_unaligned_head): Enable unaligned access only when HAVE_GCC_ATTRIBUTE_PACKED and HAVE_GCC_ATTRIBUTE_ALIGNED defined. (fast_wipememory_t): New. (fast_wipememory2): Use 'fast_wipememory_t'. -- Signed-off-by: Jussi Kivilinna diff --git a/src/g10lib.h b/src/g10lib.h index 238871d..50a08ec 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -323,16 +323,26 @@ void __gcry_burn_stack (unsigned int bytes); #endif /* Following architectures can handle unaligned accesses fast. */ -#if defined(__i386__) || defined(__x86_64__) || \ - defined(__powerpc__) || defined(__powerpc64__) || \ - (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ - defined(__aarch64__) +#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \ + defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \ + (defined(__i386__) || defined(__x86_64__) || \ + defined(__powerpc__) || defined(__powerpc64__) || \ + (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ + defined(__aarch64__)) #define fast_wipememory2_unaligned_head(_ptr,_set,_len) /*do nothing*/ +typedef struct fast_wipememory_s +{ + FASTWIPE_T a; +} __attribute__((packed, aligned(1))) fast_wipememory_t; #else #define fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do { \ while((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1) && _vlen) \ { *_vptr=(_vset); _vptr++; _vlen--; } \ } while(0) +typedef struct fast_wipememory_s +{ + FASTWIPE_T a; +} fast_wipememory_t; #endif /* fast_wipememory2 may leave tail bytes unhandled, in which case tail bytes @@ -344,8 +354,9 @@ void __gcry_burn_stack (unsigned int bytes); break; \ _vset_long *= FASTWIPE_MULT; \ do { \ - volatile FASTWIPE_T *_vptr_long = (volatile void *)_vptr; \ - *_vptr_long = _vset_long; \ + volatile fast_wipememory_t *_vptr_long = \ + (volatile void *)_vptr; \ + _vptr_long->a = _vset_long; \ _vlen -= sizeof(FASTWIPE_T); \ _vptr += sizeof(FASTWIPE_T); \ } while (_vlen >= sizeof(FASTWIPE_T)); \ commit 92fa5f16d69707e302c0f85b2e5e80af8dc037f1 Author: Jussi Kivilinna Date: Sat Mar 21 13:01:38 2015 +0200 bufhelp: use one-byte aligned type for unaligned memory accesses * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Enable only when HAVE_GCC_ATTRIBUTE_PACKED and HAVE_GCC_ATTRIBUTE_ALIGNED are defined. (bufhelp_int_t): New type. (buf_cpy, buf_xor, buf_xor_1, buf_xor_2dst, buf_xor_n_copy_2): Use 'bufhelp_int_t'. [BUFHELP_FAST_UNALIGNED_ACCESS] (bufhelp_u32_t, bufhelp_u64_t): New. [BUFHELP_FAST_UNALIGNED_ACCESS] (buf_get_be32, buf_get_le32) (buf_put_be32, buf_put_le32, buf_get_be64, buf_get_le64) (buf_put_be64, buf_put_le64): Use 'bufhelp_uXX_t'. * configure.ac (gcry_cv_gcc_attribute_packed): New. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index c6bedc5..fb87939 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -23,10 +23,13 @@ #include "bithelp.h" -#if defined(__i386__) || defined(__x86_64__) || \ - defined(__powerpc__) || defined(__powerpc64__) || \ - (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ - defined(__aarch64__) +#undef BUFHELP_FAST_UNALIGNED_ACCESS +#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \ + defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \ + (defined(__i386__) || defined(__x86_64__) || \ + defined(__powerpc__) || defined(__powerpc64__) || \ + (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ + defined(__aarch64__)) /* These architectures are able of unaligned memory accesses and can handle those fast. */ @@ -34,6 +37,25 @@ #endif +#ifdef BUFHELP_FAST_UNALIGNED_ACCESS +/* Define type with one-byte alignment on architectures with fast unaligned + memory accesses. + */ +typedef struct bufhelp_int_s +{ + uintptr_t a; +} __attribute__((packed, aligned(1))) bufhelp_int_t; +#else +/* Define type with default alignment for other architectures (unaligned + accessed handled in per byte loops). + */ +typedef struct bufhelp_int_s +{ + uintptr_t a; +} bufhelp_int_t; +#endif + + /* Optimized function for small buffer copying */ static inline void buf_cpy(void *_dst, const void *_src, size_t len) @@ -44,21 +66,21 @@ buf_cpy(void *_dst, const void *_src, size_t len) #else byte *dst = _dst; const byte *src = _src; - uintptr_t *ldst; - const uintptr_t *lsrc; + bufhelp_int_t *ldst; + const bufhelp_int_t *lsrc; #ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(uintptr_t) - 1; + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ if (((uintptr_t)dst | (uintptr_t)src) & longmask) goto do_bytes; #endif - ldst = (uintptr_t *)(void *)dst; - lsrc = (const uintptr_t *)(const void *)src; + ldst = (bufhelp_int_t *)(void *)dst; + lsrc = (const bufhelp_int_t *)(const void *)src; - for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) - *ldst++ = *lsrc++; + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst++)->a = (lsrc++)->a; dst = (byte *)ldst; src = (const byte *)lsrc; @@ -80,22 +102,22 @@ buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len) byte *dst = _dst; const byte *src1 = _src1; const byte *src2 = _src2; - uintptr_t *ldst; - const uintptr_t *lsrc1, *lsrc2; + bufhelp_int_t *ldst; + const bufhelp_int_t *lsrc1, *lsrc2; #ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(uintptr_t) - 1; + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask) goto do_bytes; #endif - ldst = (uintptr_t *)(void *)dst; - lsrc1 = (const uintptr_t *)(const void *)src1; - lsrc2 = (const uintptr_t *)(const void *)src2; + ldst = (bufhelp_int_t *)(void *)dst; + lsrc1 = (const bufhelp_int_t *)(const void *)src1; + lsrc2 = (const bufhelp_int_t *)(const void *)src2; - for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) - *ldst++ = *lsrc1++ ^ *lsrc2++; + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst++)->a = (lsrc1++)->a ^ (lsrc2++)->a; dst = (byte *)ldst; src1 = (const byte *)lsrc1; @@ -116,21 +138,21 @@ buf_xor_1(void *_dst, const void *_src, size_t len) { byte *dst = _dst; const byte *src = _src; - uintptr_t *ldst; - const uintptr_t *lsrc; + bufhelp_int_t *ldst; + const bufhelp_int_t *lsrc; #ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(uintptr_t) - 1; + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ if (((uintptr_t)dst | (uintptr_t)src) & longmask) goto do_bytes; #endif - ldst = (uintptr_t *)(void *)dst; - lsrc = (const uintptr_t *)(const void *)src; + ldst = (bufhelp_int_t *)(void *)dst; + lsrc = (const bufhelp_int_t *)(const void *)src; - for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) - *ldst++ ^= *lsrc++; + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst++)->a ^= (lsrc++)->a; dst = (byte *)ldst; src = (const byte *)lsrc; @@ -152,22 +174,22 @@ buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len) byte *dst1 = _dst1; byte *dst2 = _dst2; const byte *src = _src; - uintptr_t *ldst1, *ldst2; - const uintptr_t *lsrc; + bufhelp_int_t *ldst1, *ldst2; + const bufhelp_int_t *lsrc; #ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(uintptr_t) - 1; + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask) goto do_bytes; #endif - ldst1 = (uintptr_t *)(void *)dst1; - ldst2 = (uintptr_t *)(void *)dst2; - lsrc = (const uintptr_t *)(const void *)src; + ldst1 = (bufhelp_int_t *)(void *)dst1; + ldst2 = (bufhelp_int_t *)(void *)dst2; + lsrc = (const bufhelp_int_t *)(const void *)src; - for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) - *ldst1++ = (*ldst2++ ^= *lsrc++); + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst1++)->a = ((ldst2++)->a ^= (lsrc++)->a); dst1 = (byte *)ldst1; dst2 = (byte *)ldst2; @@ -193,11 +215,11 @@ buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy, const byte *src_xor = _src_xor; const byte *src_cpy = _src_cpy; byte temp; - uintptr_t *ldst_xor, *lsrcdst_cpy; - const uintptr_t *lsrc_cpy, *lsrc_xor; + bufhelp_int_t *ldst_xor, *lsrcdst_cpy; + const bufhelp_int_t *lsrc_cpy, *lsrc_xor; uintptr_t ltemp; #ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(uintptr_t) - 1; + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; /* Skip fast processing if buffers are unaligned. */ if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor | @@ -205,16 +227,16 @@ buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy, goto do_bytes; #endif - ldst_xor = (uintptr_t *)(void *)dst_xor; - lsrc_xor = (const uintptr_t *)(void *)src_xor; - lsrcdst_cpy = (uintptr_t *)(void *)srcdst_cpy; - lsrc_cpy = (const uintptr_t *)(const void *)src_cpy; + ldst_xor = (bufhelp_int_t *)(void *)dst_xor; + lsrc_xor = (const bufhelp_int_t *)(void *)src_xor; + lsrcdst_cpy = (bufhelp_int_t *)(void *)srcdst_cpy; + lsrc_cpy = (const bufhelp_int_t *)(const void *)src_cpy; - for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) { - ltemp = *lsrc_cpy++; - *ldst_xor++ = *lsrcdst_cpy ^ *lsrc_xor++; - *lsrcdst_cpy++ = ltemp; + ltemp = (lsrc_cpy++)->a; + (ldst_xor++)->a = (lsrcdst_cpy)->a ^ (lsrc_xor++)->a; + (lsrcdst_cpy++)->a = ltemp; } dst_xor = (byte *)ldst_xor; @@ -347,53 +369,64 @@ static inline void buf_put_le64(void *_buf, u64 val) #else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ +typedef struct bufhelp_u32_s +{ + u32 a; +} __attribute__((packed, aligned(1))) bufhelp_u32_t; + /* Functions for loading and storing unaligned u32 values of different endianness. */ static inline u32 buf_get_be32(const void *_buf) { - return be_bswap32(*(const u32 *)_buf); + return be_bswap32(((const bufhelp_u32_t *)_buf)->a); } static inline u32 buf_get_le32(const void *_buf) { - return le_bswap32(*(const u32 *)_buf); + return le_bswap32(((const bufhelp_u32_t *)_buf)->a); } static inline void buf_put_be32(void *_buf, u32 val) { - u32 *out = _buf; - *out = be_bswap32(val); + bufhelp_u32_t *out = _buf; + out->a = be_bswap32(val); } static inline void buf_put_le32(void *_buf, u32 val) { - u32 *out = _buf; - *out = le_bswap32(val); + bufhelp_u32_t *out = _buf; + out->a = le_bswap32(val); } #ifdef HAVE_U64_TYPEDEF + +typedef struct bufhelp_u64_s +{ + u64 a; +} __attribute__((packed, aligned(1))) bufhelp_u64_t; + /* Functions for loading and storing unaligned u64 values of different endianness. */ static inline u64 buf_get_be64(const void *_buf) { - return be_bswap64(*(const u64 *)_buf); + return be_bswap64(((const bufhelp_u64_t *)_buf)->a); } static inline u64 buf_get_le64(const void *_buf) { - return le_bswap64(*(const u64 *)_buf); + return le_bswap64(((const bufhelp_u64_t *)_buf)->a); } static inline void buf_put_be64(void *_buf, u64 val) { - u64 *out = _buf; - *out = be_bswap64(val); + bufhelp_u64_t *out = _buf; + out->a = be_bswap64(val); } static inline void buf_put_le64(void *_buf, u64 val) { - u64 *out = _buf; - *out = le_bswap64(val); + bufhelp_u64_t *out = _buf; + out->a = le_bswap64(val); } #endif /*HAVE_U64_TYPEDEF*/ diff --git a/configure.ac b/configure.ac index 4bbd686..16f6a21 100644 --- a/configure.ac +++ b/configure.ac @@ -958,6 +958,24 @@ fi # +# Check whether the compiler supports the GCC style packed attribute +# +AC_CACHE_CHECK([whether the GCC style packed attribute is supported], + [gcry_cv_gcc_attribute_packed], + [gcry_cv_gcc_attribute_packed=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [[struct foo_s { char a; long b; } __attribute__ ((packed)); + enum bar { + FOO = 1 / (sizeof(struct foo_s) == (sizeof(char) + sizeof(long))), + };]])], + [gcry_cv_gcc_attribute_packed=yes])]) +if test "$gcry_cv_gcc_attribute_packed" = "yes" ; then + AC_DEFINE(HAVE_GCC_ATTRIBUTE_PACKED,1, + [Defined if a GCC style "__attribute__ ((packed))" is supported]) +fi + + +# # Check whether the compiler supports 'asm' or '__asm__' keyword for # assembler blocks. # commit aa234561d00c3fb15fe501df4bf58f3db7c7c06b Author: Jussi Kivilinna Date: Sat Mar 21 13:01:38 2015 +0200 tests/bench-slope: fix memory-leak and use-after-free bugs * tests/bench-slope.c (do_slope_benchmark): Free 'measurements' at end. (bench_mac_init): Move 'key' free at end of function. -- Signed-off-by: Jussi Kivilinna diff --git a/tests/bench-slope.c b/tests/bench-slope.c index c309b7e..394d7fc 100644 --- a/tests/bench-slope.c +++ b/tests/bench-slope.c @@ -442,6 +442,7 @@ do_slope_benchmark (struct bench_obj *obj) &overhead); free (measurement_raw); + free (measurements); free (real_buffer); obj->ops->finalize (obj); @@ -1450,11 +1451,11 @@ bench_mac_init (struct bench_obj *obj) } err = gcry_mac_setkey (hd, key, keylen); - free (key); if (err) { fprintf (stderr, PGM ": error setting key for mac `%s'\n", gcry_mac_algo_name (mode->algo)); + free (key); exit (1); } @@ -1473,6 +1474,7 @@ bench_mac_init (struct bench_obj *obj) obj->priv = hd; + free (key); return 0; } ----------------------------------------------------------------------- Summary of changes: cipher/bufhelp.h | 147 ++++++++++++++++++++++++++++++++-------------------- configure.ac | 18 +++++++ src/g10lib.h | 23 +++++--- tests/bench-slope.c | 4 +- 4 files changed, 128 insertions(+), 64 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 23 19:59:11 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Mon, 23 Mar 2015 19:59:11 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-61-g318329c 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 318329c3966906b239419d172a7ac6f41d60162a (commit) via 7a56b6b3aa8b7a07bd80a3fcd5114bd1af359fa3 (commit) via 096f4186c8cba7435105b4731b63aab953eb3ac7 (commit) via 00a16cf49336ee0b4ce21eb05a79db955af053e0 (commit) via 51341badb623927f2a358588c725a356fc77dbe7 (commit) via 81e83060856f02f6cfc7b48f8032e0cf14fc6c68 (commit) via 9e79a15f74c428624b0049a3f6a077c1bc7c731d (commit) via 63552852bf191985b4b55aa524bc397c5b1d1515 (commit) via 1a75b7c39f0a84f518711438565645a34fb2673f (commit) via e23b3ba5ffd3134a72da176a039e4d6c4f3ff595 (commit) via 79907ad256f5b84f36cbebdc92e5a05d9e266557 (commit) via b18ffcb81a3839dbf09603d70ebb8b80f65892d3 (commit) from bebab54027d8c63574a2680c60481cfe9b88c240 (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: common/gettime.c | 102 ++ common/gettime.h | 1 + common/http.c | 22 +- common/http.h | 3 + common/stringhelp.c | 90 +- common/stringhelp.h | 3 +- common/strlist.c | 14 + common/strlist.h | 3 + common/t-stringhelp.c | 58 + common/userids.c | 2 +- configure.ac | 2 +- dirmngr/Makefile.am | 21 +- dirmngr/certcache.c | 4 +- dirmngr/dirmngr.c | 6 +- dirmngr/ks-action.c | 77 +- dirmngr/ks-action.h | 4 +- dirmngr/ks-engine-hkp.c | 63 +- dirmngr/ks-engine-ldap.c | 2055 ++++++++++++++++++++++++++ dirmngr/ks-engine.h | 10 + dirmngr/ldap-parse-uri.c | 240 +++ common/isascii.c => dirmngr/ldap-parse-uri.h | 25 +- dirmngr/ldap-wrapper.c | 2 +- dirmngr/ldap.c | 2 +- dirmngr/ldapserver.c | 2 +- dirmngr/misc.c | 77 +- dirmngr/misc.h | 6 + dirmngr/server.c | 23 +- dirmngr/t-ldap-parse-uri.c | 255 ++++ common/xmalloc.h => dirmngr/t-support.h | 21 +- doc/DETAILS | 2 +- g10/call-dirmngr.c | 204 ++- tools/watchgnupg.c | 2 +- 32 files changed, 3205 insertions(+), 196 deletions(-) create mode 100644 dirmngr/ks-engine-ldap.c create mode 100644 dirmngr/ldap-parse-uri.c copy common/isascii.c => dirmngr/ldap-parse-uri.h (65%) create mode 100644 dirmngr/t-ldap-parse-uri.c copy common/xmalloc.h => dirmngr/t-support.h (66%) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 24 09:29:51 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 24 Mar 2015 09:29:51 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-62-g898c5c4 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 898c5c4836e3771d70df4da56c01deda139e6ddb (commit) from 318329c3966906b239419d172a7ac6f41d60162a (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 898c5c4836e3771d70df4da56c01deda139e6ddb Author: Werner Koch Date: Tue Mar 24 09:22:24 2015 +0100 doc: Mention that --use-standard-socket-p always returns true. -- diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 84a7d60..3e77909 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -295,7 +295,7 @@ debugger. @item --debug-quick-random @opindex debug-quick-random -This option inhibits the use the very secure random quality level +This option inhibits the use of the very secure random quality level (Libgcrypt?s @code{GCRY_VERY_STRONG_RANDOM}) and degrades all request down to standard random quality. It is only used for testing and shall not be used for any production quality keys. This option is @@ -485,11 +485,14 @@ debugging purposes. @item --use-standard-socket @itemx --no-use-standard-socket + at itemx --use-standard-socket-p @opindex use-standard-socket @opindex no-use-standard-socket + at opindex use-standard-socket-p @ifset gpgtwoone Since GnuPG 2.1 the standard socket is always used. These options -have no more effect. +have no more effect. The command @code{gpg-agent +--use-standard-socket-p} will thus always return success. @end ifset @ifclear gpgtwoone By enabling this option @command{gpg-agent} will listen on the socket ----------------------------------------------------------------------- Summary of changes: doc/gpg-agent.texi | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 24 09:51:49 2015 From: cvs at cvs.gnupg.org (by Petr PísaÅ™) Date: Tue, 24 Mar 2015 09:51:49 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.18-10-g60bd5fa 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 60bd5fa1d2f2911713f679f80601285dc7c372a0 (commit) via c01c8f0c4f55d76b037c7f6aa44ad25ede18d38a (commit) from 528ee704f8f9d881ba370dcbfa9194d6704f9a2f (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 60bd5fa1d2f2911713f679f80601285dc7c372a0 Author: Petr P?sa? Date: Mon Mar 16 13:39:56 2015 -0400 po: Update Czech translation -- Forwarded: http://lists.gnupg.org/pipermail/ \ gnupg-i18n/2014-November/000348.html diff --git a/po/cs.po b/po/cs.po index 4a62316..dc78d6a 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1,7 +1,7 @@ # Czech translation of libgpg-error. # Copyright (C) 2009 Free Software Foundation, Inc. # This file is distributed under the same license as the libgpg-error package. -# Petr Pisar , 2009, 2012. +# Petr Pisar , 2009, 2012, 2014. # # certificate chain ? ?et?zec (posloupnost) certifik?t? # keybox ? schr?nka (na kl??e) @@ -12,9 +12,9 @@ # msgid "" msgstr "" -"Project-Id-Version: libgpg-error 1.10\n" +"Project-Id-Version: libgpg-error 1.18\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2013-02-23 20:08+0100\n" +"PO-Revision-Date: 2014-11-27 19:31+0100\n" "Last-Translator: Petr Pisar \n" "Language-Team: Czech \n" "Language: cs\n" @@ -72,7 +72,7 @@ msgid "Assuan" msgstr "Assuan" msgid "TLS" -msgstr "" +msgstr "TLS" msgid "Any source" msgstr "Nespecifikovan? zdroj" @@ -327,10 +327,8 @@ msgstr "Neplatn? odpov??" msgid "No agent running" msgstr "Agent neb???" -#, fuzzy -#| msgid "agent error" msgid "Agent error" -msgstr "chyba agenta" +msgstr "Chyba agenta" msgid "Invalid data" msgstr "Neplatn? data" @@ -663,48 +661,32 @@ msgstr "Neplatn? eliptick? k?ivka" msgid "Unknown elliptic curve" msgstr "Nezn?m? eliptick? k?ivka" -#, fuzzy -#| msgid "Duplicated value" msgid "Duplicated key" -msgstr "Zdvojen? hodnota" +msgstr "Zdvojen? kl??" -#, fuzzy -#| msgid "Ambiguous name" msgid "Ambiguous result" -msgstr "Nejednozna?n? jm?no" +msgstr "Nejednozna?n? v?sledek" -#, fuzzy -#| msgid "No crypto engine" msgid "No crypto context" -msgstr "Chyb? kryptografick? jednotka" +msgstr "Chyb? kryptografick? kontext" -#, fuzzy -#| msgid "No crypto engine" msgid "Wrong crypto context" -msgstr "Chyb? kryptografick? jednotka" +msgstr "Chybn? kryptografick? kontext" -#, fuzzy -#| msgid "Invalid crypto engine" msgid "Bad crypto context" -msgstr "Neplatn? kryptografick? jednotka" +msgstr "?patn? kryptografick? kontext" msgid "Conflict in the crypto context" -msgstr "" +msgstr "Rozpor v?kryptografick?m kontextu" -#, fuzzy -#| msgid "No public key" msgid "Broken public key" -msgstr "??dn? ve?ejn? kl??" +msgstr "Rozbit? ve?ejn? kl??" -#, fuzzy -#| msgid "No secret key" msgid "Broken secret key" -msgstr "??dn? tajn? kl??" +msgstr "Rozbit? tajn? kl??" -#, fuzzy -#| msgid "Invalid digest algorithm" msgid "Invalid MAC algorithm" -msgstr "Neplatn? hashovac? algoritmus" +msgstr "Neplatn? algoritmus MAC" msgid "Operation fully cancelled" msgstr "Operace zcela zru?ena" @@ -770,116 +752,90 @@ msgstr "P??li? dlouh? ??dek" msgid "Object is in termination state" msgstr "" -#, fuzzy -#| msgid "Bad certificate chain" msgid "No certificate chain" -msgstr "Chybn? ?et?zec certifik?t?" +msgstr "Chyb? ?et?zec certifik?t?" -#, fuzzy -#| msgid "Certificate too young" msgid "Certificate is too large" -msgstr "Certifik?t je p??li? mlad?" +msgstr "Certifik?t je p??li? velk?" -#, fuzzy -#| msgid "Invalid card" msgid "Invalid record" -msgstr "Neplatn? karta" +msgstr "Neplatn? z?znam" msgid "The MAC does not verify" -msgstr "" +msgstr "Ov??en? MAC selhalo" -#, fuzzy -#| msgid "Unexpected tag" msgid "Unexpected message" -msgstr "Neo?ek?van? zna?ka" +msgstr "Neo?ek?van? zpr?va" msgid "Compression or decompression failed" -msgstr "" +msgstr "Komprese nebo dekomprese selhala" msgid "A counter would wrap" -msgstr "" +msgstr "Po??tadlo by p?eteklo" msgid "Fatal alert message received" -msgstr "" +msgstr "P?ijata nep?ekonateln? chybov? zpr?va" -#, fuzzy -#| msgid "Invalid cipher algorithm" msgid "No cipher algorithm" -msgstr "Neplatn? ?ifrovac? algoritmus" +msgstr "??dn? ?ifrovac? algoritmus" -#, fuzzy -#| msgid "Missing issuer certificate" msgid "Missing client certificate" -msgstr "Chyb? certifik?t vydavatele" +msgstr "Chyb? certifik?t klienta" -#, fuzzy -#| msgid "Certificate revoked" msgid "Close notification received" -msgstr "Certifik?t odvol?n" +msgstr "P?ijato ozn?men? o?uzav?en?" -#, fuzzy -#| msgid "Key expired" msgid "Ticket expired" -msgstr "Kl??i vypr?ela platnost" +msgstr "L?stku vypr?ela platnost" -#, fuzzy -#| msgid "Bad public key" msgid "Bad ticket" -msgstr "Chybn? ve?ejn? kl??" +msgstr "Chybn? l?stek" -#, fuzzy -#| msgid "Unknown packet" msgid "Unknown identity" -msgstr "Nezn?m? packet" +msgstr "Nezn?m? toto?nost" -#, fuzzy -#| msgid "Bad certificate chain" msgid "Bad certificate message in handshake" -msgstr "Chybn? ?et?zec certifik?t?" +msgstr "Chybn? zpr?va s?certifik?tem v?zah?jen?" msgid "Bad certificate request message in handshake" -msgstr "" +msgstr "Chybn? zpr?va s?po?adavkem na certifik?t v?zah?jen?" msgid "Bad certificate verify message in handshake" -msgstr "" +msgstr "Chybn? zpr?va o?ov??en? certifik?tu v?zah?jen?" msgid "Bad change cipher messsage in handshake" -msgstr "" +msgstr "Chybn? zpr?va se zm?nou ?ifry v?zah?jen?" msgid "Bad client hello message in handshake" -msgstr "" +msgstr "Chybn? zpr?va s?pozdravem klienta v?zah?jen?" msgid "Bad server hello message in handshake" -msgstr "" +msgstr "Chybn? zpr?va s?pozdravem serveru v?zah?jen?" msgid "Bad server hello done message in hanshake" -msgstr "" +msgstr "Chybn? zpr?va o?dokon?en? pozdravu serveru v?zah?jen?" msgid "Bad finished message in handshake" -msgstr "" +msgstr "Chybn? zpr?va o?dokon?en? v?zah?jen?" msgid "Bad server key exchange message in handshake" -msgstr "" +msgstr "Chybn? zpr?va o?v?m?n? kl??e serveru v?zah?jen?" msgid "Bad client key exchange message in handshake" -msgstr "" +msgstr "Chybn? zpr?va o?v?m?n? kl??e klienta v?zah?jen?" msgid "Bogus string" -msgstr "" +msgstr "Chybn? ?et?zec" msgid "Forbidden" msgstr "" -#, fuzzy -#| msgid "Key expired" msgid "Key disabled" -msgstr "Kl??i vypr?ela platnost" +msgstr "Kl?? zak?z?n" msgid "Not possible with a card based key" -msgstr "" +msgstr "Nelze prov?st s?kl??em na kart?" -#, fuzzy -#| msgid "Invalid object" msgid "Invalid lock object" msgstr "Neplatn? objekt" commit c01c8f0c4f55d76b037c7f6aa44ad25ede18d38a Author: Daniel Kahn Gillmor Date: Mon Mar 16 13:40:12 2015 -0400 Avoid breakage with gcc 5 * src/Makefile.am: Add -P to the C preprocessor when building mkerrcodes.h, to avoid a noisy intermediate pipeline. -- With gcc 5 without this patch, we see many errors like the following: gcc -I. -I. -o mkerrcodes ./mkerrcodes.c In file included from ./mkerrcodes.c:26:0: ./mkerrcodes.h:9:5: error: expected expression before ?,? token { , "GPG_ERR_E2BIG" }, ^ ./mkerrcodes.h:10:5: error: expected expression before ?,? token { , "GPG_ERR_EACCES" }, ^ This patch cleans up the generated mkerrcodes.h by making the intermediate stage clean for all the versions of gcc i tested (4.x and 5). Debian-Bug-Id: 777374 Signed-Off-By: Daniel Kahn Gillmor diff --git a/src/Makefile.am b/src/Makefile.am index 99c2c53..f847a80 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -213,7 +213,7 @@ code-to-errno.h: Makefile mkerrnos.awk errnos.in # It is correct to use $(CPP). We want the host's idea of the error codes. mkerrcodes.h: Makefile mkerrcodes.awk $(gpg_extra_headers) $(AWK) -f $(srcdir)/mkerrcodes1.awk $(srcdir)/errnos.in >_$@ - $(CPP) $(CPPFLAGS) $(extra_cppflags) _$@ | grep GPG_ERR_ | \ + $(CPP) $(CPPFLAGS) $(extra_cppflags) -P _$@ | grep GPG_ERR_ | \ $(AWK) -f $(srcdir)/mkerrcodes.awk >$@ -rm _$@ ----------------------------------------------------------------------- Summary of changes: po/cs.po | 126 ++++++++++++++++++-------------------------------------- src/Makefile.am | 2 +- 2 files changed, 42 insertions(+), 86 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 24 11:25:16 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 24 Mar 2015 11:25:16 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.18-11-g56feff5 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 56feff58d4fab92701ae77a1004af820b85e7f6c (commit) from 60bd5fa1d2f2911713f679f80601285dc7c372a0 (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 56feff58d4fab92701ae77a1004af820b85e7f6c Author: Werner Koch Date: Tue Mar 24 11:23:35 2015 +0100 Use assert to print diagnosicts before calling abort. * src/posix-lock.c: Add assert calls. Signed-off-by: Werner Koch diff --git a/src/posix-lock.c b/src/posix-lock.c index 7f20347..89be944 100644 --- a/src/posix-lock.c +++ b/src/posix-lock.c @@ -33,6 +33,7 @@ #include #include #include +#include #if USE_POSIX_THREADS # include @@ -88,7 +89,10 @@ use_pthread_p (void) /* Thread creation works. */ void *retval; if (pthread_join (thread, &retval) != 0) - abort (); + { + assert (!"pthread_join"); + abort (); + } result = 1; } tested = 1; @@ -106,9 +110,15 @@ get_lock_object (gpgrt_lock_t *lockhd) _gpgrt_lock_t *lock = (_gpgrt_lock_t*)lockhd; if (lock->vers != LOCK_ABI_VERSION) - abort (); + { + assert (!"lock ABI version"); + abort (); + } if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t)) - abort (); + { + assert (!"sizeof lock obj"); + abort (); + } return lock; } @@ -126,7 +136,10 @@ _gpgrt_lock_init (gpgrt_lock_t *lockhd) if (!lock->vers) { if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t)) - abort (); + { + assert (!"sizeof lock obj"); + abort (); + } lock->vers = LOCK_ABI_VERSION; } else /* Run the usual check. */ ----------------------------------------------------------------------- Summary of changes: src/posix-lock.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 24 11:38:31 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 24 Mar 2015 11:38:31 +0100 Subject: [git] gnupg-doc - branch, master, updated. 813ad5c401e1d2effca419f9687545920bc1ff5c 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 813ad5c401e1d2effca419f9687545920bc1ff5c (commit) from 570e1bc920b08f25fec300d1eaee5de11a6e21d1 (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 813ad5c401e1d2effca419f9687545920bc1ff5c Author: Werner Koch Date: Tue Mar 24 11:37:07 2015 +0100 Update an URL, add release info for pinentry. diff --git a/misc/id/eddsa-for-openpgp/back.mkd b/misc/id/eddsa-for-openpgp/back.mkd index 420f564..988b8f6 100644 --- a/misc/id/eddsa-for-openpgp/back.mkd +++ b/misc/id/eddsa-for-openpgp/back.mkd @@ -49,8 +49,7 @@ Which is fed into the EdDSA signature function and yields this signature: s: d09c4fa11527f038e0f57f2201d82f2ea2c9033265fa6ceb489e854bae61b404 -Note the MPI encoding rules require that the value of S needs to be -prefixed with a 0x00 octet. The entire signature packet is thus: +The entire signature packet is thus: 88 5e 04 00 16 08 00 06 05 02 55 f9 5f 95 00 0a 09 10 8c fd e1 21 97 96 5a 9a f6 22 01 00 56 f9 @@ -58,3 +57,22 @@ prefixed with a 0x00 octet. The entire signature packet is thus: 7e d8 2b f4 dd e5 60 6e 0d 75 6a ed 33 66 01 00 d0 9c 4f a1 15 27 f0 38 e0 f5 7f 22 01 d8 2f 2e a2 c9 03 32 65 fa 6c eb 48 9e 85 4b ae 61 b4 04 + +# Point compression flag bytes + +This specification introduces the new flag byte 0x40 to indicate the +point compression format. The value has been chosen so that the high +bit is not cleared and thus to avoid accidental sign extension. Two +other values might also be interesting for other ECC specifications: + + Flag Description + ---- ----------- + 0x04 Standard flag for uncompression format + 0x40 Native point format of the curve follows + 0x41 Only X coordinate follows. + 0x42 Only Y coordinate follows. + +# Changes since -02 + + - Fixed decription in the test vectors regarding an extra 0x00 byte. + - Small gramar fixes. diff --git a/web/related_software/swlist.org b/web/related_software/swlist.org index 1961714..65a9c9d 100644 --- a/web/related_software/swlist.org +++ b/web/related_software/swlist.org @@ -34,12 +34,12 @@ Cryptophane is an easy-to-use application for MS Windows. It allows users to encrypt, sign, decrypt, and perform key maintenance without having to deal with GnuPG's command-line interface. -** [[http://egd.sourceforge.org][EGD]] [Unix] MISC +** [[http://egd.sourceforge.net][EGD]] [Unix] MISC :PROPERTIES: :CUSTOM_ID: egd :END: -Unices without a /dev/random should [[../../download/index.org::egd][download]] and install +Unices without a =/dev/random= should download and install this Entropy Gathering Daemon. ** [[http://enigform.mozdev.org][enigform]] [Unix,Windows,OSX] MISC diff --git a/web/swdb.mac b/web/swdb.mac index c295ccb..dd08436 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -53,9 +53,9 @@ # # PINENTRY # -#+macro: pinentry_ver 0.9.0 -#+macro: pinentry_size 453k -#+macro: pinentry_sha1 f8e5c774c35fbb91d84e82559baf76f6b4513236 +#+macro: pinentry_ver 0.9.1 +#+macro: pinentry_size 471k +#+macro: pinentry_sha1 01e62c45435496ff0e011255fb0ac1879a3bc177 # ----------------------------------------------------------------------- Summary of changes: misc/id/eddsa-for-openpgp/back.mkd | 22 ++++++++++++++++++++-- web/related_software/swlist.org | 4 ++-- web/swdb.mac | 6 +++--- 3 files changed, 25 insertions(+), 7 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 24 13:33:14 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 24 Mar 2015 13:33:14 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-63-gbdd22e3 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 bdd22e3a0846d38a0b6cdb822476ad2f15d03455 (commit) from 898c5c4836e3771d70df4da56c01deda139e6ddb (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 bdd22e3a0846d38a0b6cdb822476ad2f15d03455 Author: Werner Koch Date: Tue Mar 24 13:30:57 2015 +0100 gpg,w32: Handle forward slash in --keyring option. * g10/keydb.c (keydb_add_resource): Allow forward slash under Windows. -- GnuPG-bug-id: 1546 diff --git a/g10/keydb.c b/g10/keydb.c index cf422a8..040ca65 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -369,10 +369,18 @@ keydb_add_resource (const char *url, unsigned int flags) } #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ - if (*resname != DIRSEP_C ) + if (*resname != DIRSEP_C +#ifdef HAVE_W32_SYSTEM + && *resname != '/' /* Fixme: does not handle drive letters. */ +#endif + ) { /* Do tilde expansion etc. */ - if (strchr(resname, DIRSEP_C) ) + if (strchr (resname, DIRSEP_C) +#ifdef HAVE_W32_SYSTEM + || strchr (resname, '/') /* Windows also accepts this. */ +#endif + ) filename = make_filename (resname, NULL); else filename = make_filename (opt.homedir, resname, NULL); ----------------------------------------------------------------------- Summary of changes: g10/keydb.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 25 10:14:04 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 25 Mar 2015 10:14:04 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-64-g1e4d8dd 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 1e4d8ddbe3ad7ee8f1c1d1798694d91f792776c0 (commit) from bdd22e3a0846d38a0b6cdb822476ad2f15d03455 (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 1e4d8ddbe3ad7ee8f1c1d1798694d91f792776c0 Author: Werner Koch Date: Wed Mar 25 10:12:11 2015 +0100 sm: Change default algos to SHA256 (CSR) and AES128 (bulk encryption). * sm/certreqgen.c (create_request): Change default hash algo. * sm/gpgsm.c (DEFAULT_CIPHER_ALGO): Change default bulk cipher algo. -- Signed-off-by: Werner Koch diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 9720b80..0774591 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -807,7 +807,7 @@ create_request (ctrl_t ctrl, if (string) mdalgo = gcry_md_map_name (string); else - mdalgo = GCRY_MD_SHA1; + mdalgo = GCRY_MD_SHA256; rc = gcry_md_open (&md, mdalgo, 0); if (rc) { diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 62e29b8..773cf9c 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -438,7 +438,7 @@ static int default_include_certs = DEFAULT_INCLUDE_CERTS; static int default_validation_model; /* The default cipher algo. */ -#define DEFAULT_CIPHER_ALGO "3DES" /*des-EDE3-CBC*/ +#define DEFAULT_CIPHER_ALGO "AES" static char *build_list (const char *text, ----------------------------------------------------------------------- Summary of changes: sm/certreqgen.c | 2 +- sm/gpgsm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 25 10:18:10 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 25 Mar 2015 10:18:10 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-65-g674e9a0 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 674e9a02aba85be769d780509313ef1080526027 (commit) from 1e4d8ddbe3ad7ee8f1c1d1798694d91f792776c0 (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 674e9a02aba85be769d780509313ef1080526027 Author: Werner Koch Date: Wed Mar 25 10:16:37 2015 +0100 doc: Document the changed default algos for gpgsm. -- diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index dcfe292..9f16f82 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -622,7 +622,7 @@ certificates starting with the signer cert. The default is -2. Use the cipher algorithm with the ASN.1 object identifier @var{oid} for encryption. For convenience the strings @code{3DES}, @code{AES} and @code{AES256} may be used instead of their OIDs. The default is - at code{3DES} (1.2.840.113549.3.7). + at code{AES} (2.16.840.1.101.3.4.1.2). @item --digest-algo @code{name} Use @code{name} as the message digest algorithm. Usually this @@ -1144,7 +1144,7 @@ keygrip with a @samp{&}. Use @var{hash-algo} for this CSR or certificate. The supported hash algorithms are: @samp{sha1}, @samp{sha256}, @samp{sha384} and @samp{sha512}; they may also be specified with uppercase letters. The -default is @samp{sha1}. +default is @samp{sha256}. @end table ----------------------------------------------------------------------- Summary of changes: doc/gpgsm.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 25 10:30:08 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 25 Mar 2015 10:30:08 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.27-7-g2a2da1b 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 2a2da1b165f0a3050bca51dea67db9c04b9cb734 (commit) via bdf439035d123e4751e133ad42982673b0c86b75 (commit) from 0ed2cfcf054e286b238d4ddbbb3e929482849a47 (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 2a2da1b165f0a3050bca51dea67db9c04b9cb734 Author: Werner Koch Date: Wed Mar 25 10:16:37 2015 +0100 doc: Document the changed default algos for gpgsm. -- diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 078d2ad..b0882b8 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -609,7 +609,7 @@ certificates starting with the signer cert. The default is -2. Use the cipher algorithm with the ASN.1 object identifier @var{oid} for encryption. For convenience the strings @code{3DES}, @code{AES} and @code{AES256} may be used instead of their OIDs. The default is - at code{3DES} (1.2.840.113549.3.7). + at code{AES} (2.16.840.1.101.3.4.1.2). @item --digest-algo @code{name} Use @code{name} as the message digest algorithm. Usually this @@ -1127,7 +1127,7 @@ keygrip with a @samp{&}. Use @var{hash-algo} for this CSR or certificate. The supported hash algorithms are: @samp{sha1}, @samp{sha256}, @samp{sha384} and @samp{sha512}; they may also be specified with uppercase letters. The -default is @samp{sha1}. +default is @samp{sha256}. @end table commit bdf439035d123e4751e133ad42982673b0c86b75 Author: Werner Koch Date: Wed Mar 25 10:12:11 2015 +0100 sm: Change default algos to SHA256 (CSR) and AES128 (bulk encryption). * sm/certreqgen.c (create_request): Change default hash algo. * sm/gpgsm.c (main): Change default bulk cipher algo. -- Signed-off-by: Werner Koch diff --git a/sm/certreqgen.c b/sm/certreqgen.c index c3f3165..ab8fbc8 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -611,7 +611,7 @@ create_request (ctrl_t ctrl, if (err) return err; - rc = gcry_md_open (&md, GCRY_MD_SHA1, 0); + rc = gcry_md_open (&md, GCRY_MD_SHA256, 0); if (rc) { log_error ("md_open failed: %s\n", gpg_strerror (rc)); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 855de83..ef01a5c 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -931,7 +931,7 @@ main ( int argc, char **argv) /* Note: If you change this default cipher algorithm , please remember to update the Gpgconflist entry as well. */ - opt.def_cipher_algoid = "3DES"; /*des-EDE3-CBC*/ + opt.def_cipher_algoid = "AES"; opt.homedir = default_homedir (); @@ -1652,7 +1652,7 @@ main ( int argc, char **argv) #ifndef HAVE_W32_SYSTEM printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); #endif - printf ("cipher-algo:%lu:\"3DES:\n", GC_OPT_FLAG_DEFAULT); + printf ("cipher-algo:%lu:\"AES:\n", GC_OPT_FLAG_DEFAULT); printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT); ----------------------------------------------------------------------- Summary of changes: doc/gpgsm.texi | 4 ++-- sm/certreqgen.c | 2 +- sm/gpgsm.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 26 00:56:42 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 26 Mar 2015 00:56:42 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-68-gbec10ae 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 bec10ae4b5a870303c800cdf3cd906044613fc2d (commit) via 6c701af121782c2feb4ee51e559a7420df00471f (commit) via 99ef9cd7f589b51921bfbe8d52735c104ef260e3 (commit) from 674e9a02aba85be769d780509313ef1080526027 (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 bec10ae4b5a870303c800cdf3cd906044613fc2d Author: Werner Koch Date: Wed Mar 25 19:39:27 2015 +0100 dirmngr: Fix resource leaks and check rare errors. * dirmngr/ks-engine-ldap.c (keyspec_to_ldap_filter): Fix resource leak. (ks_ldap_search): Check error from es_fopenmem. Use LDAP_ERR where required. (modlist_dump): Check error from es_fopenmem. (uncescape): s/int/size_t/. Use existing macros. (extract_attributes): Use existing trim function. (ks_ldap_put): Do not segv on error from modlist_dump. Signed-off-by: Werner Koch diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index a17a312..bf56d35 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -329,6 +329,7 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) /* XXX: Should we include disabled / revoke options? */ KEYDB_SEARCH_DESC desc; char *f = NULL; + char *freeme = NULL; gpg_error_t err = classify_user_id (keyspec, &desc, 1); if (err) @@ -338,31 +339,31 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) { case KEYDB_SEARCH_MODE_EXACT: f = xasprintf ("(pgpUserID=%s)", - ldap_escape_filter (desc.u.name)); + (freeme = ldap_escape_filter (desc.u.name))); break; case KEYDB_SEARCH_MODE_SUBSTR: if (! only_exact) f = xasprintf ("(pgpUserID=*%s*)", - ldap_escape_filter (desc.u.name)); + (freeme = ldap_escape_filter (desc.u.name))); break; case KEYDB_SEARCH_MODE_MAIL: if (! only_exact) f = xasprintf ("(pgpUserID=*<%s>*)", - ldap_escape_filter (desc.u.name)); + (freeme = ldap_escape_filter (desc.u.name))); break; case KEYDB_SEARCH_MODE_MAILSUB: if (! only_exact) f = xasprintf ("(pgpUserID=*<*%s*>*)", - ldap_escape_filter (desc.u.name)); + (freeme = ldap_escape_filter (desc.u.name))); break; case KEYDB_SEARCH_MODE_MAILEND: if (! only_exact) f = xasprintf ("(pgpUserID=*<*%s>*)", - ldap_escape_filter (desc.u.name)); + (freeme = ldap_escape_filter (desc.u.name))); break; case KEYDB_SEARCH_MODE_SHORT_KID: @@ -388,6 +389,8 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) break; } + xfree (freeme); + if (! f) { log_error ("Unsupported search mode.\n"); @@ -398,6 +401,8 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) return 0; } + + /* Connect to an LDAP server and interrogate it. @@ -1028,6 +1033,11 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, /* Even if we have no results, we want to return a stream. */ fp = es_fopenmem(0, "rw"); + if (!fp) + { + err = gpg_error_from_syserror (); + goto out; + } { char **vals; @@ -1052,7 +1062,7 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, xfree (filter); filter = NULL; - if (err != LDAP_SUCCESS && err != LDAP_SIZELIMIT_EXCEEDED) + if (ldap_err != LDAP_SUCCESS && ldap_err != LDAP_SIZELIMIT_EXCEEDED) { err = ldap_err_to_gpg_err (ldap_err); @@ -1076,7 +1086,7 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, } } - if (err == LDAP_SIZELIMIT_EXCEEDED) + if (ldap_err == LDAP_SIZELIMIT_EXCEEDED) { if (count == 1) log_error ("gpgkeys: search results exceeded server limit." @@ -1261,6 +1271,8 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, return err; } + + /* A modlist describes a set of changes to an LDAP entry. (An entry consists of 1 or more attributes. Attributes are @@ -1399,9 +1411,12 @@ modlist_dump (LDAPMod **modlist, estream_t output) LDAPMod **m; int opened = 0; + if (! output) { output = es_fopenmem (0, "rw"); + if (!output) + return NULL; opened = 1; } @@ -1538,8 +1553,8 @@ modlists_join (LDAPMod ***one, LDAPMod **two) static void uncescape (char *str) { - int r = 0; - int w = 0; + size_t r = 0; + size_t w = 0; char *first = strchr (str, '\\'); if (! first) @@ -1551,14 +1566,13 @@ uncescape (char *str) while (str[r]) { - /* XXX: What to do about bad escapes? */ + /* XXX: What to do about bad escapes? + XXX: hextobyte already checks the string thus the hexdigitp + could be removed. */ if (str[r] == '\\' && str[r + 1] == 'x' - && (('0' <= str[r + 2] && str[r + 2] <= '9') - || ('a' <= str[r + 2] && str[r + 2] <= 'f') - || ('A' <= str[r + 2] && str[r + 2] <= 'F')) - && (('0' <= str[r + 3] && str[r + 3] <= '9') - || ('a' <= str[r + 3] && str[r + 3] <= 'f') - || ('A' <= str[r + 3] && str[r + 3] <= 'F'))) + && str[r+2] && str[r+3] + && hexdigitp (str + r + 2) + && hexdigitp (str + r + 3)) { int x = hextobyte (&str[r + 2]); assert (0 <= x && x <= 0xff); @@ -1582,8 +1596,6 @@ uncescape (char *str) static void extract_attributes (LDAPMod ***modlist, char *line) { - int i; - int field_count; char **fields; @@ -1592,8 +1604,7 @@ extract_attributes (LDAPMod ***modlist, char *line) int is_pub, is_sub, is_uid, is_sig; /* Remove trailing whitespace */ - for (i = strlen (line) - 1; i >= 0 && ascii_isspace (line[i]); i--) - line[i] = '\0'; + trim_trailing_spaces (line); fields = strsplit (line, ':', '\0', &field_count); if (field_count == 1) @@ -1671,7 +1682,7 @@ extract_attributes (LDAPMod ***modlist, char *line) char padded[6]; if (val < 99999 && val > 0) { - sprintf (padded, "%05u", val); + snprintf (padded, sizeof padded, "%05u", val); size = padded; } } @@ -1992,8 +2003,11 @@ ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri, if (dump) { estream_t input = modlist_dump (modlist, NULL); - copy_stream (input, dump); - es_fclose (input); + if (input) + { + copy_stream (input, dump); + es_fclose (input); + } } /* Going on the assumption that modify operations are more frequent commit 6c701af121782c2feb4ee51e559a7420df00471f Author: Werner Koch Date: Wed Mar 25 19:33:59 2015 +0100 dirmngr: Minor cleanups. * dirmngr/ks-engine-ldap.c [__riscos__]: Remove doubled util.h. (ldap_to_gpg_err): s/GPG_ERR_GENERAL/GPG_ERR_INTERNAL/. (tm2ldaptime): Use snprintf. (ldap_connect): Get error code prior to log_error and and use modern function. Use xfree, xtrustrdup etc. (modlist_lookup): Use GNUPG_GCC_A_USED. (modlist_free): Use xfree. -- sprintf has been replaced by snprintf to avoid warnings on some platforms. xfree et al. is required so that replacement functions are used if defined. For example the Libgcrypt functions which may not be fully compatible with standard free. Impossible conditions should use GPG_ERR_INTERNAL. Signed-off-by: Werner Koch diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index 68a1bb7..a17a312 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -49,10 +49,6 @@ #include "ks-engine.h" #include "ldap-parse-uri.h" -#ifdef __riscos__ -# include "util.h" -#endif - #ifndef HAVE_TIMEGM time_t timegm(struct tm *tm); #endif @@ -220,7 +216,7 @@ ldap_to_gpg_err (LDAP *ld) #else /* We should never get here since the LDAP library should always have either ldap_get_option or ld_errno, but just in case... */ - return GPG_ERR_GENERAL; + return GPG_ERR_INTERNAL; #endif } @@ -265,7 +261,7 @@ tm2ldaptime (struct tm *tm) tmp.tm_year += 1900; tmp.tm_mon ++; - sprintf (buf, "%04d%02d%02d%02d%02d%02dZ", + snprintf (buf, sizeof buf, "%04d%02d%02d%02d%02d%02dZ", tmp.tm_year, tmp.tm_mon, tmp.tm_mday, @@ -435,7 +431,7 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) If no LDAP error occured, you still need to check that *basednp is valid. If it is NULL, then the server does not appear to be an - OpenPGP Keyserver. In this case, you also do not need to free + OpenPGP Keyserver. In this case, you also do not need to xfree *pgpkeyattrp. */ static int ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, @@ -476,9 +472,9 @@ ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, ldap_conn = ldap_init (uri->host, uri->port); if (! ldap_conn) { + err = gpg_err_code_from_syserror (); log_error ("Failed to open connection to LDAP server (%s://%s:%d)\n", uri->scheme, uri->host, uri->port); - err = gpg_err_code_from_errno (errno); goto out; } @@ -516,7 +512,7 @@ ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, /* XXX: We need an option to determine whether to abort if the certificate is bad or not. Right now we conservatively default to checking the certificate and aborting. */ - int check_cert = LDAP_OPT_X_TLS_HARD; // LDAP_OPT_X_TLS_NEVER + int check_cert = LDAP_OPT_X_TLS_HARD; /* LDAP_OPT_X_TLS_NEVER */ err = ldap_set_option (ldap_conn, LDAP_OPT_X_TLS_REQUIRE_CERT, &check_cert); @@ -587,10 +583,13 @@ ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, char **vals; LDAPMessage *si_res; - char *object = xasprintf ("cn=pgpServerInfo,%s", context[i]); - err = ldap_search_s (ldap_conn, object, LDAP_SCOPE_BASE, - "(objectClass=*)", attr2, 0, &si_res); - free (object); + { + char *object = xasprintf ("cn=pgpServerInfo,%s", + context[i]); + err = ldap_search_s (ldap_conn, object, LDAP_SCOPE_BASE, + "(objectClass=*)", attr2, 0, &si_res); + xfree (object); + } if (err == LDAP_SUCCESS) { @@ -598,7 +597,7 @@ ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, "pgpBaseKeySpaceDN"); if (vals) { - basedn = strdup (vals[0]); + basedn = xtrystrdup (vals[0]); ldap_value_free (vals); } @@ -649,7 +648,7 @@ ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, vals = ldap_get_values (ldap_conn, si_res, "baseKeySpaceDN"); if (vals) { - basedn = strdup (vals[0]); + basedn = xtrystrdup (vals[0]); ldap_value_free (vals); } @@ -1361,8 +1360,6 @@ modlist_add (LDAPMod ***modlistp, char *attr, const char *value) { modlist[nummods]->mod_values = xmalloc (sizeof(char *) * 2); - /* XXX: Is this the right thing? Can a UTF8-encoded user ID - have embedded nulls? */ modlist[nummods]->mod_values[0] = xstrdup (value); modlist[nummods]->mod_values[1] = NULL; } @@ -1394,7 +1391,7 @@ modlist_lookup (LDAPMod **modlist, const char *attr) /* Dump a modlist to a file. This is useful for debugging. */ static estream_t modlist_dump (LDAPMod **modlist, estream_t output) - __attribute__ ((used)); + GNUPG_GCC_A_USED; static estream_t modlist_dump (LDAPMod **modlist, estream_t output) @@ -1488,14 +1485,14 @@ modlist_free (LDAPMod **modlist) if (mod->mod_values) { for (ptr = mod->mod_values; *ptr; ptr++) - free (*ptr); + xfree (*ptr); - free (mod->mod_values); + xfree (mod->mod_values); } - free (mod); + xfree (mod); } - free (modlist); + xfree (modlist); } /* Append two onto the end of one. Two is not freed, but its pointers @@ -1633,7 +1630,8 @@ extract_attributes (LDAPMod ***modlist, char *line) if (is_pub) { - int disabled = 0, revoked = 0; + int disabled = 0; + int revoked = 0; char *flags; for (flags = fields[1]; *flags; flags ++) switch (*flags) diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c index 2a341ad..9a6d619 100644 --- a/dirmngr/ldap-parse-uri.c +++ b/dirmngr/ldap-parse-uri.c @@ -127,7 +127,7 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri) len = 0; -#define add(s) { if (s) len += strlen (s) + 1; } +#define add(s) do { if (s) len += strlen (s) + 1; } while (0) add (scheme); add (host); @@ -166,6 +166,11 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri) if (password) { puri->query = calloc (sizeof (*puri->query), 1); + if (!puri->query) + { + err = gpg_err_code_from_syserror (); + goto out; + } puri->query->name = "password"; copy (puri->query->value, password); puri->query->valuelen = strlen (password) + 1; @@ -221,7 +226,8 @@ ldap_escape_filter (const char *filter) case ')': case '\\': case '/': - sprintf (&escaped[escaped_i], "%%%02x", filter[filter_i]); + snprintf (&escaped[escaped_i], 4, "%%%02x", + ((const unsigned char *)filter)[filter_i]); escaped_i += 3; break; commit 99ef9cd7f589b51921bfbe8d52735c104ef260e3 Author: Werner Koch Date: Wed Mar 25 19:19:38 2015 +0100 common: Add macro GNUPG_GCC_A_USED. * common/util.h (GNUPG_GCC_A_USED): New. Signed-off-by: Werner Koch diff --git a/common/util.h b/common/util.h index 4761a28..d22820d 100644 --- a/common/util.h +++ b/common/util.h @@ -159,6 +159,12 @@ # define GNUPG_GCC_A_SENTINEL(a) #endif +#if __GNUC__ >= 4 +# define GNUPG_GCC_A_USED __attribute__ ((used)) +#else +# define GNUPG_GCC_A_USED +#endif + /* We need this type even if we are not using libreadline and or we did not include libreadline in the current file. */ ----------------------------------------------------------------------- Summary of changes: common/util.h | 6 +++ dirmngr/ks-engine-ldap.c | 104 ++++++++++++++++++++++++++--------------------- dirmngr/ldap-parse-uri.c | 10 ++++- 3 files changed, 72 insertions(+), 48 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Mar 28 12:28:04 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 28 Mar 2015 12:28:04 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.19-2-gf34d883 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 f34d88364a984947bcd7c344f9532f683b856353 (commit) from eb645a57e2a041ed9b368b447cc7e7d77ac05565 (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 f34d88364a984947bcd7c344f9532f683b856353 Author: Werner Koch Date: Thu Feb 26 09:38:58 2015 +0100 gpg: Remove left-over debug message. * g10/armor.c (check_input): Remove log_debug. diff --git a/g10/armor.c b/g10/armor.c index 4332d70..be03692 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -538,9 +538,6 @@ check_input( armor_filter_context_t *afx, IOBUF a ) /* This is probably input from a keyserver helper and we have not yet seen an error line. */ afx->key_failed_code = parse_key_failed_line (line+4, len-4); - log_debug ("armor-keys-failed (%.*s) ->%d\n", - (int)len, line, - afx->key_failed_code); } if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) { hdr_line = i; ----------------------------------------------------------------------- Summary of changes: g10/armor.c | 3 --- 1 file changed, 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Mar 28 16:55:59 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Sat, 28 Mar 2015 16:55:59 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-69-gf26ba14 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 f26ba14028d34845ae10aae552b90681907e377d (commit) from bec10ae4b5a870303c800cdf3cd906044613fc2d (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 f26ba14028d34845ae10aae552b90681907e377d Author: Neal H. Walfield Date: Sat Mar 28 16:55:10 2015 +0100 gpg: Only use the last specified keyserver. * g10/gpg.c (main): Only use the last specified keyserver. -- Signed-off-by: Neal H. Walfield diff --git a/g10/gpg.c b/g10/gpg.c index eb75409..da4224f 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1,6 +1,7 @@ /* gpg.c - The GnuPG utility (main for gpg) * Copyright (C) 1998-2011 Free Software Foundation, Inc. * Copyright (C) 1997-2014 Werner Koch + * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -2829,7 +2830,13 @@ main (int argc, char **argv) log_error (_("could not parse keyserver URL\n")); else { - keyserver->next = opt.keyserver; + /* We only support a single keyserver. Later ones + override earlier ones. (Since we parse the + config file first and then the command line + arguments, the command line takes + precedence.) */ + if (opt.keyserver) + free_keyserver_spec (opt.keyserver); opt.keyserver = keyserver; } } ----------------------------------------------------------------------- Summary of changes: g10/gpg.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Mar 28 17:24:28 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Sat, 28 Mar 2015 17:24:28 +0100 Subject: [git] GnuPG - branch, neal/pending, created. gnupg-2.1.2-70-gd4a32ae 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, neal/pending has been created at d4a32ae5c6e60dc342d9b19f5aa0d1f4bc89027c (commit) - Log ----------------------------------------------------------------- commit d4a32ae5c6e60dc342d9b19f5aa0d1f4bc89027c Author: Neal H. Walfield Date: Sat Mar 28 17:23:56 2015 +0100 dirmngr: Better encapsulate the keyservers variable. * dirmngr/dirmngr.h (struct server_control_s): Move field keyservers from here... * dirmngr/server.c (struct server_local_s): ... to here. Update users. * dirmngr/ks-action.h (ks_action_resolve): Add argument keyservers. (ks_action_search): Likewise. (ks_action_get): Likewise. (ks_action_put): Likewise. * dirmngr/ks-action.c (ks_action_resolve): Add argument keyservers. Use it instead of ctrl->keyservers. (ks_action_search): Likewise. (ks_action_get): Likewise. (ks_action_put): Likewise. -- Signed-off-by: Neal H. Walfield diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 3dd16a3..320d178 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -1,6 +1,6 @@ /* dirmngr.h - Common definitions for the dirmngr * Copyright (C) 2002 Klar?lvdalens Datakonsult AB - * Copyright (C) 2004 g10 Code GmbH + * Copyright (C) 2004, 2015 g10 Code GmbH * Copyright (C) 2014 Werner Koch * * This file is part of GnuPG. @@ -174,7 +174,6 @@ struct server_control_s response. */ int audit_events; /* Send audit events to client. */ - uri_item_t keyservers; /* List of keyservers. */ }; diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index 6cfb598..c76aaaa 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -1,7 +1,7 @@ /* ks-action.c - OpenPGP keyserver actions * Copyright (C) 2011 Free Software Foundation, Inc. * Copyright (C) 2011, 2014 Werner Koch - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -105,13 +105,13 @@ ks_action_help (ctrl_t ctrl, const char *url) /* Resolve all host names. This is useful for looking at the status of configured keyservers. */ gpg_error_t -ks_action_resolve (ctrl_t ctrl) +ks_action_resolve (ctrl_t ctrl, uri_item_t keyservers) { gpg_error_t err = 0; int any_server = 0; uri_item_t uri; - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { if (uri->parsed_uri->is_http) { @@ -131,7 +131,8 @@ ks_action_resolve (ctrl_t ctrl) /* Search all configured keyservers for keys matching PATTERNS and write the result to the provided output stream. */ gpg_error_t -ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp) +ks_action_search (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp) { gpg_error_t err = 0; int any_server = 0; @@ -147,7 +148,7 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp) errors - it might not be the best idea to ignore an error from one server and silently continue with another server. For now we stop at the first error. */ - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { int is_http = uri->parsed_uri->is_http; int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 @@ -179,7 +180,8 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp) /* Get the requested keys (matching PATTERNS) using all configured keyservers and write the result to the provided output stream. */ gpg_error_t -ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp) +ks_action_get (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp) { gpg_error_t err = 0; gpg_error_t first_err = 0; @@ -198,7 +200,7 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp) keyservers might not all be fully synced thus it is not clear whether the first keyserver has the freshest copy of the key. Need to think about a better strategy. */ - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { int is_http = uri->parsed_uri->is_http; int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 @@ -311,7 +313,8 @@ ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp) KEYID; done'. This function may modify DATA and INFO. If this is a problem, then the caller should create a copy. */ gpg_error_t -ks_action_put (ctrl_t ctrl, void *data, size_t datalen, +ks_action_put (ctrl_t ctrl, uri_item_t keyservers, + void *data, size_t datalen, void *info, size_t infolen) { gpg_error_t err = 0; @@ -319,7 +322,7 @@ ks_action_put (ctrl_t ctrl, void *data, size_t datalen, int any_server = 0; uri_item_t uri; - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { int is_http = uri->parsed_uri->is_http; int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 diff --git a/dirmngr/ks-action.h b/dirmngr/ks-action.h index 2def3dc..c373bf9 100644 --- a/dirmngr/ks-action.h +++ b/dirmngr/ks-action.h @@ -22,11 +22,14 @@ #define DIRMNGR_KS_ACTION_H 1 gpg_error_t ks_action_help (ctrl_t ctrl, const char *url); -gpg_error_t ks_action_resolve (ctrl_t ctrl); -gpg_error_t ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp); -gpg_error_t ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp); +gpg_error_t ks_action_resolve (ctrl_t ctrl, uri_item_t keyservers); +gpg_error_t ks_action_search (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp); +gpg_error_t ks_action_get (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp); gpg_error_t ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp); -gpg_error_t ks_action_put (ctrl_t ctrl, void *data, size_t datalen, +gpg_error_t ks_action_put (ctrl_t ctrl, uri_item_t keyservers, + void *data, size_t datalen, void *info, size_t infolen); diff --git a/dirmngr/server.c b/dirmngr/server.c index deae85c..16e6c0a 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1,8 +1,7 @@ /* server.c - LDAP and Keyserver access server * Copyright (C) 2002 Klar?lvdalens Datakonsult AB - * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011 g10 Code GmbH + * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2015 g10 Code GmbH * Copyright (C) 2014 Werner Koch - * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -76,6 +75,9 @@ struct server_local_s /* Per-session LDAP servers. */ ldap_server_t ldapservers; + /* Per-session list of keyservers. */ + uri_item_t keyservers; + /* If this flag is set to true this dirmngr process will be terminated after the end of this session. */ int stopme; @@ -113,12 +115,12 @@ get_ldapservers_from_ctrl (ctrl_t ctrl) void release_ctrl_keyservers (ctrl_t ctrl) { - while (ctrl->keyservers) + while (ctrl->server_local->keyservers) { - uri_item_t tmp = ctrl->keyservers->next; - http_release_parsed_uri (ctrl->keyservers->parsed_uri); - xfree (ctrl->keyservers); - ctrl->keyservers = tmp; + uri_item_t tmp = ctrl->server_local->keyservers->next; + http_release_parsed_uri (ctrl->server_local->keyservers->parsed_uri); + xfree (ctrl->server_local->keyservers); + ctrl->server_local->keyservers = tmp; } } @@ -1476,7 +1478,7 @@ cmd_keyserver (assuan_context_t ctx, char *line) if (resolve_flag) { - err = ks_action_resolve (ctrl); + err = ks_action_resolve (ctrl, ctrl->server_local->keyservers); if (err) goto leave; } @@ -1540,15 +1542,15 @@ cmd_keyserver (assuan_context_t ctx, char *line) release_ctrl_keyservers (ctrl); if (add_flag) { - item->next = ctrl->keyservers; - ctrl->keyservers = item; + item->next = ctrl->server_local->keyservers; + ctrl->server_local->keyservers = item; } if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers. */ { uri_item_t u; - for (u=ctrl->keyservers; u; u = u->next) + for (u=ctrl->server_local->keyservers; u; u = u->next) dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL); } err = 0; @@ -1606,7 +1608,8 @@ cmd_ks_search (assuan_context_t ctx, char *line) err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream"); else { - err = ks_action_search (ctrl, list, outfp); + err = ks_action_search (ctrl, ctrl->server_local->keyservers, + list, outfp); es_fclose (outfp); } @@ -1667,7 +1670,7 @@ cmd_ks_get (assuan_context_t ctx, char *line) err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream"); else { - err = ks_action_get (ctrl, list, outfp); + err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp); es_fclose (outfp); } @@ -1762,7 +1765,8 @@ cmd_ks_put (assuan_context_t ctx, char *line) } /* Send the key. */ - err = ks_action_put (ctrl, value, valuelen, info, infolen); + err = ks_action_put (ctrl, ctrl->server_local->keyservers, + value, valuelen, info, infolen); leave: xfree (info); ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 31 14:51:07 2015 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 31 Mar 2015 14:51:07 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.2-75-gd0ff2ee 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 d0ff2ee04187fbedacbe4d3884ee75d957a0b8c6 (commit) via 802eec0ca49b92104c92f18c9a6a04c34de74168 (commit) via 6d5aee23c341a2e9196617975662ccc735050b72 (commit) via 7f6d7948c1e56e09c1bdaa5143e1b5558c4376dd (commit) via 44297d0821dbc2330b1f91351aaab8f6925dc032 (commit) via 348c520040a31f5c322183c0654a34978e2baf6f (commit) from f26ba14028d34845ae10aae552b90681907e377d (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 d0ff2ee04187fbedacbe4d3884ee75d957a0b8c6 Author: Neal H. Walfield Date: Tue Mar 31 14:48:31 2015 +0200 dirmngr: Don't use alloca. * dirmngr/ks-engine-ldap.c (ks_ldap_put): Replace use of alloca with xmalloc and xfree. -- Signed-off-by: Neal H. Walfield diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index 66e4964..1ce709d 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -1961,7 +1961,7 @@ ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri, /* The last line is not \n terminated! Make a copy so we can add a NUL terminator. */ { - temp = alloca (infolen + 1); + temp = xmalloc (infolen + 1); memcpy (temp, info, infolen); info = temp; newline = (char *) info + infolen; @@ -1978,7 +1978,10 @@ ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri, if (! temp) assert ((char *) info + infolen - 1 == infoend); else - assert (infolen == -1); + { + assert (infolen == -1); + xfree (temp); + } } modlist_add (&addlist, "objectClass", "pgpKeyInfo"); commit 802eec0ca49b92104c92f18c9a6a04c34de74168 Author: Neal H. Walfield Date: Tue Mar 31 14:23:13 2015 +0200 dirmngr: Simplify truncation of long strings in debug code. * dirmngr/ks-engine-ldap.c (modlist_dump): Simplify truncation of long strings. -- Signed-off-by: Neal H. Walfield diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index 236f923..66e4964 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -1440,29 +1440,22 @@ modlist_dump (LDAPMod **modlist, estream_t output) for ((ptr = (*m)->mod_values), (i = 1); ptr && *ptr; ptr++, i ++) { - /* At most about 10 lines. */ + /* Assuming terminals are about 80 characters wide, + display at most most about 10 lines of debugging + output. If we do trim the buffer, append '...' to + the end. */ const int max_len = 10 * 70; size_t value_len = strlen (*ptr); - char buffer[max_len + 4]; - char *temp; - int elided = 0; - if (value_len > max_len) - { - temp = buffer; - memcpy (temp, *ptr, max_len); - temp[max_len] = temp[max_len + 1] = temp[max_len + 2] = '.'; - temp[max_len + 3] = 0; - elided = 1; - } - else - temp = *ptr; + int elide = value_len > max_len; if (multi) es_fprintf (output, " %d. ", i); - es_fprintf (output, "`%s'", temp); - if (elided) - es_fprintf (output, " (%zd bytes elided)", + es_fprintf (output, "`%.*s", max_len, *ptr); + if (elide) + es_fprintf (output, "...' (%zd bytes elided)", value_len - max_len); + else + es_fprintf (output, "'"); es_fprintf (output, "\n"); } } commit 6d5aee23c341a2e9196617975662ccc735050b72 Author: Neal H. Walfield Date: Tue Mar 31 12:26:59 2015 +0200 dirmngr: Correct indentation. -- Signed-off-by: Neal H. Walfield diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index bf56d35..236f923 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -1123,118 +1123,117 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, es_fprintf (fp, "pub:%s:",certid[0]); - vals = ldap_get_values (ldap_conn, each, "pgpkeytype"); - if (vals) - { - /* The LDAP server doesn't exactly handle this - well. */ - if (strcasecmp (vals[0], "RSA") == 0) - es_fputs ("1", fp); - else if (strcasecmp (vals[0], "DSS/DH") == 0) - es_fputs ("17", fp); - ldap_value_free (vals); - } - - es_fputc (':', fp); - - vals = ldap_get_values (ldap_conn, each, "pgpkeysize"); - if (vals) - { - /* Not sure why, but some keys are listed with a - key size of 0. Treat that like an - unknown. */ - if (atoi (vals[0]) > 0) - es_fprintf (fp, "%d", atoi (vals[0])); - ldap_value_free (vals); - } - - es_fputc (':', fp); - - /* YYYYMMDDHHmmssZ */ - - vals = ldap_get_values (ldap_conn, each, "pgpkeycreatetime"); - if(vals && strlen (vals[0]) == 15) - { - es_fprintf (fp, "%u", - (unsigned int) ldap2epochtime(vals[0])); - ldap_value_free (vals); - } - - es_fputc (':', fp); - - vals = ldap_get_values (ldap_conn, each, "pgpkeyexpiretime"); - if (vals && strlen (vals[0]) == 15) - { - es_fprintf (fp, "%u", - (unsigned int) ldap2epochtime (vals[0])); - ldap_value_free (vals); - } - - es_fputc (':', fp); - - vals = ldap_get_values (ldap_conn, each, "pgprevoked"); - if (vals) - { - if (atoi (vals[0]) == 1) - es_fprintf (fp, "r"); - ldap_value_free (vals); - } - - vals = ldap_get_values (ldap_conn, each, "pgpdisabled"); - if (vals) - { - if (atoi (vals[0]) ==1) - es_fprintf (fp, "d"); - ldap_value_free (vals); - } + vals = ldap_get_values (ldap_conn, each, "pgpkeytype"); + if (vals) + { + /* The LDAP server doesn't exactly handle this + well. */ + if (strcasecmp (vals[0], "RSA") == 0) + es_fputs ("1", fp); + else if (strcasecmp (vals[0], "DSS/DH") == 0) + es_fputs ("17", fp); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "pgpkeysize"); + if (vals) + { + /* Not sure why, but some keys are listed with a + key size of 0. Treat that like an unknown. */ + if (atoi (vals[0]) > 0) + es_fprintf (fp, "%d", atoi (vals[0])); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + /* YYYYMMDDHHmmssZ */ + + vals = ldap_get_values (ldap_conn, each, "pgpkeycreatetime"); + if(vals && strlen (vals[0]) == 15) + { + es_fprintf (fp, "%u", + (unsigned int) ldap2epochtime(vals[0])); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "pgpkeyexpiretime"); + if (vals && strlen (vals[0]) == 15) + { + es_fprintf (fp, "%u", + (unsigned int) ldap2epochtime (vals[0])); + ldap_value_free (vals); + } + + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "pgprevoked"); + if (vals) + { + if (atoi (vals[0]) == 1) + es_fprintf (fp, "r"); + ldap_value_free (vals); + } + + vals = ldap_get_values (ldap_conn, each, "pgpdisabled"); + if (vals) + { + if (atoi (vals[0]) ==1) + es_fprintf (fp, "d"); + ldap_value_free (vals); + } #if 0 - /* This is not yet specified in the keyserver - protocol, but may be someday. */ - es_fputc (':', fp); - - vals = ldap_get_values (ldap_conn, each, "modifytimestamp"); - if(vals && strlen (vals[0]) == 15) - { - es_fprintf (fp, "%u", - (unsigned int) ldap2epochtime (vals[0])); - ldap_value_free (vals); - } + /* This is not yet specified in the keyserver + protocol, but may be someday. */ + es_fputc (':', fp); + + vals = ldap_get_values (ldap_conn, each, "modifytimestamp"); + if(vals && strlen (vals[0]) == 15) + { + es_fprintf (fp, "%u", + (unsigned int) ldap2epochtime (vals[0])); + ldap_value_free (vals); + } #endif - es_fprintf (fp, "\n"); - - /* Now print all the uids that have this certid */ - for (uids = ldap_first_entry (ldap_conn, res); - uids; - uids = ldap_next_entry (ldap_conn, uids)) - { - vals = ldap_get_values (ldap_conn, uids, "pgpcertid"); - if (! vals) - continue; - - if (strcasecmp (certid[0], vals[0]) == 0) - { - char **uidvals; - - es_fprintf (fp, "uid:"); - - uidvals = ldap_get_values (ldap_conn, - uids, "pgpuserid"); - if (uidvals) - { - /* Need to escape any colons */ - char *quoted = percent_escape (uidvals[0], NULL); - es_fputs (quoted, fp); - xfree (quoted); - ldap_value_free (uidvals); - } - - es_fprintf (fp, "\n"); - } - - ldap_value_free(vals); - } + es_fprintf (fp, "\n"); + + /* Now print all the uids that have this certid */ + for (uids = ldap_first_entry (ldap_conn, res); + uids; + uids = ldap_next_entry (ldap_conn, uids)) + { + vals = ldap_get_values (ldap_conn, uids, "pgpcertid"); + if (! vals) + continue; + + if (strcasecmp (certid[0], vals[0]) == 0) + { + char **uidvals; + + es_fprintf (fp, "uid:"); + + uidvals = ldap_get_values (ldap_conn, + uids, "pgpuserid"); + if (uidvals) + { + /* Need to escape any colons */ + char *quoted = percent_escape (uidvals[0], NULL); + es_fputs (quoted, fp); + xfree (quoted); + ldap_value_free (uidvals); + } + + es_fprintf (fp, "\n"); + } + + ldap_value_free(vals); + } } ldap_value_free (certid); commit 7f6d7948c1e56e09c1bdaa5143e1b5558c4376dd Author: Neal H. Walfield Date: Tue Mar 31 12:07:39 2015 +0200 dirmngr: Use a better error code. * dirmngr/ldap-parse-uri.c (ldap_parse_uri): On error, return GPG_ERR_GENERAL, not GPG_ERR_ASS_GENERAL. -- Signed-off-by: Neal H. Walfield diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c index 9a6d619..62f8f6d 100644 --- a/dirmngr/ldap-parse-uri.c +++ b/dirmngr/ldap-parse-uri.c @@ -94,7 +94,7 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri) if (result != 0) { log_error ("Unable to parse LDAP uri '%s'\n", uri); - err = GPG_ERR_ASS_GENERAL; + err = GPG_ERR_GENERAL; goto out; } commit 44297d0821dbc2330b1f91351aaab8f6925dc032 Author: Neal H. Walfield Date: Tue Mar 31 12:00:58 2015 +0200 gpg: Remove gratuitous extern qualifier from declaration. -- Signed-off-by: Neal H. Walfield diff --git a/common/http.h b/common/http.h index 17f778d..fcab12a 100644 --- a/common/http.h +++ b/common/http.h @@ -62,7 +62,7 @@ struct parsed_uri_s }; typedef struct parsed_uri_s *parsed_uri_t; -extern struct uri_tuple_s *uri_query_lookup (parsed_uri_t uri, const char *key); +struct uri_tuple_s *uri_query_lookup (parsed_uri_t uri, const char *key); typedef enum { commit 348c520040a31f5c322183c0654a34978e2baf6f Author: Neal H. Walfield Date: Sat Mar 28 17:23:56 2015 +0100 dirmngr: Better encapsulate the keyservers variable. * dirmngr/dirmngr.h (struct server_control_s): Move field keyservers from here... * dirmngr/server.c (struct server_local_s): ... to here. Update users. * dirmngr/ks-action.h (ks_action_resolve): Add argument keyservers. (ks_action_search): Likewise. (ks_action_get): Likewise. (ks_action_put): Likewise. * dirmngr/ks-action.c (ks_action_resolve): Add argument keyservers. Use it instead of ctrl->keyservers. (ks_action_search): Likewise. (ks_action_get): Likewise. (ks_action_put): Likewise. -- Signed-off-by: Neal H. Walfield diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 3dd16a3..320d178 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -1,6 +1,6 @@ /* dirmngr.h - Common definitions for the dirmngr * Copyright (C) 2002 Klar?lvdalens Datakonsult AB - * Copyright (C) 2004 g10 Code GmbH + * Copyright (C) 2004, 2015 g10 Code GmbH * Copyright (C) 2014 Werner Koch * * This file is part of GnuPG. @@ -174,7 +174,6 @@ struct server_control_s response. */ int audit_events; /* Send audit events to client. */ - uri_item_t keyservers; /* List of keyservers. */ }; diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index 6cfb598..c76aaaa 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -1,7 +1,7 @@ /* ks-action.c - OpenPGP keyserver actions * Copyright (C) 2011 Free Software Foundation, Inc. * Copyright (C) 2011, 2014 Werner Koch - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -105,13 +105,13 @@ ks_action_help (ctrl_t ctrl, const char *url) /* Resolve all host names. This is useful for looking at the status of configured keyservers. */ gpg_error_t -ks_action_resolve (ctrl_t ctrl) +ks_action_resolve (ctrl_t ctrl, uri_item_t keyservers) { gpg_error_t err = 0; int any_server = 0; uri_item_t uri; - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { if (uri->parsed_uri->is_http) { @@ -131,7 +131,8 @@ ks_action_resolve (ctrl_t ctrl) /* Search all configured keyservers for keys matching PATTERNS and write the result to the provided output stream. */ gpg_error_t -ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp) +ks_action_search (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp) { gpg_error_t err = 0; int any_server = 0; @@ -147,7 +148,7 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp) errors - it might not be the best idea to ignore an error from one server and silently continue with another server. For now we stop at the first error. */ - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { int is_http = uri->parsed_uri->is_http; int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 @@ -179,7 +180,8 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp) /* Get the requested keys (matching PATTERNS) using all configured keyservers and write the result to the provided output stream. */ gpg_error_t -ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp) +ks_action_get (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp) { gpg_error_t err = 0; gpg_error_t first_err = 0; @@ -198,7 +200,7 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp) keyservers might not all be fully synced thus it is not clear whether the first keyserver has the freshest copy of the key. Need to think about a better strategy. */ - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { int is_http = uri->parsed_uri->is_http; int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 @@ -311,7 +313,8 @@ ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp) KEYID; done'. This function may modify DATA and INFO. If this is a problem, then the caller should create a copy. */ gpg_error_t -ks_action_put (ctrl_t ctrl, void *data, size_t datalen, +ks_action_put (ctrl_t ctrl, uri_item_t keyservers, + void *data, size_t datalen, void *info, size_t infolen) { gpg_error_t err = 0; @@ -319,7 +322,7 @@ ks_action_put (ctrl_t ctrl, void *data, size_t datalen, int any_server = 0; uri_item_t uri; - for (uri = ctrl->keyservers; !err && uri; uri = uri->next) + for (uri = keyservers; !err && uri; uri = uri->next) { int is_http = uri->parsed_uri->is_http; int is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0 diff --git a/dirmngr/ks-action.h b/dirmngr/ks-action.h index 2def3dc..c373bf9 100644 --- a/dirmngr/ks-action.h +++ b/dirmngr/ks-action.h @@ -22,11 +22,14 @@ #define DIRMNGR_KS_ACTION_H 1 gpg_error_t ks_action_help (ctrl_t ctrl, const char *url); -gpg_error_t ks_action_resolve (ctrl_t ctrl); -gpg_error_t ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp); -gpg_error_t ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp); +gpg_error_t ks_action_resolve (ctrl_t ctrl, uri_item_t keyservers); +gpg_error_t ks_action_search (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp); +gpg_error_t ks_action_get (ctrl_t ctrl, uri_item_t keyservers, + strlist_t patterns, estream_t outfp); gpg_error_t ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp); -gpg_error_t ks_action_put (ctrl_t ctrl, void *data, size_t datalen, +gpg_error_t ks_action_put (ctrl_t ctrl, uri_item_t keyservers, + void *data, size_t datalen, void *info, size_t infolen); diff --git a/dirmngr/server.c b/dirmngr/server.c index deae85c..506b137 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1,8 +1,7 @@ /* server.c - LDAP and Keyserver access server * Copyright (C) 2002 Klar?lvdalens Datakonsult AB - * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011 g10 Code GmbH + * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2015 g10 Code GmbH * Copyright (C) 2014 Werner Koch - * Copyright (C) 2015 g10 Code GmbH * * This file is part of GnuPG. * @@ -76,6 +75,9 @@ struct server_local_s /* Per-session LDAP servers. */ ldap_server_t ldapservers; + /* Per-session list of keyservers. */ + uri_item_t keyservers; + /* If this flag is set to true this dirmngr process will be terminated after the end of this session. */ int stopme; @@ -113,12 +115,15 @@ get_ldapservers_from_ctrl (ctrl_t ctrl) void release_ctrl_keyservers (ctrl_t ctrl) { - while (ctrl->keyservers) + if (! ctrl->server_local) + return; + + while (ctrl->server_local->keyservers) { - uri_item_t tmp = ctrl->keyservers->next; - http_release_parsed_uri (ctrl->keyservers->parsed_uri); - xfree (ctrl->keyservers); - ctrl->keyservers = tmp; + uri_item_t tmp = ctrl->server_local->keyservers->next; + http_release_parsed_uri (ctrl->server_local->keyservers->parsed_uri); + xfree (ctrl->server_local->keyservers); + ctrl->server_local->keyservers = tmp; } } @@ -127,7 +132,6 @@ release_ctrl_keyservers (ctrl_t ctrl) /* Helper to print a message while leaving a command. */ static gpg_error_t leave_cmd (assuan_context_t ctx, gpg_error_t err) - { if (err) { @@ -1476,7 +1480,7 @@ cmd_keyserver (assuan_context_t ctx, char *line) if (resolve_flag) { - err = ks_action_resolve (ctrl); + err = ks_action_resolve (ctrl, ctrl->server_local->keyservers); if (err) goto leave; } @@ -1540,15 +1544,15 @@ cmd_keyserver (assuan_context_t ctx, char *line) release_ctrl_keyservers (ctrl); if (add_flag) { - item->next = ctrl->keyservers; - ctrl->keyservers = item; + item->next = ctrl->server_local->keyservers; + ctrl->server_local->keyservers = item; } if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers. */ { uri_item_t u; - for (u=ctrl->keyservers; u; u = u->next) + for (u=ctrl->server_local->keyservers; u; u = u->next) dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL); } err = 0; @@ -1606,7 +1610,8 @@ cmd_ks_search (assuan_context_t ctx, char *line) err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream"); else { - err = ks_action_search (ctrl, list, outfp); + err = ks_action_search (ctrl, ctrl->server_local->keyservers, + list, outfp); es_fclose (outfp); } @@ -1667,7 +1672,7 @@ cmd_ks_get (assuan_context_t ctx, char *line) err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream"); else { - err = ks_action_get (ctrl, list, outfp); + err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp); es_fclose (outfp); } @@ -1762,7 +1767,8 @@ cmd_ks_put (assuan_context_t ctx, char *line) } /* Send the key. */ - err = ks_action_put (ctrl, value, valuelen, info, infolen); + err = ks_action_put (ctrl, ctrl->server_local->keyservers, + value, valuelen, info, infolen); leave: xfree (info); ----------------------------------------------------------------------- Summary of changes: common/http.h | 2 +- dirmngr/dirmngr.h | 3 +- dirmngr/ks-action.c | 21 ++-- dirmngr/ks-action.h | 11 ++- dirmngr/ks-engine-ldap.c | 249 +++++++++++++++++++++++------------------------ dirmngr/ldap-parse-uri.c | 2 +- dirmngr/server.c | 36 ++++--- 7 files changed, 165 insertions(+), 159 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org